File indexing completed on 2025-02-23 05:32:30
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Loader 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 */ 0020 0021 // Grab SplAutoloader interface 0022 // require_once dirname(__FILE__) . '/SplAutoloader.php'; 0023 0024 /** 0025 * Class-map autoloader 0026 * 0027 * Utilizes class-map files to lookup classfile locations. 0028 * 0029 * @package Zend_Loader 0030 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0031 * @license New BSD {@link http://framework.zend.com/license/new-bsd} 0032 */ 0033 class Zend_Loader_ClassMapAutoloader implements Zend_Loader_SplAutoloader 0034 { 0035 /** 0036 * Registry of map files that have already been loaded 0037 * @var array 0038 */ 0039 protected $mapsLoaded = array(); 0040 0041 /** 0042 * Class name/filename map 0043 * @var array 0044 */ 0045 protected $map = array(); 0046 0047 /** 0048 * Constructor 0049 * 0050 * Create a new instance, and optionally configure the autoloader. 0051 * 0052 * @param null|array|Traversable $options 0053 * @return void 0054 */ 0055 public function __construct($options = null) 0056 { 0057 if (null !== $options) { 0058 $this->setOptions($options); 0059 } 0060 } 0061 0062 /** 0063 * Configure the autoloader 0064 * 0065 * Proxies to {@link registerAutoloadMaps()}. 0066 * 0067 * @param array|Traversable $options 0068 * @return Zend_Loader_ClassMapAutoloader 0069 */ 0070 public function setOptions($options) 0071 { 0072 $this->registerAutoloadMaps($options); 0073 return $this; 0074 } 0075 0076 /** 0077 * Register an autoload map 0078 * 0079 * An autoload map may be either an associative array, or a file returning 0080 * an associative array. 0081 * 0082 * An autoload map should be an associative array containing 0083 * classname/file pairs. 0084 * 0085 * @param string|array $location 0086 * @return Zend_Loader_ClassMapAutoloader 0087 */ 0088 public function registerAutoloadMap($map) 0089 { 0090 if (is_string($map)) { 0091 $location = $map; 0092 if ($this === ($map = $this->loadMapFromFile($location))) { 0093 return $this; 0094 } 0095 } 0096 0097 if (!is_array($map)) { 0098 // require_once dirname(__FILE__) . '/Exception/InvalidArgumentException.php'; 0099 throw new Zend_Loader_Exception_InvalidArgumentException('Map file provided does not return a map'); 0100 } 0101 0102 $this->map = array_merge($this->map, $map); 0103 0104 if (isset($location)) { 0105 $this->mapsLoaded[] = $location; 0106 } 0107 0108 return $this; 0109 } 0110 0111 /** 0112 * Register many autoload maps at once 0113 * 0114 * @param array $locations 0115 * @return Zend_Loader_ClassMapAutoloader 0116 */ 0117 public function registerAutoloadMaps($locations) 0118 { 0119 if (!is_array($locations) && !($locations instanceof Traversable)) { 0120 // require_once dirname(__FILE__) . '/Exception/InvalidArgumentException.php'; 0121 throw new Zend_Loader_Exception_InvalidArgumentException('Map list must be an array or implement Traversable'); 0122 } 0123 foreach ($locations as $location) { 0124 $this->registerAutoloadMap($location); 0125 } 0126 return $this; 0127 } 0128 0129 /** 0130 * Retrieve current autoload map 0131 * 0132 * @return array 0133 */ 0134 public function getAutoloadMap() 0135 { 0136 return $this->map; 0137 } 0138 0139 /** 0140 * Defined by Autoloadable 0141 * 0142 * @param string $class 0143 * @return void 0144 */ 0145 public function autoload($class) 0146 { 0147 if (isset($this->map[$class])) { 0148 // require_once $this->map[$class]; 0149 } 0150 } 0151 0152 /** 0153 * Register the autoloader with spl_autoload registry 0154 * 0155 * @return void 0156 */ 0157 public function register() 0158 { 0159 if (version_compare(PHP_VERSION, '5.3.0', '>=')) { 0160 spl_autoload_register(array($this, 'autoload'), true, true); 0161 } else { 0162 spl_autoload_register(array($this, 'autoload'), true); 0163 } 0164 } 0165 0166 /** 0167 * Load a map from a file 0168 * 0169 * If the map has been previously loaded, returns the current instance; 0170 * otherwise, returns whatever was returned by calling include() on the 0171 * location. 0172 * 0173 * @param string $location 0174 * @return Zend_Loader_ClassMapAutoloader|mixed 0175 * @throws Zend_Loader_Exception_InvalidArgumentException for nonexistent locations 0176 */ 0177 protected function loadMapFromFile($location) 0178 { 0179 if (!file_exists($location)) { 0180 // require_once dirname(__FILE__) . '/Exception/InvalidArgumentException.php'; 0181 throw new Zend_Loader_Exception_InvalidArgumentException('Map file provided does not exist'); 0182 } 0183 0184 if (!$path = self::realPharPath($location)) { 0185 $path = realpath($location); 0186 } 0187 0188 if (in_array($path, $this->mapsLoaded)) { 0189 // Already loaded this map 0190 return $this; 0191 } 0192 0193 $map = include $path; 0194 0195 return $map; 0196 } 0197 0198 /** 0199 * Resolve the real_path() to a file within a phar. 0200 * 0201 * @see https://bugs.php.net/bug.php?id=52769 0202 * @param string $path 0203 * @return string 0204 */ 0205 public static function realPharPath($path) 0206 { 0207 if (strpos($path, 'phar:///') !== 0) { 0208 return; 0209 } 0210 0211 $parts = explode('/', str_replace(array('/','\\'), '/', substr($path, 8))); 0212 $parts = array_values(array_filter($parts, array(__CLASS__, 'concatPharParts'))); 0213 0214 array_walk($parts, array(__CLASS__, 'resolvePharParentPath'), $parts); 0215 0216 if (file_exists($realPath = 'phar:///' . implode('/', $parts))) { 0217 return $realPath; 0218 } 0219 } 0220 0221 /** 0222 * Helper callback for filtering phar paths 0223 * 0224 * @param string $part 0225 * @return bool 0226 */ 0227 public static function concatPharParts($part) 0228 { 0229 return ($part !== '' && $part !== '.'); 0230 } 0231 0232 /** 0233 * Helper callback to resolve a parent path in a Phar archive 0234 * 0235 * @param string $value 0236 * @param int $key 0237 * @param array $parts 0238 * @return void 0239 */ 0240 public static function resolvePharParentPath($value, $key, &$parts) 0241 { 0242 if ($value !== '...') { 0243 return; 0244 } 0245 unset($parts[$key], $parts[$key-1]); 0246 $parts = array_values($parts); 0247 } 0248 }