Skip to content

Commit 6c311ce

Browse files
committed
MAGETWO-32782: [TD] Third party interfaces are not supported by single-tenant compiler
- implemented check for external interfaces mention in preferences configuration - removed obsolete types from config
1 parent ad849eb commit 6c311ce

File tree

9 files changed

+233
-70
lines changed

9 files changed

+233
-70
lines changed

app/code/Magento/Backend/etc/di.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
<preference for="Magento\Backend\Model\Config\Structure\SearchInterface" type="Magento\Backend\Model\Config\Structure" />
1313
<preference for="Magento\Backend\Model\Config\Backend\File\RequestData\RequestDataInterface" type="Magento\Backend\Model\Config\Backend\File\RequestData" />
1414
<preference for="Magento\Backend\Model\Auth\Credential\StorageInterface" type="Magento\User\Model\User" />
15-
<preference for="Magento\Adminhtml\Helper\Data" type="Magento\Backend\Helper\Data" />
1615
<preference for="Magento\Backend\App\ConfigInterface" type="Magento\Backend\App\Config" />
1716
<preference for="Magento\Backend\Model\UrlInterface" type="Magento\Backend\Model\Url" />
1817
<preference for="Magento\Backend\Block\Widget\Button\ToolbarInterface" type="Magento\Backend\Block\Widget\Button\Toolbar" />

app/code/Magento/Core/etc/di.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,12 @@
1414
<preference for="Magento\Framework\Authorization\PolicyInterface" type="Magento\Framework\Authorization\Policy\DefaultPolicy" />
1515
<preference for="Magento\Framework\Authorization\RoleLocatorInterface" type="Magento\Framework\Authorization\RoleLocator\DefaultRoleLocator" />
1616
<preference for="Magento\Framework\Session\SessionManagerInterface" type="Magento\Framework\Session\Generic" />
17-
<preference for="Magento\Core\Model\DataService\ConfigInterface" type="Magento\Core\Model\DataService\Config" />
1817
<preference for="Magento\Framework\App\Config\ScopeConfigInterface" type="Magento\Framework\App\Config" />
1918
<preference for="Magento\Framework\App\Config\ReinitableConfigInterface" type="Magento\Framework\App\ReinitableConfig" />
2019
<preference for="Magento\Framework\App\Config\MutableScopeConfigInterface" type="Magento\Framework\App\MutableScopeConfig" />
2120
<preference for="Magento\Framework\App\Config\Storage\WriterInterface" type="Magento\Framework\App\Config\Storage\Writer" />
2221
<preference for="Magento\Framework\View\Design\Theme\FileInterface" type="Magento\Core\Model\Theme\File" />
2322
<preference for="Magento\Framework\Config\ConverterInterface" type="Magento\Framework\Config\Converter\Dom"/>
24-
<preference for="Magento\Core\Model\Url\SecurityInfoInterface" type="Magento\Core\Model\Url\SecurityInfo\Proxy" />
2523
<preference for="Magento\Framework\App\DefaultPathInterface" type="Magento\Framework\App\DefaultPath\DefaultPath" />
2624
<preference for="Magento\Framework\Encryption\EncryptorInterface" type="Magento\Framework\Encryption\Encryptor" />
2725
<preference for="Magento\Framework\Filter\Encrypt\AdapterInterface" type="Magento\Framework\Filter\Encrypt\Basic" />

dev/tests/unit/testsuite/Magento/Tools/Di/Compiler/Config/ReaderTest.php

Lines changed: 178 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Tools\Di\Compiler\Config;
77

8+
use Magento\Framework\App\Area;
9+
use Magento\Tools\Di\Definition\Collection;
10+
811
class ReaderTest extends \PHPUnit_Framework_TestCase
912
{
1013
/**
@@ -54,6 +57,9 @@ protected function setUp()
5457
false
5558
);
5659
$this->argumentsResolver = $this->getMock('Magento\Tools\Di\Compiler\ArgumentsResolver', [], [], '', false);
60+
$this->argumentsResolverFactory->expects($this->any())
61+
->method('create')
62+
->willReturn($this->argumentsResolver);
5763
$this->classReaderDecorator = $this->getMock(
5864
'Magento\Tools\Di\Code\Reader\ClassReaderDecorator',
5965
[],
@@ -72,71 +78,182 @@ protected function setUp()
7278
);
7379
}
7480

75-
public function testGenerateCachePerScopeExtends()
81+
public function testGenerateCachePerScopeGlobal()
7682
{
77-
$definitionsCollection = $this->getMock('Magento\Tools\Di\Definition\Collection', [], [], '', false);
78-
$this->diContainerConfig->expects($this->once())
79-
->method('extend')
80-
->with([]);
81-
$this->configLoader->expects($this->once())
82-
->method('load')
83-
->with('areaCode')
84-
->willReturn([]);
85-
86-
$this->argumentsResolverFactory->expects($this->once())
87-
->method('create')
88-
->with($this->diContainerConfig)
89-
->willReturn($this->argumentsResolver);
90-
$definitionsCollection->expects($this->exactly(2))
91-
->method('getInstancesNamesList')
92-
->willReturn(['instanceType1'], ['instanceType2']);
93-
$definitionsCollection->expects($this->once())
94-
->method('getInstanceArguments')
95-
->willReturnMap([
96-
['instanceType1', null],
97-
['instanceType2', ['arg1', 'arg2']],
98-
]);
99-
$this->typeReader->expects($this->exactly(3))
100-
->method('isConcrete')
101-
->willReturnMap([
102-
['instanceType1', true],
103-
['instanceType2', false],
104-
['originalType1', true],
105-
['originalType2', false],
106-
]);
107-
$this->argumentsResolver->expects($this->exactly(2))
108-
->method('getResolvedConstructorArguments')
109-
->willReturnMap([
110-
['instanceType1', 'resolvedConstructor1'],
111-
['instanceVirtualType1', 'resolvedConstructor2'],
112-
]);
113-
$this->diContainerConfig->expects($this->exactly(2))
83+
$definitionCollection = $this->getDefinitionsCollection();
84+
$this->diContainerConfig->expects($this->any())
11485
->method('getVirtualTypes')
115-
->willReturn(['instanceVirtualType1' => 1, 'instanceVirtualType2' => 2]);
116-
$this->diContainerConfig->expects($this->exactly(4))
86+
->willReturn($this->getVirtualTypes());
87+
$this->diContainerConfig->expects($this->any())
88+
->method('getPreferences')
89+
->willReturn($this->getPreferences());
90+
91+
$getResolvedConstructorArgumentsMap = $this->getResolvedVirtualConstructorArgumentsMap(
92+
$definitionCollection,
93+
$this->getVirtualTypes()
94+
);
95+
96+
$this->diContainerConfig->expects($this->any())
11797
->method('getInstanceType')
118-
->willReturnMap([
119-
['instanceVirtualType1', 'originalType1'],
120-
['instanceVirtualType2', 'originalType2'],
121-
]);
122-
$definitionsCollection->expects($this->exactly(2))
123-
->method('hasInstance')
124-
->willReturn('');
125-
$this->classReaderDecorator->expects($this->once())
126-
->method('getConstructor')
127-
->willReturn('constructor');
128-
$this->diContainerConfig->expects($this->once())
98+
->willReturnMap($this->getInstanceTypeMap($this->getVirtualTypes()));
99+
100+
$this->diContainerConfig->expects($this->any())
129101
->method('isShared')
130-
->willReturnMap([
131-
['instanceType1', true],
132-
['instanceType2', false],
133-
]);
134-
$this->diContainerConfig->expects($this->once())
102+
->willReturnMap($this->getExpectedNonShared());
103+
104+
$this->diContainerConfig->expects($this->any())
135105
->method('getPreference')
136-
->willReturnMap([
137-
['instanceType1', 'instanceType1ss'],
138-
['instanceType2', 'instanceType2'],
139-
]);
140-
$this->model->generateCachePerScope($definitionsCollection, 'areaCode');
106+
->willReturnMap($this->getPreferencesMap());
107+
108+
$isConcreteMap = [];
109+
foreach($definitionCollection->getInstancesNamesList() as $instanceType) {
110+
$isConcreteMap[] = [$instanceType, strpos($instanceType, 'Interface') === false];
111+
112+
$getResolvedConstructorArgumentsMap[] = [
113+
$instanceType,
114+
$definitionCollection->getInstanceArguments($instanceType),
115+
$this->getResolvedArguments(
116+
$definitionCollection->getInstanceArguments($instanceType)
117+
)
118+
];
119+
}
120+
121+
$this->typeReader->expects($this->any())
122+
->method('isConcrete')
123+
->willReturnMap($isConcreteMap);
124+
$this->argumentsResolver->expects($this->any())
125+
->method('getResolvedConstructorArguments')
126+
->willReturnMap($getResolvedConstructorArgumentsMap);
127+
128+
$this->assertEquals(
129+
$this->getExpectedGlobalConfig(),
130+
$this->model->generateCachePerScope($definitionCollection, Area::AREA_GLOBAL)
131+
);
132+
}
133+
134+
/**
135+
* @return array
136+
*/
137+
private function getExpectedGlobalConfig()
138+
{
139+
return [
140+
'arguments' => [
141+
'ConcreteType1' => serialize(['resolved_argument1', 'resolved_argument2']),
142+
'ConcreteType2' => serialize(['resolved_argument1', 'resolved_argument2']),
143+
'virtualType1' => serialize(['resolved_argument1', 'resolved_argument2'])
144+
],
145+
'nonShared' => [
146+
'ConcreteType2' => true,
147+
'ThirdPartyInterface' => true
148+
],
149+
'preferences' => $this->getPreferences(),
150+
'instanceTypes' => $this->getVirtualTypes(),
151+
];
152+
}
153+
154+
/**
155+
* @return Collection
156+
*/
157+
private function getDefinitionsCollection()
158+
{
159+
$definitionCollection = new Collection();
160+
$definitionCollection->addDefinition('ConcreteType1', ['argument1', 'argument2']);
161+
$definitionCollection->addDefinition('ConcreteType2', ['argument1', 'argument2']);
162+
$definitionCollection->addDefinition('Interface1', [null]);
163+
164+
return $definitionCollection;
165+
}
166+
167+
/**
168+
* @return array
169+
*/
170+
private function getVirtualTypes()
171+
{
172+
return ['virtualType1' => 'ConcreteType1'];
173+
}
174+
175+
/**
176+
* @return array
177+
*/
178+
private function getExpectedNonShared()
179+
{
180+
return [
181+
['ConcreteType1', true],
182+
['ConcreteType2', false],
183+
['Interface1', true],
184+
['ThirdPartyInterface', false]
185+
];
186+
}
187+
188+
/**
189+
* @return array
190+
*/
191+
private function getPreferences()
192+
{
193+
return [
194+
'Interface1' => 'ConcreteType1',
195+
'ThirdPartyInterface' => 'ConcreteType2'
196+
];
197+
}
198+
199+
/**
200+
* @return array
201+
*/
202+
private function getPreferencesMap()
203+
{
204+
return [
205+
['ConcreteType1', 'ConcreteType1'],
206+
['ConcreteType2', 'ConcreteType2'],
207+
['Interface1', 'ConcreteType1'],
208+
['ThirdPartyInterface', 'ConcreteType2']
209+
];
210+
}
211+
212+
/**
213+
* @param array $arguments
214+
* @return array|null
215+
*/
216+
private function getResolvedArguments($arguments)
217+
{
218+
return empty($arguments) ? null : array_map(
219+
function($argument) {
220+
return 'resolved_' . $argument;
221+
},
222+
$arguments
223+
);
224+
}
225+
226+
/**
227+
* @param array $virtualTypes
228+
* @return array
229+
*/
230+
private function getInstanceTypeMap($virtualTypes)
231+
{
232+
$getInstanceTypeMap = [];
233+
foreach ($virtualTypes as $virtualType => $concreteType) {
234+
$getInstanceTypeMap[] = [$virtualType, $concreteType];
235+
}
236+
237+
return $getInstanceTypeMap;
238+
}
239+
240+
/**
241+
* @param Collection $definitionCollection
242+
* @param array $virtualTypes
243+
* @return array
244+
*/
245+
private function getResolvedVirtualConstructorArgumentsMap(Collection $definitionCollection, array $virtualTypes)
246+
{
247+
$getResolvedConstructorArgumentsMap = [];
248+
foreach ($virtualTypes as $virtualType => $concreteType) {
249+
$getResolvedConstructorArgumentsMap[] = [
250+
$virtualType,
251+
$definitionCollection->getInstanceArguments($concreteType),
252+
$this->getResolvedArguments(
253+
$definitionCollection->getInstanceArguments($concreteType)
254+
)
255+
];
256+
}
257+
return $getResolvedConstructorArgumentsMap;
141258
}
142259
}

dev/tools/Magento/Tools/Di/Code/Reader/ClassesScanner.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function getList($path)
4141
}
4242
$classes = [];
4343
$recursiveIterator = new \RecursiveIteratorIterator(
44-
new \RecursiveDirectoryIterator($realPath),
44+
new \RecursiveDirectoryIterator($realPath, \FilesystemIterator::FOLLOW_SYMLINKS),
4545
\RecursiveIteratorIterator::SELF_FIRST
4646
);
4747
/** @var $fileItem \SplFileInfo */

dev/tools/Magento/Tools/Di/Compiler/Config/Reader.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class Reader
4949
* @param Type $typeReader
5050
*/
5151
public function __construct(
52-
\Magento\Framework\ObjectManager\ConfigInterface $diContainerConfig,
52+
ConfigInterface $diContainerConfig,
5353
App\ObjectManager\ConfigLoader $configLoader,
5454
ArgumentsResolverFactory $argumentsResolverFactory,
5555
ClassReaderDecorator $classReaderDecorator,
@@ -86,6 +86,8 @@ public function generateCachePerScope(
8686
$config['arguments'][$key] = serialize($value);
8787
}
8888
}
89+
90+
$this->fillThirdPartyInterfaces($areaConfig, $definitionsCollection);
8991
foreach ($definitionsCollection->getInstancesNamesList() as $instanceName) {
9092
if (!$areaConfig->isShared($instanceName)) {
9193
$config['nonShared'][$instanceName] = true;
@@ -95,6 +97,7 @@ public function generateCachePerScope(
9597
$config['preferences'][$instanceName] = $preference;
9698
}
9799
}
100+
98101
foreach (array_keys($areaConfig->getVirtualTypes()) as $virtualType) {
99102
$config['instanceTypes'][$virtualType] = $areaConfig->getInstanceType($virtualType);
100103
}
@@ -140,4 +143,23 @@ private function getConfigForScope(DefinitionsCollection $definitionsCollection,
140143
}
141144
return $constructors;
142145
}
146+
147+
/**
148+
* Returns preferences for third party code
149+
*
150+
* @param ConfigInterface $config
151+
* @param DefinitionsCollection $definitionsCollection
152+
*/
153+
private function fillThirdPartyInterfaces(ConfigInterface $config, DefinitionsCollection $definitionsCollection)
154+
{
155+
$definedInstances = $definitionsCollection->getInstancesNamesList();
156+
157+
foreach ($config->getPreferences() as $interface => $preference) {
158+
if (in_array($interface, $definedInstances)) {
159+
continue;
160+
}
161+
162+
$definitionsCollection->addDefinition($interface, []);
163+
}
164+
}
143165
}

dev/tools/Magento/Tools/Di/Definition/Collection.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function getCollection()
3333
*
3434
* @return void
3535
*/
36-
public function initialize($definitions)
36+
public function initialize(array $definitions)
3737
{
3838
$this->definitions = $definitions;
3939
}
@@ -54,7 +54,7 @@ public function addCollection(Collection $collection)
5454
* Add new definition for instance
5555
*
5656
* @param string $instance
57-
* @param array $arguments
57+
* @param array|null $arguments
5858
*
5959
* @return void
6060
*/
@@ -63,11 +63,11 @@ public function addDefinition($instance, $arguments = [])
6363
$this->definitions[$instance] = $arguments;
6464
}
6565

66-
/**
66+
/**+
6767
* Returns instance arguments
6868
*
6969
* @param string $instanceName
70-
* @return null
70+
* @return null|array
7171
*/
7272
public function getInstanceArguments($instanceName)
7373
{

lib/internal/Magento/Framework/ObjectManager/Config/Compiled.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,14 @@ public function getVirtualTypes()
145145
{
146146
return $this->virtualTypes;
147147
}
148+
149+
/**
150+
* Returns list on preferences
151+
*
152+
* @return array
153+
*/
154+
public function getPreferences()
155+
{
156+
return $this->preferences;
157+
}
148158
}

0 commit comments

Comments
 (0)