/bitrix/modules/main/lib/loader.php
PHP | 382 lines | 278 code | 46 blank | 58 comment | 44 complexity | dc4810648db1c2a13921abb746d510ad MD5 | raw file
Possible License(s): Apache-2.0
- <?php
- namespace Bitrix\Main;
- /**
- * Class Loader loads required files, classes and modules. It is the only class which is included directly.
- * @package Bitrix\Main
- */
- final class Loader
- {
- /**
- * Can be used to prevent loading all modules except main and fileman
- */
- const SAFE_MODE = false;
- const BITRIX_HOLDER = "bitrix";
- const LOCAL_HOLDER = "local";
- private static $safeModeModules = array("main", "fileman");
- private static $arLoadedModules = array("main" => true);
- private static $arSemiloadedModules = array();
- private static $arLoadedModulesHolders = array("main" => self::BITRIX_HOLDER);
- private static $arSharewareModules = array();
- /**
- * Returned by includeSharewareModule() if module is not found
- */
- const MODULE_NOT_FOUND = 0;
- /**
- * Returned by includeSharewareModule() if module is installed
- */
- const MODULE_INSTALLED = 1;
- /**
- * Returned by includeSharewareModule() if module works in demo mode
- */
- const MODULE_DEMO = 2;
- /**
- * Returned by includeSharewareModule() if the trial period is expired
- */
- const MODULE_DEMO_EXPIRED = 3;
- private static $arAutoLoadClasses = array();
- private static $isAutoLoadOn = true;
- const ALPHA_LOWER = "qwertyuioplkjhgfdsazxcvbnm";
- const ALPHA_UPPER = "QWERTYUIOPLKJHGFDSAZXCVBNM";
- /**
- * Includes module by its name
- *
- * @param string $moduleName Name of the included module
- * @return bool Returns true if module was included successfully, otherwise returns false
- * @throws LoaderException
- */
- public static function includeModule($moduleName)
- {
- if (!is_string($moduleName) || $moduleName == "")
- throw new LoaderException("Empty module name");
- if (preg_match("#[^a-zA-Z0-9._]#", $moduleName))
- throw new LoaderException(sprintf("Module name '%s' is not correct", $moduleName));
- $moduleName = strtr($moduleName, static::ALPHA_UPPER, static::ALPHA_LOWER);
- if (self::SAFE_MODE)
- {
- if (!in_array($moduleName, self::$safeModeModules))
- return false;
- }
- if (isset(self::$arLoadedModules[$moduleName]))
- return self::$arLoadedModules[$moduleName];
- if (isset(self::$arSemiloadedModules[$moduleName]))
- trigger_error("Module '".$moduleName."' is in loading progress", E_USER_WARNING);
- $arInstalledModules = ModuleManager::getInstalledModules();
- if (!isset($arInstalledModules[$moduleName]))
- return self::$arLoadedModules[$moduleName] = false;
- $documentRoot = static::getDocumentRoot();
- $moduleHolder = self::LOCAL_HOLDER;
- $pathToInclude = $documentRoot."/".$moduleHolder."/modules/".$moduleName."/include.php";
- if (!file_exists($pathToInclude))
- {
- $moduleHolder = self::BITRIX_HOLDER;
- $pathToInclude = $documentRoot."/".$moduleHolder."/modules/".$moduleName."/include.php";
- if (!file_exists($pathToInclude))
- return self::$arLoadedModules[$moduleName] = false;
- }
- self::$arLoadedModulesHolders[$moduleName] = $moduleHolder;
- self::$arSemiloadedModules[$moduleName] = true;
- $res = self::includeModuleInternal($pathToInclude);
- unset(self::$arSemiloadedModules[$moduleName]);
- if ($res === false)
- return self::$arLoadedModules[$moduleName] = false;
- return self::$arLoadedModules[$moduleName] = true;
- }
- private static function includeModuleInternal($path)
- {
- /** @noinspection PhpUnusedLocalVariableInspection */
- global $DB, $MESS;
- return include_once($path);
- }
- /**
- * Includes shareware module by its name.
- * Module must initialize constant <module name>_DEMO = Y in include.php to define demo mode.
- * include.php must return false to define trial period expiration.
- * Constants is used because it is easy to obfuscate them.
- *
- * @param string $moduleName Name of the included module
- * @return int One of the following constant: Loader::MODULE_NOT_FOUND, Loader::MODULE_INSTALLED, Loader::MODULE_DEMO, Loader::MODULE_DEMO_EXPIRED
- */
- public static function includeSharewareModule($moduleName)
- {
- if (isset(self::$arSharewareModules[$moduleName]))
- return self::$arSharewareModules[$moduleName];
- $moduleNameTmp = str_replace(".", "_", $moduleName);
- if (self::includeModule($moduleName))
- {
- if (defined($moduleNameTmp."_DEMO") && constant($moduleNameTmp."_DEMO") == "Y")
- self::$arSharewareModules[$moduleName] = self::MODULE_DEMO;
- else
- self::$arSharewareModules[$moduleName] = self::MODULE_INSTALLED;
- return self::$arSharewareModules[$moduleName];
- }
- if (defined($moduleNameTmp."_DEMO") && constant($moduleNameTmp."_DEMO") == "Y")
- return self::$arSharewareModules[$moduleName] = self::MODULE_DEMO_EXPIRED;
- return self::$arSharewareModules[$moduleName] = self::MODULE_NOT_FOUND;
- }
- public static function clearModuleCache($moduleName)
- {
- if (!is_string($moduleName) || $moduleName == "")
- throw new LoaderException("Empty module name");
- if($moduleName !== "main")
- {
- unset(static::$arLoadedModules[$moduleName]);
- unset(static::$arLoadedModulesHolders[$moduleName]);
- }
- if (isset(static::$arSharewareModules[$moduleName]))
- unset(static::$arSharewareModules[$moduleName]);
- }
- /**
- * Returns document root
- *
- * @return string Document root
- */
- public static function getDocumentRoot()
- {
- static $documentRoot = null;
- if ($documentRoot === null)
- $documentRoot = rtrim($_SERVER["DOCUMENT_ROOT"], "/\\");
- return $documentRoot;
- }
- public static function switchAutoLoad($value = true)
- {
- static::$isAutoLoadOn = $value;
- }
- /**
- * Registers classes for auto loading.
- * All the frequently used classes should be registered for auto loading (performance).
- * It is not necessary to register rarely used classes. They can be found and loaded dynamically.
- *
- * @param string $moduleName Name of the module. Can be null if classes are not part of any module
- * @param array $arClasses Array of classes with class names as keys and paths as values.
- * @throws LoaderException
- */
- public static function registerAutoLoadClasses($moduleName, array $arClasses)
- {
- if (empty($arClasses))
- return;
- if (($moduleName !== null) && empty($moduleName))
- {
- throw new LoaderException(sprintf("Module name '%s' is not correct", $moduleName));
- }
- if (!static::$isAutoLoadOn)
- {
- if (!is_null($moduleName) && !isset(static::$arLoadedModulesHolders[$moduleName]))
- throw new LoaderException(sprintf("Holder of module '%s' is not found", $moduleName));
- $documentRoot = static::getDocumentRoot();
- if (!is_null($moduleName))
- {
- foreach ($arClasses as $value)
- {
- if (file_exists($documentRoot."/".self::$arLoadedModulesHolders[$moduleName]."/modules/".$moduleName."/".$value))
- require_once($documentRoot."/".self::$arLoadedModulesHolders[$moduleName]."/modules/".$moduleName."/".$value);
- }
- }
- else
- {
- foreach ($arClasses as $value)
- {
- if (($includePath = self::getLocal($value, $documentRoot)) !== false)
- require_once($includePath);
- }
- }
- }
- else
- {
- foreach ($arClasses as $key => $value)
- {
- $class = ltrim($key, "\\");
- self::$arAutoLoadClasses[strtr($class, static::ALPHA_UPPER, static::ALPHA_LOWER)] = array(
- "module" => $moduleName,
- "file" => $value
- );
- }
- }
- }
- public static function isAutoLoadClassRegistered($className)
- {
- $className = trim(ltrim($className, "\\"));
- if ($className == '')
- return false;
- $className = strtr($className, static::ALPHA_UPPER, static::ALPHA_LOWER);
- return isset(self::$arAutoLoadClasses[$className]);
- }
- /**
- * \Bitrix\Main\IO\File -> /main/lib/io/file.php
- * \Bitrix\IBlock\Type -> /iblock/lib/type.php
- * \Bitrix\IBlock\Section\Type -> /iblock/lib/section/type.php
- * \QSoft\Catalog\Tools\File -> /qsoft.catalog/lib/tools/file.php
- *
- * @param $className
- */
- public static function autoLoad($className)
- {
- $file = ltrim($className, "\\"); // fix web env
- $file = strtr($file, static::ALPHA_UPPER, static::ALPHA_LOWER);
- static $documentRoot = null;
- if ($documentRoot === null)
- $documentRoot = static::getDocumentRoot();
- if (isset(self::$arAutoLoadClasses[$file]))
- {
- $pathInfo = self::$arAutoLoadClasses[$file];
- if ($pathInfo["module"] != "")
- {
- $m = $pathInfo["module"];
- $h = isset(self::$arLoadedModulesHolders[$m]) ? self::$arLoadedModulesHolders[$m] : 'bitrix';
- include_once($documentRoot."/".$h."/modules/".$m."/" .$pathInfo["file"]);
- }
- else
- {
- require_once($documentRoot.$pathInfo["file"]);
- }
- return;
- }
- if (preg_match("#[^\\\\/a-zA-Z0-9_]#", $file))
- return;
- if (substr($file, -5) == "table")
- $file = substr($file, 0, -5);
- $file = str_replace('\\', '/', $file);
- $arFile = explode("/", $file);
- if ($arFile[0] === "bitrix")
- {
- array_shift($arFile);
- if (empty($arFile))
- return;
- $module = array_shift($arFile);
- if ($module == null || empty($arFile))
- return;
- }
- else
- {
- $module1 = array_shift($arFile);
- $module2 = array_shift($arFile);
- if ($module1 == null || $module2 == null || empty($arFile))
- return;
- $module = $module1.".".$module2;
- }
- if (!isset(self::$arLoadedModulesHolders[$module]))
- return;
- $filePath = $documentRoot."/".self::$arLoadedModulesHolders[$module]."/modules/".$module."/lib/".implode("/", $arFile).".php";
- if (file_exists($filePath))
- require_once($filePath);
- }
- /**
- * Checks if file exists in /local or /bitrix directories
- *
- * @param string $path File path relative to /local/ or /bitrix/
- * @param string $root Server document root, default static::getDocumentRoot()
- * @return string|bool Returns combined path or false if the file does not exist in both dirs
- */
- public static function getLocal($path, $root = null)
- {
- if ($root === null)
- $root = static::getDocumentRoot();
- if (file_exists($root."/local/".$path))
- return $root."/local/".$path;
- elseif (file_exists($root."/bitrix/".$path))
- return $root."/bitrix/".$path;
- else
- return false;
- }
- /**
- * Checks if file exists in personal directory.
- * If $_SERVER["BX_PERSONAL_ROOT"] is not set than personal directory is equal to /bitrix/
- *
- * @param string $path File path relative to personal directory
- * @return string|bool Returns combined path or false if the file does not exist
- */
- public static function getPersonal($path)
- {
- $root = static::getDocumentRoot();
- $personal = isset($_SERVER["BX_PERSONAL_ROOT"]) ? $_SERVER["BX_PERSONAL_ROOT"] : "";
- if (!empty($personal) && file_exists($root.$personal."/".$path))
- return $root.$personal."/".$path;
- return self::getLocal($path, $root);
- }
- }
- class LoaderException extends \Exception
- {
- public function __construct($message = "", $code = 0, \Exception $previous = null)
- {
- parent::__construct($message, $code, $previous);
- }
- }
- if (!function_exists("__autoload"))
- {
- if (function_exists('spl_autoload_register'))
- {
- \spl_autoload_register('\Bitrix\Main\Loader::autoLoad');
- }
- else
- {
- function __autoload($className)
- {
- Loader::autoLoad($className);
- }
- }
- Loader::switchAutoLoad(true);
- }
- else
- {
- Loader::switchAutoLoad(false);
- }