00001 <?php 00024 require_once 'Zend/Loader/PluginLoader/Interface.php'; 00025 00027 require_once 'Zend/Loader.php'; 00028 00038 class Zend_Loader_PluginLoader implements Zend_Loader_PluginLoader_Interface 00039 { 00044 protected static $_includeFileCache; 00045 00051 protected $_loadedPluginPaths = array(); 00052 00058 protected $_loadedPlugins = array(); 00059 00065 protected $_prefixToPaths = array(); 00066 00072 protected static $_staticLoadedPluginPaths = array(); 00073 00079 protected static $_staticLoadedPlugins = array(); 00080 00086 protected static $_staticPrefixToPaths = array(); 00087 00093 protected $_useStaticRegistry = null; 00094 00101 public function __construct(Array $prefixToPaths = array(), $staticRegistryName = null) 00102 { 00103 if (is_string($staticRegistryName) && !empty($staticRegistryName)) { 00104 $this->_useStaticRegistry = $staticRegistryName; 00105 if(!isset(self::$_staticPrefixToPaths[$staticRegistryName])) { 00106 self::$_staticPrefixToPaths[$staticRegistryName] = array(); 00107 } 00108 if(!isset(self::$_staticLoadedPlugins[$staticRegistryName])) { 00109 self::$_staticLoadedPlugins[$staticRegistryName] = array(); 00110 } 00111 } 00112 00113 foreach ($prefixToPaths as $prefix => $path) { 00114 $this->addPrefixPath($prefix, $path); 00115 } 00116 } 00117 00124 protected function _formatPrefix($prefix) 00125 { 00126 if($prefix == "") { 00127 return $prefix; 00128 } 00129 return rtrim($prefix, '_') . '_'; 00130 } 00131 00139 public function addPrefixPath($prefix, $path) 00140 { 00141 if (!is_string($prefix) || !is_string($path)) { 00142 require_once 'Zend/Loader/PluginLoader/Exception.php'; 00143 throw new Zend_Loader_PluginLoader_Exception('Zend_Loader_PluginLoader::addPrefixPath() method only takes strings for prefix and path.'); 00144 } 00145 00146 $prefix = $this->_formatPrefix($prefix); 00147 $path = rtrim($path, '/\\') . '/'; 00148 00149 if ($this->_useStaticRegistry) { 00150 self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix][] = $path; 00151 } else { 00152 if (!isset($this->_prefixToPaths[$prefix])) { 00153 $this->_prefixToPaths[$prefix] = array(); 00154 } 00155 if (!in_array($path, $this->_prefixToPaths[$prefix])) { 00156 $this->_prefixToPaths[$prefix][] = $path; 00157 } 00158 } 00159 return $this; 00160 } 00161 00168 public function getPaths($prefix = null) 00169 { 00170 if ((null !== $prefix) && is_string($prefix)) { 00171 $prefix = $this->_formatPrefix($prefix); 00172 if ($this->_useStaticRegistry) { 00173 if (isset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix])) { 00174 return self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix]; 00175 } 00176 00177 return false; 00178 } 00179 00180 if (isset($this->_prefixToPaths[$prefix])) { 00181 return $this->_prefixToPaths[$prefix]; 00182 } 00183 00184 return false; 00185 } 00186 00187 if ($this->_useStaticRegistry) { 00188 return self::$_staticPrefixToPaths[$this->_useStaticRegistry]; 00189 } 00190 00191 return $this->_prefixToPaths; 00192 } 00193 00200 public function clearPaths($prefix = null) 00201 { 00202 if ((null !== $prefix) && is_string($prefix)) { 00203 $prefix = $this->_formatPrefix($prefix); 00204 if ($this->_useStaticRegistry) { 00205 if (isset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix])) { 00206 unset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix]); 00207 return true; 00208 } 00209 00210 return false; 00211 } 00212 00213 if (isset($this->_prefixToPaths[$prefix])) { 00214 unset($this->_prefixToPaths[$prefix]); 00215 return true; 00216 } 00217 00218 return false; 00219 } 00220 00221 if ($this->_useStaticRegistry) { 00222 self::$_staticPrefixToPaths[$this->_useStaticRegistry] = array(); 00223 } else { 00224 $this->_prefixToPaths = array(); 00225 } 00226 00227 return true; 00228 } 00229 00237 public function removePrefixPath($prefix, $path = null) 00238 { 00239 $prefix = $this->_formatPrefix($prefix); 00240 if ($this->_useStaticRegistry) { 00241 $registry =& self::$_staticPrefixToPaths[$this->_useStaticRegistry]; 00242 } else { 00243 $registry =& $this->_prefixToPaths; 00244 } 00245 00246 if (!isset($registry[$prefix])) { 00247 require_once 'Zend/Loader/PluginLoader/Exception.php'; 00248 throw new Zend_Loader_PluginLoader_Exception('Prefix ' . $prefix . ' was not found in the PluginLoader.'); 00249 } 00250 00251 if ($path != null) { 00252 $pos = array_search($path, $registry[$prefix]); 00253 if ($pos === null) { 00254 require_once 'Zend/Loader/PluginLoader/Exception.php'; 00255 throw new Zend_Loader_PluginLoader_Exception('Prefix ' . $prefix . ' / Path ' . $path . ' was not found in the PluginLoader.'); 00256 } 00257 unset($registry[$prefix][$pos]); 00258 } else { 00259 unset($registry[$prefix]); 00260 } 00261 00262 return $this; 00263 } 00264 00271 protected function _formatName($name) 00272 { 00273 return ucfirst((string) $name); 00274 } 00275 00282 public function isLoaded($name) 00283 { 00284 $name = $this->_formatName($name); 00285 if ($this->_useStaticRegistry) { 00286 return isset(self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name]); 00287 } 00288 00289 return isset($this->_loadedPlugins[$name]); 00290 } 00291 00298 public function getClassName($name) 00299 { 00300 $name = $this->_formatName($name); 00301 if ($this->_useStaticRegistry 00302 && isset(self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name]) 00303 ) { 00304 return self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name]; 00305 } elseif (isset($this->_loadedPlugins[$name])) { 00306 return $this->_loadedPlugins[$name]; 00307 } 00308 00309 return false; 00310 } 00311 00318 public function getClassPath($name) 00319 { 00320 $name = $this->_formatName($name); 00321 if ($this->_useStaticRegistry 00322 && !empty(self::$_staticLoadedPluginPaths[$this->_useStaticRegistry][$name]) 00323 ) { 00324 return self::$_staticLoadedPluginPaths[$this->_useStaticRegistry][$name]; 00325 } elseif (!empty($this->_loadedPluginPaths[$name])) { 00326 return $this->_loadedPluginPaths[$name]; 00327 } 00328 00329 if ($this->isLoaded($name)) { 00330 $class = $this->getClassName($name); 00331 $r = new ReflectionClass($class); 00332 $path = $r->getFileName(); 00333 if ($this->_useStaticRegistry) { 00334 self::$_staticLoadedPluginPaths[$this->_useStaticRegistry][$name] = $path; 00335 } else { 00336 $this->_loadedPluginPaths[$name] = $path; 00337 } 00338 return $path; 00339 } 00340 00341 return false; 00342 } 00343 00354 public function load($name, $throwExceptions = true) 00355 { 00356 $name = $this->_formatName($name); 00357 if ($this->isLoaded($name)) { 00358 return $this->getClassName($name); 00359 } 00360 00361 if ($this->_useStaticRegistry) { 00362 $registry = self::$_staticPrefixToPaths[$this->_useStaticRegistry]; 00363 } else { 00364 $registry = $this->_prefixToPaths; 00365 } 00366 00367 $registry = array_reverse($registry, true); 00368 $found = false; 00369 $classFile = str_replace('_', DIRECTORY_SEPARATOR, $name) . '.php'; 00370 $incFile = self::getIncludeFileCache(); 00371 foreach ($registry as $prefix => $paths) { 00372 $className = $prefix . $name; 00373 00374 if (class_exists($className, false)) { 00375 $found = true; 00376 break; 00377 } 00378 00379 $paths = array_reverse($paths, true); 00380 00381 foreach ($paths as $path) { 00382 $loadFile = $path . $classFile; 00383 if (Zend_Loader::isReadable($loadFile)) { 00384 include_once $loadFile; 00385 if (class_exists($className, false)) { 00386 if (null !== $incFile) { 00387 self::_appendIncFile($loadFile); 00388 } 00389 $found = true; 00390 break 2; 00391 } 00392 } 00393 } 00394 } 00395 00396 if (!$found) { 00397 if (!$throwExceptions) { 00398 return false; 00399 } 00400 00401 $message = "Plugin by name '$name' was not found in the registry; used paths:"; 00402 foreach ($registry as $prefix => $paths) { 00403 $message .= "\n$prefix: " . implode(PATH_SEPARATOR, $paths); 00404 } 00405 require_once 'Zend/Loader/PluginLoader/Exception.php'; 00406 throw new Zend_Loader_PluginLoader_Exception($message); 00407 } 00408 00409 if ($this->_useStaticRegistry) { 00410 self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name] = $className; 00411 self::$_staticLoadedPluginPaths[$this->_useStaticRegistry][$name] = (isset($loadFile) ? $loadFile : ''); 00412 } else { 00413 $this->_loadedPlugins[$name] = $className; 00414 $this->_loadedPluginPaths[$name] = (isset($loadFile) ? $loadFile : ''); 00415 } 00416 return $className; 00417 } 00418 00429 public static function setIncludeFileCache($file) 00430 { 00431 if (null === $file) { 00432 self::$_includeFileCache = null; 00433 return; 00434 } 00435 00436 if (!file_exists($file) && !file_exists(dirname($file))) { 00437 require_once 'Zend/Loader/PluginLoader/Exception.php'; 00438 throw new Zend_Loader_PluginLoader_Exception('Specified file does not exist and/or directory does not exist (' . $file . ')'); 00439 } 00440 if (file_exists($file) && !is_writable($file)) { 00441 require_once 'Zend/Loader/PluginLoader/Exception.php'; 00442 throw new Zend_Loader_PluginLoader_Exception('Specified file is not writeable (' . $file . ')'); 00443 } 00444 if (!file_exists($file) && file_exists(dirname($file)) && !is_writable(dirname($file))) { 00445 require_once 'Zend/Loader/PluginLoader/Exception.php'; 00446 throw new Zend_Loader_PluginLoader_Exception('Specified file is not writeable (' . $file . ')'); 00447 } 00448 00449 self::$_includeFileCache = $file; 00450 } 00451 00457 public static function getIncludeFileCache() 00458 { 00459 return self::$_includeFileCache; 00460 } 00461 00468 protected static function _appendIncFile($incFile) 00469 { 00470 if (!file_exists(self::$_includeFileCache)) { 00471 $file = '<?php'; 00472 } else { 00473 $file = file_get_contents(self::$_includeFileCache); 00474 } 00475 if (!strstr($file, $incFile)) { 00476 $file .= "\ninclude_once '$incFile';"; 00477 file_put_contents(self::$_includeFileCache, $file); 00478 } 00479 } 00480 }