PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/dev/tools/di/compiler.php

https://bitbucket.org/sunil_nextbits/magento2
PHP | 301 lines | 161 code | 34 blank | 106 comment | 22 complexity | 390dd73477992f48f19f0a2ffbd3512e MD5 | raw file
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Tools
  22. * @package DI
  23. * @copyright Copyright (c) 2012 X.commerce, Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Constants definition
  28. */
  29. define('DS', DIRECTORY_SEPARATOR);
  30. define('BP', realpath(__DIR__ . '/../../..'));
  31. /**
  32. * Require necessary files
  33. */
  34. require_once BP . '/app/code/core/Mage/Core/functions.php';
  35. require_once BP . '/app/Mage.php';
  36. require __DIR__ . '/../../../app/autoload.php';
  37. Magento_Autoload_IncludePath::addIncludePath(array(
  38. BP . DS . 'app' . DS . 'code' . DS . 'local',
  39. BP . DS . 'app' . DS . 'code' . DS . 'community',
  40. BP . DS . 'app' . DS . 'code' . DS . 'core',
  41. BP . DS . 'lib',
  42. ));
  43. Mage::setRoot();
  44. $definitions = array();
  45. class ArrayDefinitionCompiler
  46. {
  47. /**#@+
  48. * Abstract classes
  49. */
  50. const ABSTRACT_MODEL = 'Mage_Core_Model_Abstract';
  51. const ABSTRACT_BLOCK = 'Mage_Core_Block_Abstract';
  52. /**#@-*/
  53. /**
  54. * Main config
  55. *
  56. * @var Mage_Core_Model_Config
  57. */
  58. protected $_config;
  59. /**
  60. * Information about abstract block/model constructor
  61. *
  62. * @var ReflectionMethod[]
  63. */
  64. protected $_constructorList;
  65. /**
  66. * List of common dependencies for model and block abstract
  67. *
  68. * @var array
  69. */
  70. protected $_commonDependencies = array();
  71. /**
  72. * Class constructor
  73. */
  74. public function __construct()
  75. {
  76. $this->_config = new Mage_Core_Model_Config(new Magento_ObjectManager_Zend());
  77. $this->_config->loadBase();
  78. $this->_config->loadModules();
  79. $this->_initCommonDependencies();
  80. }
  81. /**
  82. * Compile module definitions
  83. *
  84. * @param string $moduleDir
  85. * @return array
  86. */
  87. public function compileModule($moduleDir)
  88. {
  89. $moduleDefinitions = $this->_compileModuleDefinitions($moduleDir);
  90. $this->_removeModelAndBlockConstructors($moduleDefinitions);
  91. array_walk($moduleDefinitions, function (&$item)
  92. {
  93. unset($item['supertypes']);
  94. });
  95. return $moduleDefinitions;
  96. }
  97. /**
  98. * Check is module enabled
  99. *
  100. * @param string $moduleName
  101. * @return bool
  102. */
  103. public function isModuleEnabled($moduleName)
  104. {
  105. return $this->_config->isModuleEnabled($moduleName);
  106. }
  107. /**
  108. * Init list of common dependencies of model and block abstract classes
  109. *
  110. * @return ArrayDefinitionCompiler
  111. */
  112. protected function _initCommonDependencies()
  113. {
  114. $classList = array(
  115. self::ABSTRACT_MODEL,
  116. self::ABSTRACT_BLOCK
  117. );
  118. foreach ($classList as $className) {
  119. $this->_constructorList[$className] = new ReflectionMethod($className, '__construct');
  120. /** @var $param ReflectionParameter */
  121. foreach ($this->_constructorList[$className]->getParameters() as $param) {
  122. if ($param->getClass() && !in_array($param->getClass()->getName(), $this->_commonDependencies)) {
  123. $this->_commonDependencies[] = $param->getClass()->getName();
  124. }
  125. }
  126. }
  127. return $this;
  128. }
  129. /**
  130. * Compile definitions using Magento_Di_Definition_CompilerDefinition_Zend
  131. *
  132. * @param string $moduleDir
  133. * @return array
  134. */
  135. protected function _compileModuleDefinitions($moduleDir)
  136. {
  137. $strategy = new \Zend\Di\Definition\IntrospectionStrategy(new \Zend\Code\Annotation\AnnotationManager());
  138. $strategy->setMethodNameInclusionPatterns(array());
  139. $strategy->setInterfaceInjectionInclusionPatterns(array());
  140. $compiler = new Magento_Di_Definition_CompilerDefinition_Zend($strategy);
  141. $compiler->addDirectory($moduleDir);
  142. $controllerPath = $moduleDir . '/controllers/';
  143. if (file_exists($controllerPath)) {
  144. /** @var $file DirectoryIterator */
  145. foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($controllerPath)) as $file) {
  146. if (!$file->isDir()) {
  147. require_once $file->getPathname();
  148. }
  149. }
  150. }
  151. $compiler->compile();
  152. $moduleDefinitions = $compiler->toArray();
  153. return $moduleDefinitions;
  154. }
  155. /**
  156. * Remove model and block constructors
  157. *
  158. * @see Zend\Di\Di::newInstance()
  159. * @param $moduleDefinitions
  160. */
  161. protected function _removeModelAndBlockConstructors(&$moduleDefinitions)
  162. {
  163. foreach ($moduleDefinitions as $name => $definition) {
  164. if (!$this->_hasConstructorParams($name, $definition)
  165. || $this->_areConstructorParamsEquals(self::ABSTRACT_MODEL, $definition)
  166. || $this->_areConstructorParamsEquals(self::ABSTRACT_BLOCK, $definition)
  167. ) {
  168. unset($moduleDefinitions[$name]);
  169. }
  170. }
  171. }
  172. /**
  173. * Check if class has constructor params
  174. *
  175. * For cases when *_Model_* found function will return true, because such classes must be in compiled array.
  176. *
  177. * @param $className
  178. * @param $definition
  179. * @return bool
  180. */
  181. protected function _hasConstructorParams($className, $definition)
  182. {
  183. $constructorParams = array();
  184. if (isset($definition['parameters']['__construct'])) {
  185. $constructorParams = array_values($definition['parameters']['__construct']);
  186. }
  187. $paramNumber = count($constructorParams);
  188. if (!$paramNumber && in_array($className, $this->_commonDependencies)) {
  189. return true;
  190. }
  191. return (bool) $paramNumber;
  192. }
  193. /**
  194. * Check is class constructor params are same as in abstract
  195. *
  196. * @param string $className
  197. * @param array $definition
  198. * @return bool
  199. */
  200. protected function _areConstructorParamsEquals($className, $definition)
  201. {
  202. if (!isset($this->_constructorList[$className])) {
  203. $this->_constructorList[$className] = new ReflectionMethod($className, '__construct');
  204. }
  205. if (isset($definition['supertypes']) && isset($definition['parameters']['__construct'])) {
  206. foreach ($definition['supertypes'] as $type) {
  207. if (($type == $className)
  208. && (count($definition['parameters']['__construct']) ==
  209. count($this->_constructorList[$className]->getParameters())
  210. )
  211. ) {
  212. return $this->_compareConstructorParams($definition['parameters']['__construct'],
  213. $this->_constructorList[$className]->getParameters()
  214. );
  215. }
  216. }
  217. }
  218. return false;
  219. }
  220. /**
  221. * Compare constructors params
  222. *
  223. * @param array $classArguments
  224. * @param ReflectionParameter[] $abstractArguments
  225. * @return bool
  226. */
  227. protected function _compareConstructorParams($classArguments, $abstractArguments)
  228. {
  229. $index = 0;
  230. foreach ($classArguments as $argumentInfo) {
  231. $argumentType = null;
  232. if ($abstractArguments[$index]->getClass()) {
  233. $argumentType = $abstractArguments[$index]->getClass()->getName();
  234. }
  235. if ($argumentInfo[1] != $argumentType) {
  236. return false;
  237. }
  238. $index++;
  239. }
  240. return true;
  241. }
  242. }
  243. $compiler = new ArrayDefinitionCompiler();
  244. foreach (glob(BP . '/app/code/*') as $codePoolDir) {
  245. foreach (glob($codePoolDir . '/*') as $vendorDir) {
  246. foreach (glob($vendorDir . '/*') as $moduleDir) {
  247. $moduleName = basename($vendorDir) . '_' . basename($moduleDir);
  248. if (is_dir($moduleDir) && $compiler->isModuleEnabled($moduleName)) {
  249. echo "Compiling module " . $moduleName . "\n";
  250. $definitions = array_merge_recursive($definitions, $compiler->compileModule($moduleDir));
  251. }
  252. }
  253. }
  254. }
  255. echo "Compiling Varien\n";
  256. $definitions = array_merge_recursive($definitions, $compiler->compileModule(BP . '/lib/Varien'));
  257. echo "Compiling Magento\n";
  258. $definitions = array_merge_recursive($definitions, $compiler->compileModule(BP . '/lib/Magento'));
  259. echo "Compiling Mage\n";
  260. $definitions = array_merge_recursive($definitions, $compiler->compileModule(BP . '/lib/Mage'));
  261. foreach ($definitions as $key => $definition) {
  262. $definitions[$key] = json_encode($definition);
  263. }
  264. if (!file_exists(BP . '/var/di/')) {
  265. mkdir(BP . '/var/di', 0777, true);
  266. }
  267. file_put_contents(BP . '/var/di/definitions.php', serialize($definitions));