/app/code/core/Mage/Compiler/Model/Process.php
PHP | 451 lines | 316 code | 32 blank | 103 comment | 65 complexity | 5292839c5bd7ababd2df84f21fa564de MD5 | raw file
- <?php
- /**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magento.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magento.com for more information.
- *
- * @category Mage
- * @package Mage_Compiler
- * @copyright Copyright (c) 2006-2015 X.commerce, Inc. (http://www.magento.com)
- * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
- */
- /**
- * Compilation process model
- *
- * @category Mage
- * @package Mage_Compiler
- * @author Magento Core Team <core@magentocommerce.com>
- */
- class Mage_Compiler_Model_Process
- {
- protected $_compileDir = null;
- protected $_includeDir = null;
- protected $_statDir = null;
- protected $_compileConfig = null;
- protected $_includePaths = array();
- protected $_processedClasses= array();
- protected $_controllerFolders = array();
- public function __construct($options=array())
- {
- if (isset($options['compile_dir'])) {
- $this->_compileDir = $options['compile_dir'];
- } else {
- $this->_compileDir = Mage::getBaseDir() . DS . 'includes';
- }
- $this->_includeDir = $this->_compileDir . DS . 'src';
- $this->_statDir = $this->_compileDir . DS . 'stat';
- }
- /**
- * Get compilation config
- *
- * @return Mage_Core_Model_Config_Base
- */
- public function getCompileConfig()
- {
- if ($this->_compileConfig === null) {
- $this->_compileConfig = Mage::getConfig()->loadModulesConfiguration('compilation.xml');
- }
- return $this->_compileConfig;
- }
- /**
- * Get allowed include paths
- *
- * @return array
- */
- protected function _getIncludePaths()
- {
- if (empty($this->_includePaths)) {
- $originalPath = Mage::registry('original_include_path');
- /**
- * Exclude current dirrectory include path
- */
- if ($originalPath == '.') {
- $path = get_include_path();
- } else {
- $path = str_replace($originalPath, '', get_include_path());
- }
-
- $this->_includePaths = explode(PS, $path);
- foreach ($this->_includePaths as $index => $path) {
- if (empty($path) || $path == '.') {
- unset($this->_includePaths[$index]);
- }
- }
- }
- return $this->_includePaths;
- }
- /**
- * Copy directory
- *
- * @param string $source
- * @param string $target
- * @return Mage_Compiler_Model_Process
- */
- protected function _copy($source, $target, $firstIteration = true)
- {
- if (is_dir($source)) {
- $dir = dir($source);
- while (false !== ($file = $dir->read())) {
- if (($file[0] == '.')) {
- continue;
- }
- $sourceFile = $source . DS . $file;
- if ($file == 'controllers') {
- $this->_controllerFolders[] = $sourceFile;
- continue;
- }
- if ($firstIteration) {
- $targetFile = $target . DS . $file;
- } else {
- $targetFile = $target . '_' . $file;
- }
- $this->_copy($sourceFile, $targetFile, false);
- }
- } else {
- if (strpos(str_replace($this->_includeDir, '', $target), '-')
- || !in_array(substr($source, strlen($source)-4, 4), array('.php'))) {
- return $this;
- }
- copy($source, $target);
- }
- return $this;
- }
- /**
- * Copy Zend Locale data to compilation folter
- *
- * @param string $destDir
- * @return Mage_Compiler_Model_Process
- */
- protected function _copyZendLocaleData($destDir)
- {
- $source = Mage::getBaseDir('lib').DS.'Zend'.DS.'Locale'.DS.'Data';
- $dir = dir($source);
- while (false !== ($file = $dir->read())) {
- if (($file[0] == '.')) {
- continue;
- }
- $sourceFile = $source . DS . $file;
- $targetFile = $destDir . DS . $file;
- copy($sourceFile, $targetFile);
- }
- return $this;
- }
- /**
- * Copy controllers with folders structure
- *
- * @param string $basePath base include path where files are located
- * @return Mage_Compiler_Model_Process
- */
- protected function _copyControllers($basePath)
- {
- foreach ($this->_controllerFolders as $path) {
- $relPath = str_replace($basePath, '', $path);
- $relPath = trim($relPath, DS);
- $arrDirs = explode(DS, $relPath);
- $destPath = $this->_includeDir;
- foreach ($arrDirs as $dir) {
- $destPath.= DS.$dir;
- $this->_mkdir($destPath);
- }
- $this->_copyAll($path, $destPath);
- }
- return $this;
- }
- /**
- * Copy all files and subfolders
- *
- * @param string $source
- * @param string $target
- * @return Mage_Compiler_Model_Process
- */
- protected function _copyAll($source, $target)
- {
- if (is_dir($source)) {
- $this->_mkdir($target);
- $dir = dir($source);
- while (false !== ($file = $dir->read())) {
- if (($file[0] == '.')) {
- continue;
- }
- $sourceFile = $source . DS . $file;
- $targetFile = $target . DS . $file;
- $this->_copyAll($sourceFile, $targetFile);
- }
- } else {
- if (!in_array(substr($source, strlen($source)-4, 4), array('.php'))) {
- return $this;
- }
- copy($source, $target);
- }
- return $this;
- }
- /**
- * Create directory if not exist
- *
- * @param string $dir
- * @return string
- */
- protected function _mkdir($dir)
- {
- if (!is_dir($dir)) {
- mkdir($dir);
- @chmod($dir, 0777);
- }
- return $dir;
- }
- /**
- * Copy files from all include directories to one.
- * Lib files and controllers files will be copied as is
- *
- * @return Mage_Compiler_Model_Process
- */
- protected function _collectFiles()
- {
- $paths = $this->_getIncludePaths();
- $paths = array_reverse($paths);
- $destDir= $this->_includeDir;
- $libDir = Mage::getBaseDir('lib');
- $this->_mkdir($destDir);
- foreach ($paths as $path) {
- $this->_controllerFolders = array();
- $this->_copy($path, $destDir);
- $this->_copyControllers($path);
- if ($path == $libDir) {
- $this->_copyAll($libDir, $destDir);
- }
- }
- $destDir.= DS.'Data';
- $this->_mkdir($destDir);
- $this->_copyZendLocaleData($destDir);
- return $this;
- }
- public function getCollectedFilesCount()
- {
- return count(glob($this->_includeDir.DS.'*'));
- }
- public function getCompiledFilesCount()
- {
- return count(glob($this->_includeDir.DS.Varien_Autoload::SCOPE_FILE_PREFIX.'*'));
- }
- public function getCompileClassList()
- {
- $arrFiles = array();
- $statDir = $this->_statDir;
- $statFiles= array();
- if (is_dir($statDir)) {
- $dir = dir($statDir);
- while (false !== ($file = $dir->read())) {
- if (($file[0] == '.')) {
- continue;
- }
- $statFiles[str_replace('.csv', '', $file)] = $this->_statDir.DS.$file;
- }
- }
- foreach ($this->getCompileConfig()->getNode('includes')->children() as $code => $config) {
- $classes = $config->asArray();
- if (is_array($classes)) {
- $arrFiles[$code] = array_keys($classes);
- } else {
- $arrFiles[$code] = array();
- }
- $statClasses = array();
- if (isset($statFiles[$code])) {
- $statClasses = explode("\n", file_get_contents($statFiles[$code]));
- $popularStatClasses = array();
- foreach ($statClasses as $index => $classInfo) {
- $classInfo = explode(':', $classInfo);
- $popularStatClasses[$classInfo[1]][] = $classInfo[0];
- }
- ksort($popularStatClasses);
- $statClasses = array_pop($popularStatClasses);
- unset($statFiles[$code]);
- }
- $arrFiles[$code] = array_merge($arrFiles[$code], $statClasses);
- $arrFiles[$code] = array_unique($arrFiles[$code]);
- sort($arrFiles[$code]);
- }
- foreach($statFiles as $code => $file) {
- $classes = explode("\n", file_get_contents($file));
- $popularStatClasses = array();
- foreach ($classes as $index => $classInfo) {
- $classInfo = explode(':', $classInfo);
- $popularStatClasses[$classInfo[1]][] = $classInfo[0];
- }
- ksort($popularStatClasses);
- $arrFiles[$code] = array_pop($popularStatClasses);
- }
- foreach ($arrFiles as $scope=>$classes) {
- if ($scope != 'default') {
- foreach ($classes as $index => $class) {
- if (in_array($class, $arrFiles['default'])) {
- unset($arrFiles[$scope][$index]);
- }
- }
- }
- }
- return $arrFiles;
- }
- /**
- * Compile classes code to files
- *
- * @return Mage_Compiler_Model_Process
- */
- protected function _compileFiles()
- {
- $classesInfo = $this->getCompileClassList();
- foreach ($classesInfo as $code => $classes) {
- $classesSorce = $this->_getClassesSourceCode($classes, $code);
- file_put_contents($this->_includeDir.DS.Varien_Autoload::SCOPE_FILE_PREFIX.$code.'.php', $classesSorce);
- }
- return $this;
- }
- protected function _getClassesSourceCode($classes, $scope)
- {
- $sortedClasses = array();
- foreach ($classes as $className) {
- $implements = array_reverse(class_implements($className));
- foreach ($implements as $class) {
- if (!in_array($class, $sortedClasses) && !in_array($class, $this->_processedClasses) && strstr($class, '_')) {
- $sortedClasses[] = $class;
- if ($scope == 'default') {
- $this->_processedClasses[] = $class;
- }
- }
- }
- $extends = array_reverse(class_parents($className));
- foreach ($extends as $class) {
- if (!in_array($class, $sortedClasses) && !in_array($class, $this->_processedClasses) && strstr($class, '_')) {
- $sortedClasses[] = $class;
- if ($scope == 'default') {
- $this->_processedClasses[] = $class;
- }
- }
- }
- if (!in_array($className, $sortedClasses) && !in_array($className, $this->_processedClasses)) {
- $sortedClasses[] = $className;
- if ($scope == 'default') {
- $this->_processedClasses[] = $className;
- }
- }
- }
- $classesSource = "<?php\n";
- foreach ($sortedClasses as $className) {
- $file = $this->_includeDir.DS.$className.'.php';
- if (!file_exists($file)) {
- continue;
- }
- $content = file_get_contents($file);
- $content = ltrim($content, '<?php');
- $content = rtrim($content, "\n\r\t?>");
- $classesSource.= $content;
- }
- return $classesSource;
- }
- public function clear()
- {
- $this->registerIncludePath(false);
- if (is_dir($this->_includeDir)) {
- mageDelTree($this->_includeDir);
- }
- return $this;
- }
- /**
- * Run compilation process
- *
- * @return Mage_Compiler_Model_Process
- */
- public function run()
- {
- $this->_collectFiles();
- $this->_compileFiles();
- $this->registerIncludePath();
- return $this;
- }
- /**
- * Enable or disable include path constant definition in compiler config.php
- *
- * @param bool $flag
- * @return Mage_Compiler_Model_Process
- */
- public function registerIncludePath($flag = true)
- {
- $file = $this->_compileDir.DS.'config.php';
- if (is_writeable($file)) {
- $content = file_get_contents($file);
- $content = explode("\n", $content);
- foreach ($content as $index => $line) {
- if (strpos($line, 'COMPILER_INCLUDE_PATH')) {
- if ($flag) {
- $content[$index] = ltrim($line, '#');
- } else {
- $content[$index] = '#'.$line;
- }
- }
- }
- file_put_contents($file, implode("\n", $content));
- }
- return $this;
- }
- /**
- * Validate if compilation process is allowed
- *
- * @return array
- */
- public function validate()
- {
- $result = array();
- if (!is_writeable($this->_compileDir)) {
- $result[] = Mage::helper('compiler')->__('Directory "%s" must be writeable', $this->_compileDir);
- }
- $file = $this->_compileDir.DS.'config.php';
- if (!is_writeable($file)) {
- $result[] = Mage::helper('compiler')->__('File "%s" must be writeable', $file);
- }
- return $result;
- }
- }