<?php /*+********************************************************************************** * The contents of this file are subject to the vtiger CRM Public License Version 1.1 * ("License"); You may not use this file except in compliance with the License * The Original Code is: vtiger CRM Open Source * The Initial Developer of the Original Code is vtiger. * Portions created by vtiger are Copyright (C) vtiger. * All Rights Reserved. ************************************************************************************/ global $LOADER_FILE_DIR; $LOADER_FILE_DIR = dirname(__FILE__); class Vtiger_Loader { protected static $includeCache = array(); protected static $includePathCache = array(); /** * Static function to resolve the qualified php filename to absolute path * @global <String> $LOADER_FILE_DIR * @param <String> $qualifiedName * @return <String> Absolute File Name */ static function resolveNameToPath($qualifiedName, $fileExtension='php') { global $LOADER_FILE_DIR; $allowedExtensions = array('php', 'js', 'css', 'less'); $file = ''; if(!in_array($fileExtension, $allowedExtensions)) { return ''; } // TO handle loading vtiger files if (strpos($qualifiedName, '~~') === 0) { $file = str_replace('~~', '', $qualifiedName); $file = $LOADER_FILE_DIR . DIRECTORY_SEPARATOR .'..' . DIRECTORY_SEPARATOR . $file; } else if (strpos($qualifiedName, '~') === 0) { $file = str_replace('~', '', $qualifiedName); $file = $LOADER_FILE_DIR . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . $file; } else { $file = str_replace('.', DIRECTORY_SEPARATOR, $qualifiedName) . '.' .$fileExtension; $file = $LOADER_FILE_DIR . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . $file; } return $file; } /** * Function to include a given php file through qualified file name * @param <String> $qualifiedName * @param <Boolean> $supressWarning * @return <Boolean> */ static function includeOnce($qualifiedName, $supressWarning=false) { if (isset(self::$includeCache[$qualifiedName])) { return true; } $file = self::resolveNameToPath($qualifiedName); if (!file_exists($file)) { return false; } // Check file inclusion before including it checkFileAccessForInclusion($file); $status = -1; if ($supressWarning) { $status = @include_once $file; } else { $status = include_once $file; } $success = ($status === 0)? false : true; if ($success) { self::$includeCache[$qualifiedName] = $file; } return $success; } static function includePath($qualifiedName) { // Already included? if (isset(self::$includePathCache[$qualifiedName])) { return true; } $path = realpath(self::resolveNameToPath($qualifiedName)); self::$includePathCache[$qualifiedName] = $path; // TODO Check if resolvedPath is already part of include path. set_include_path($path . PATH_SEPARATOR . get_include_path()); return true; } /** * Function to get the class name of a given Component, of given Type, for a given Module * @param <String> $componentType * @param <String> $componentName * @param <String> $moduleName * @return <String> Required Class Name * @throws AppException */ public static function getComponentClassName($componentType, $componentName, $moduleName='Vtiger') { // Change component type from view to views, action to actions to navigate to the right path. $componentTypeDirectory = strtolower($componentType).'s'; // Fall Back Directory & Fall Back Class $fallBackModuleDir = $fallBackModuleClassPath = 'Vtiger'; // Intermediate Fall Back Directories & Classes, before relying on final fall back $firstFallBackModuleDir = $firstFallBackModuleClassPath = ''; $secondFallBackDir = $secondFallBackClassPath = ''; // Default module directory & class name $moduleDir = $moduleClassPath = $moduleName; // Change the Module directory & class, along with intermediate fall back directory and class, if module names has submodule as well if(strpos($moduleName, ':') > 0) { $moduleHierarchyParts = explode(':', $moduleName); $moduleDir = str_replace(':', '.', $moduleName); $moduleClassPath = str_replace(':', '_', $moduleName); $actualModule = $moduleHierarchyParts[count($moduleHierarchyParts)-1]; $secondFallBackModuleDir= $secondFallBackModuleClassPath = $actualModule; $modules = array('Users'); if($actualModule != 'Users') { $baseModule = $moduleHierarchyParts[0]; if($baseModule == 'Settings') $baseModule = 'Settings:Vtiger'; $firstFallBackDir = str_replace(':', '.', $baseModule); $firstFallBackClassPath = str_replace(':', '_', $baseModule); } } // Build module specific file path and class name $moduleSpecificComponentFilePath = Vtiger_Loader::resolveNameToPath('modules.'.$moduleDir.'.'.$componentTypeDirectory.'.'.$componentName); $moduleSpecificComponentClassName = $moduleClassPath.'_'.$componentName.'_'.$componentType; if(file_exists($moduleSpecificComponentFilePath)) { return $moduleSpecificComponentClassName; } // Build first intermediate fall back file path and class name if(!empty($firstFallBackDir) && !empty($firstFallBackClassPath)) { $fallBackComponentFilePath = Vtiger_Loader::resolveNameToPath('modules.'.$firstFallBackDir.'.'.$componentTypeDirectory.'.'.$componentName); $fallBackComponentClassName = $firstFallBackClassPath.'_'.$componentName.'_'.$componentType; if(file_exists($fallBackComponentFilePath)) { return $fallBackComponentClassName; } } // Build intermediate fall back file path and class name if(!empty($secondFallBackModuleDir) && !empty($secondFallBackModuleClassPath)) { $fallBackComponentFilePath = Vtiger_Loader::resolveNameToPath('modules.'.$secondFallBackModuleDir.'.'.$componentTypeDirectory.'.'.$componentName); $fallBackComponentClassName = $secondFallBackModuleClassPath.'_'.$componentName.'_'.$componentType; if(file_exists($fallBackComponentFilePath)) { return $fallBackComponentClassName; } } // Build fall back file path and class name $fallBackComponentFilePath = Vtiger_Loader::resolveNameToPath('modules.'.$fallBackModuleDir.'.'.$componentTypeDirectory.'.'.$componentName); $fallBackComponentClassName = $fallBackModuleClassPath.'_'.$componentName.'_'.$componentType; if(file_exists($fallBackComponentFilePath)) { return $fallBackComponentClassName; } throw new AppException('Handler not found.'); } /** * Function to auto load the required class files matching the directory pattern modules/xyz/types/Abc.php for class xyz_Abc_Type * @param <String> $className * @return <Boolean> */ public static function autoLoad($className) { $parts = explode('_', $className); $noOfParts = count($parts); if($noOfParts > 2) { $filePath = 'modules.'; // Append modules and sub modules names to the path for($i=0; $i<($noOfParts-2); ++$i) { $filePath .= $parts[$i]. '.'; } $fileName = $parts[$noOfParts-2]; $fileComponentName = strtolower($parts[$noOfParts-1]).'s'; $filePath .= $fileComponentName. '.' .$fileName; return Vtiger_Loader::includeOnce($filePath); } return false; } } function vimport($qualifiedName) { return Vtiger_Loader::includeOnce($qualifiedName); } function vimport_try($qualifiedName) { return Vtiger_Loader::includeOnce($qualifiedName, true); } function vimport_path($qualifiedName) { return Vtiger_Loader::includePath($qualifiedName); } spl_autoload_register('Vtiger_Loader::autoLoad');