Skip to content

Commit acefe01

Browse files
author
Dale Sikkema
committed
Merge remote-tracking branch 'origin/MAGETWO-38031-vendor' into develop
2 parents 13eca91 + a761cc7 commit acefe01

File tree

8 files changed

+275
-37
lines changed

8 files changed

+275
-37
lines changed

app/etc/di.xml

100755100644
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<preference for="Magento\Framework\Config\CacheInterface" type="Magento\Framework\App\Cache\Type\Config" />
4545
<preference for="Magento\Framework\Config\ValidationStateInterface" type="Magento\Framework\App\Arguments\ValidationState" />
4646
<preference for="Magento\Framework\Module\ModuleListInterface" type="Magento\Framework\Module\ModuleList" />
47+
<preference for="Magento\Framework\Module\ModuleRegistryInterface" type="Magento\Framework\Module\Registrar" />
4748
<preference for="Magento\Framework\Event\ConfigInterface" type="Magento\Framework\Event\Config" />
4849
<preference for="Magento\Framework\Event\InvokerInterface" type="Magento\Framework\Event\Invoker\InvokerDefault" />
4950
<preference for="Magento\Framework\Interception\PluginListInterface" type="Magento\Framework\Interception\PluginList\PluginList" />
@@ -1075,6 +1076,11 @@
10751076
<argument name="overriddenBaseFiles" xsi:type="object">lessFileOverriddenBase</argument>
10761077
</arguments>
10771078
</type>
1079+
<type name="Magento\Framework\Module\ModuleList\Loader">
1080+
<arguments>
1081+
<argument name="filesystemDriver" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
1082+
</arguments>
1083+
</type>
10781084
<type name="Magento\Framework\Module\Setup\MigrationData">
10791085
<arguments>
10801086
<argument name="data" xsi:type="array">

lib/internal/Magento/Framework/Module/Dir.php

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,20 @@
1010
use Magento\Framework\App\Filesystem\DirectoryList;
1111
use Magento\Framework\Filesystem;
1212
use Magento\Framework\Filesystem\Directory\ReadInterface;
13+
use Magento\Framework\Stdlib\String as StringHelper;
14+
use Magento\Framework\Module\ModuleRegistryInterface;
1315

1416
class Dir
1517
{
18+
/**#@+
19+
* Directories within modules
20+
*/
21+
const MODULE_ETC_DIR = 'etc';
22+
const MODULE_I18N_DIR = 'i18n';
23+
const MODULE_VIEW_DIR = 'view';
24+
const MODULE_CONTROLLER_DIR = 'Controller';
25+
/**#@-*/
26+
1627
/**
1728
* Modules root directory
1829
*
@@ -25,14 +36,26 @@ class Dir
2536
*/
2637
protected $_string;
2738

39+
/**
40+
* Module registry
41+
*
42+
* @var ModuleRegistryInterface
43+
*/
44+
private $moduleRegistry;
45+
2846
/**
2947
* @param Filesystem $filesystem
30-
* @param \Magento\Framework\Stdlib\String $string
48+
* @param StringHelper $string
49+
* @param ModuleRegistryInterface $moduleRegistry
3150
*/
32-
public function __construct(Filesystem $filesystem, \Magento\Framework\Stdlib\String $string)
33-
{
51+
public function __construct(
52+
Filesystem $filesystem,
53+
StringHelper $string,
54+
ModuleRegistryInterface $moduleRegistry
55+
) {
3456
$this->_modulesDirectory = $filesystem->getDirectoryRead(DirectoryList::MODULES);
3557
$this->_string = $string;
58+
$this->moduleRegistry = $moduleRegistry;
3659
}
3760

3861
/**
@@ -45,16 +68,23 @@ public function __construct(Filesystem $filesystem, \Magento\Framework\Stdlib\St
4568
*/
4669
public function getDir($moduleName, $type = '')
4770
{
48-
$path = $this->_string->upperCaseWords($moduleName, '_', '/');
71+
if (null === $path = $this->moduleRegistry->getModulePath($moduleName)) {
72+
$relativePath = $this->_string->upperCaseWords($moduleName, '_', '/');
73+
$path = $this->_modulesDirectory->getAbsolutePath($relativePath);
74+
}
75+
4976
if ($type) {
50-
if (!in_array($type, ['etc', 'i18n', 'view', 'Controller'])) {
77+
if (!in_array($type, [
78+
self::MODULE_ETC_DIR,
79+
self::MODULE_I18N_DIR,
80+
self::MODULE_VIEW_DIR,
81+
self::MODULE_CONTROLLER_DIR
82+
])) {
5183
throw new \InvalidArgumentException("Directory type '{$type}' is not recognized.");
5284
}
5385
$path .= '/' . $type;
5486
}
5587

56-
$result = $this->_modulesDirectory->getAbsolutePath($path);
57-
58-
return $result;
88+
return $path;
5989
}
6090
}

lib/internal/Magento/Framework/Module/ModuleList/Loader.php

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
use Magento\Framework\Filesystem;
1111
use Magento\Framework\Module\Declaration\Converter\Dom;
1212
use Magento\Framework\Xml\Parser;
13+
use Magento\Framework\Module\ModuleRegistryInterface;
14+
use Magento\Framework\Filesystem\DriverInterface;
1315

1416
/**
1517
* Loader of module list information from the filesystem
@@ -37,19 +39,42 @@ class Loader
3739
*/
3840
private $parser;
3941

42+
/**
43+
* Module registry
44+
*
45+
* @var ModuleRegistryInterface
46+
*/
47+
private $moduleRegistry;
48+
49+
/**
50+
* Filesystem driver to allow reading of module.xml files which live outside of app/code
51+
*
52+
* @var DriverInterface
53+
*/
54+
private $filesystemDriver;
55+
4056
/**
4157
* Constructor
4258
*
4359
* @param Filesystem $filesystem
4460
* @param Dom $converter
4561
* @param Parser $parser
62+
* @param ModuleRegistryInterface $moduleRegistry
63+
* @param DriverInterface $filesystemDriver
4664
*/
47-
public function __construct(Filesystem $filesystem, Dom $converter, Parser $parser)
48-
{
65+
public function __construct(
66+
Filesystem $filesystem,
67+
Dom $converter,
68+
Parser $parser,
69+
ModuleRegistryInterface $moduleRegistry,
70+
DriverInterface $filesystemDriver
71+
) {
4972
$this->filesystem = $filesystem;
5073
$this->converter = $converter;
5174
$this->parser = $parser;
5275
$this->parser->initErrorHandler();
76+
$this->moduleRegistry = $moduleRegistry;
77+
$this->filesystemDriver = $filesystemDriver;
5378
}
5479

5580
/**
@@ -61,10 +86,7 @@ public function __construct(Filesystem $filesystem, Dom $converter, Parser $pars
6186
public function load()
6287
{
6388
$result = [];
64-
$dir = $this->filesystem->getDirectoryRead(DirectoryList::MODULES);
65-
foreach ($dir->search('*/*/etc/module.xml') as $file) {
66-
$contents = $dir->readFile($file);
67-
89+
foreach ($this->getModuleConfigs() as list($file, $contents)) {
6890
try {
6991
$this->parser->loadXML($contents);
7092
} catch (\Magento\Framework\Exception\LocalizedException $e) {
@@ -84,6 +106,31 @@ public function load()
84106
return $this->sortBySequence($result);
85107
}
86108

109+
/**
110+
* Returns module config data and a path to the module.xml file.
111+
*
112+
* Example of data returned by generator:
113+
* <code>
114+
* [ 'vendor/module/etc/module.xml', '<xml>contents</xml>' ]
115+
* </code>
116+
*
117+
* @return \Traversable
118+
*
119+
* @author Josh Di Fabio <joshdifabio@gmail.com>
120+
*/
121+
private function getModuleConfigs()
122+
{
123+
$modulesDir = $this->filesystem->getDirectoryRead(DirectoryList::MODULES);
124+
foreach ($modulesDir->search('*/*/etc/module.xml') as $filePath) {
125+
yield [$filePath, $modulesDir->readFile($filePath)];
126+
}
127+
128+
foreach ($this->moduleRegistry->getModulePaths() as $modulePath) {
129+
$filePath = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, "$modulePath/etc/module.xml");
130+
yield [$filePath, $this->filesystemDriver->fileGetContents($filePath)];
131+
}
132+
}
133+
87134
/**
88135
* Sort the list of modules using "sequence" key in meta-information
89136
*
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\Module;
7+
8+
/**
9+
* @author Josh Di Fabio <joshdifabio@gmail.com>
10+
*/
11+
interface ModuleRegistryInterface
12+
{
13+
/**
14+
* Get list of registered Magento module paths
15+
*
16+
* Returns an array where key is fully-qualified module name and value is absolute path to module
17+
*
18+
* @return array
19+
*/
20+
public function getModulePaths();
21+
22+
/**
23+
* Get path of a module if it is already registered
24+
*
25+
* @param string $moduleName
26+
* @return null|string
27+
*/
28+
public function getModulePath($moduleName);
29+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
/**
3+
* Copyright © 2015 Magento. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\Module;
7+
8+
/**
9+
* Provides ability to statically register modules which do not reside in the modules directory. Not all modules
10+
* will be registered by default.
11+
*
12+
* @author Josh Di Fabio <joshdifabio@gmail.com>
13+
*/
14+
class Registrar implements ModuleRegistryInterface
15+
{
16+
/**
17+
* Paths to modules
18+
*
19+
* @var string[]
20+
*/
21+
private static $modulePaths = [];
22+
23+
/**
24+
* Sets the location of a module. Necessary for modules which do not reside in modules directory
25+
*
26+
* @param string $moduleName Fully-qualified module name
27+
* @param string $path Absolute file path to the module
28+
* @return void
29+
*/
30+
public static function registerModule($moduleName, $path)
31+
{
32+
self::$modulePaths[$moduleName] = $path;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
public function getModulePaths()
39+
{
40+
return self::$modulePaths;
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
public function getModulePath($moduleName)
47+
{
48+
return isset(self::$modulePaths[$moduleName]) ? self::$modulePaths[$moduleName] : null;
49+
}
50+
}

lib/internal/Magento/Framework/Module/Test/Unit/DirTest.php

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ class DirTest extends \PHPUnit_Framework_TestCase
2727
*/
2828
protected $directoryMock;
2929

30+
/**
31+
* @var \Magento\Framework\Module\ModuleRegistryInterface|\PHPUnit_Framework_MockObject_MockObject
32+
*/
33+
protected $moduleRegistryMock;
34+
3035
protected function setUp()
3136
{
3237
$this->filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false, false);
@@ -39,8 +44,14 @@ protected function setUp()
3944
false
4045
);
4146
$this->_stringMock = $this->getMock('Magento\Framework\Stdlib\String', [], [], '', false, false);
42-
43-
$this->_stringMock->expects($this->once())->method('upperCaseWords')->will($this->returnValue('Test/Module'));
47+
$this->moduleRegistryMock = $this->getMock(
48+
'Magento\Framework\Module\ModuleRegistryInterface',
49+
[],
50+
[],
51+
'',
52+
false,
53+
false
54+
);
4455

4556
$this->filesystemMock->expects(
4657
$this->once()
@@ -50,11 +61,27 @@ protected function setUp()
5061
$this->returnValue($this->directoryMock)
5162
);
5263

53-
$this->_model = new \Magento\Framework\Module\Dir($this->filesystemMock, $this->_stringMock);
64+
$this->_model = new \Magento\Framework\Module\Dir(
65+
$this->filesystemMock,
66+
$this->_stringMock,
67+
$this->moduleRegistryMock
68+
);
5469
}
5570

5671
public function testGetDirModuleRoot()
5772
{
73+
$this->moduleRegistryMock->expects(
74+
$this->once()
75+
)->method(
76+
'getModulePath'
77+
)->with(
78+
'Test_Module'
79+
)->will(
80+
$this->returnValue(null)
81+
);
82+
83+
$this->_stringMock->expects($this->once())->method('upperCaseWords')->will($this->returnValue('Test/Module'));
84+
5885
$this->directoryMock->expects(
5986
$this->once()
6087
)->method(
@@ -64,20 +91,39 @@ public function testGetDirModuleRoot()
6491
)->will(
6592
$this->returnValue('/Test/Module')
6693
);
94+
6795
$this->assertEquals('/Test/Module', $this->_model->getDir('Test_Module'));
6896
}
6997

98+
public function testGetDirModuleRootFromResolver()
99+
{
100+
$this->moduleRegistryMock->expects(
101+
$this->once()
102+
)->method(
103+
'getModulePath'
104+
)->with(
105+
'Test_Module2'
106+
)->will(
107+
$this->returnValue('/path/to/module')
108+
);
109+
110+
$this->assertEquals('/path/to/module', $this->_model->getDir('Test_Module2'));
111+
}
112+
70113
public function testGetDirModuleSubDir()
71114
{
115+
$this->_stringMock->expects($this->once())->method('upperCaseWords')->will($this->returnValue('Test/Module'));
116+
72117
$this->directoryMock->expects(
73118
$this->once()
74119
)->method(
75120
'getAbsolutePath'
76121
)->with(
77-
'Test/Module/etc'
122+
'Test/Module'
78123
)->will(
79-
$this->returnValue('/Test/Module/etc')
124+
$this->returnValue('/Test/Module')
80125
);
126+
81127
$this->assertEquals('/Test/Module/etc', $this->_model->getDir('Test_Module', 'etc'));
82128
}
83129

@@ -87,6 +133,8 @@ public function testGetDirModuleSubDir()
87133
*/
88134
public function testGetDirModuleSubDirUnknown()
89135
{
136+
$this->_stringMock->expects($this->once())->method('upperCaseWords')->will($this->returnValue('Test/Module'));
137+
90138
$this->_model->getDir('Test_Module', 'unknown');
91139
}
92140
}

0 commit comments

Comments
 (0)