Skip to content

Commit d6cf067

Browse files
committed
Refactor vendor root configuration
- allow for ENV variable as well as constant - remove `abstract_composer.php` shell "helper" - increase test coverage of Autoload.php - update README to reflect changes Should close #5, gets #4 closer
1 parent e651f58 commit d6cf067

File tree

5 files changed

+106
-30
lines changed

5 files changed

+106
-30
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,20 @@ This should only be a temporary solution until the project is listed on a real c
2626

2727
## Configuration
2828

29-
Post install, the new `Varien_Autoload` class needs one more setting to use Composer instead of Magento to autoload: The `VENDOR_ROOT` constant. Generally it's best to configure this in your index file as well as any other entrypoints, such as `cron.php`, `api.php` and others.
29+
Post install, the new `Varien_Autoload` class needs to know where `vendor/autoload.php` is hiding. This must be configured.
3030

31-
### `VENDOR_ROOT`
31+
### Defining the vendor root directory
3232

33-
The `VENDOR_ROOT` constant is the absolute path to your project's `vendor` directory, such that `VENDOR_ROOT . '/autoload.php'` resolves correctly to Composer autoload file. It'd be real nice to not put this config on you our users, but there's no known way around it.
33+
Regardless of how the vendor dir is defined, it **must not end with a trailing slash**.
34+
35+
The two methods of describing the vendor root directory are:
36+
- `VENDOR_ROOT` constant. Must be defined _in all entry points_.
37+
- `MAGE_VENDOR_ROOT` env variable. Be sure it's defined for **all** PHP environments (cli and fpm/mod_php).
3438

3539
## Optimizing the Autoloader
3640

41+
**WARNING: WIP**
42+
3743
Aside from `composer dump -o`, running `php shell/classmap_generator.php` when deploying new code to production is recommended. That script generates a classmap file to be used by composer to speed autoloading of files in Magento's code pools.
3844

3945
To enable use of the generated classmap, include `define('OPTIMIZED_COMPOSER', true)` in `includes/config.php`.

src/Autoload.php

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,62 @@ static public function instance()
6868
}
6969

7070
/**
71-
* Register SPL autoload function
71+
* Returns vendor root directory
72+
* @return string|false
7273
*/
73-
static public function register()
74+
public static function getVendorRootDir()
7475
{
75-
if (!defined('VENDOR_ROOT')) {
76-
spl_autoload_register(array(self::instance(), 'autoload'));
77-
return;
76+
if (isset($_ENV['MAGE_VENDOR_ROOT'])) {
77+
return $_ENV['MAGE_VENDOR_ROOT'];
7878
}
7979

80-
self::registerComposerAutoloader();
80+
if (defined('VENDOR_ROOT')) {
81+
return VENDOR_ROOT;
82+
}
83+
84+
return false;
8185
}
8286

83-
public static function registerComposerAutoloader()
87+
/**
88+
* Get an instance of the Composer Autoloader
89+
*
90+
* @return Composer\Autoload\ClassLoader
91+
* @throws Exception
92+
*/
93+
private static function getComposerAutoloader()
8494
{
85-
$autoloadFilename = VENDOR_ROOT . '/autoload.php';
95+
$vendorDir = self::getVendorRootDir();
8696

97+
$autoloadFilename = $vendorDir . '/autoload.php';
8798
if (!file_exists($autoloadFilename)) {
8899
throw new Exception(
89-
$autoloadFilename . " was not found. Is \"VENDOR_ROOT\" correctly defined?");
100+
'The composer autoload.php file was not found. See README for more information');
101+
}
102+
103+
return require $autoloadFilename;
104+
}
105+
106+
/**
107+
* Register SPL autoload function
108+
*/
109+
static public function register()
110+
{
111+
if (!self::getVendorRootDir()) {
112+
spl_autoload_register(array(self::instance(), 'autoload'));
113+
return;
90114
}
91115

92-
$autoloader = require $autoloadFilename;
116+
self::registerComposerAutoloader();
117+
}
118+
119+
/**
120+
* Add Magento's paths to the Composer autoload directory fallback
121+
* @return void
122+
* @throws Exception
123+
*/
124+
private static function registerComposerAutoloader()
125+
{
126+
$autoloader = self::getComposerAutoloader();
93127

94128
if (defined('OPTIMIZED_COMPOSER')) {
95129
self::registerClassMap($autoloader);

src/abstract_composer.php

Lines changed: 0 additions & 9 deletions
This file was deleted.

src/classmap_generator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
use Composer\Autoload\ClassMapGenerator;
77

8-
require_once 'abstract_composer.php';
8+
require_once 'abstract.php';
99

1010
/**
1111
* Magento Compiler Shell Script

tests/AutoloadTest.php

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,6 @@ class AutoloadTest extends PHPUnit_Framework_TestCase
44
{
55
public function setUp()
66
{
7-
if (!defined('VENDOR_ROOT')) {
8-
define('VENDOR_ROOT', __DIR__ . '/../vendor');
9-
}
10-
117
if (!defined('BP')) {
128
define('BP', __DIR__);
139
}
@@ -17,16 +13,60 @@ public function setUp()
1713

1814
public function testInstance()
1915
{
16+
// This method is used later on, so we should be sure it works
2017
$this->assertInstanceOf('Varien_Autoload', Varien_Autoload::instance());
2118
}
2219

20+
public function testRegisterStandard()
21+
{
22+
Varien_Autoload::register();
23+
$functions = spl_autoload_functions();
24+
25+
$matches = array_filter($functions, function ($function) {
26+
return $function == [Varien_Autoload::instance(), 'autoload'];
27+
});
28+
29+
$this->assertNotCount(0, $matches);
30+
31+
// TODO: find a way to use assertArraySubset
32+
// $this->assertArraySubset(
33+
// [Varien_Autoload::instance(), 'autoload'], $functions);
34+
35+
spl_autoload_unregister([Varien_Autoload::instance(), 'autoload']);
36+
}
37+
38+
public function testRegisterWithEnv()
39+
{
40+
$_ENV['MAGE_VENDOR_ROOT'] = __DIR__ . '/../vendor';
41+
42+
Varien_Autoload::register();
43+
44+
$loader = require __DIR__ . '/../vendor/autoload.php';
45+
46+
$expectedPaths = [
47+
BP . '/app/code/local/',
48+
BP . '/app/code/community/',
49+
BP . '/app/code/core/',
50+
BP . '/lib/',
51+
];
52+
53+
// Ensure that by registering the autoloader
54+
// The expected paths are in the "fallback dirs"
55+
// For autoloading
56+
$this->assertArraySubset(
57+
$expectedPaths, $loader->getFallbackDirs());
58+
}
59+
2360
public function testNotFoundAutoload()
2461
{
25-
$exceptionMessage = VENDOR_ROOT . '/autoload.php was not found. Is "VENDOR_ROOT" correctly defined?';
62+
if (!defined('VENDOR_ROOT')) {
63+
define('VENDOR_ROOT', __DIR__ . '/../vendor');
64+
}
65+
$exceptionMessage = 'The composer autoload.php file was not found. See README for more information';
2666

2767
rename(VENDOR_ROOT . '/autoload.php', VENDOR_ROOT . '/autoload.php.bak');
2868
try {
29-
Varien_Autoload::registerComposerAutoloader();
69+
Varien_Autoload::register();
3070
} catch (Exception $e) {
3171
$this->assertInstanceOf('Exception', $e);
3272
$this->assertEquals($e->getMessage(), $exceptionMessage);
@@ -36,7 +76,11 @@ public function testNotFoundAutoload()
3676

3777
public function testRegisterComposer()
3878
{
39-
Varien_Autoload::registerComposerAutoloader();
79+
if (!defined('VENDOR_ROOT')) {
80+
define('VENDOR_ROOT', __DIR__ . '/../vendor');
81+
}
82+
83+
Varien_Autoload::register();
4084
$loader = require __DIR__ . '/../vendor/autoload.php';
4185

4286
$expectedPaths = [
@@ -52,4 +96,5 @@ public function testRegisterComposer()
5296
$this->assertArraySubset(
5397
$expectedPaths, $loader->getFallbackDirs());
5498
}
99+
55100
}

0 commit comments

Comments
 (0)