Overview

Packages

  • Auth
  • Config
  • Controller
  • Date
  • Db
  • Feed
    • Abstract
    • Writers
  • File
    • Decorator
  • Form
    • Element
  • Image
  • Log
    • Writer
  • Net
    • Exception
    • REST
  • None
  • PHP
  • PHPMailer
  • Session
  • Util
  • Validate
    • Validator
  • Zend
    • Db
      • Adapter
      • Expr
      • Profiler
      • Select
      • Statement
      • Table
    • Loader
      • Autoloader
      • PluginLoader
    • Registry

Classes

  • Zend_Loader_PluginLoader

Interfaces

  • Zend_Loader_PluginLoader_Interface

Exceptions

  • Zend_Loader_PluginLoader_Exception
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * Zend Framework
  4:  *
  5:  * LICENSE
  6:  *
  7:  * This source file is subject to the new BSD license that is bundled
  8:  * with this package in the file LICENSE.txt.
  9:  * It is also available through the world-wide-web at this URL:
 10:  * http://framework.zend.com/license/new-bsd
 11:  * If you did not receive a copy of the license and are unable to
 12:  * obtain it through the world-wide-web, please send an email
 13:  * to license@zend.com so we can send you a copy immediately.
 14:  *
 15:  * @category   Zend
 16:  * @package    Zend_Loader
 17:  * @subpackage PluginLoader
 18:  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 19:  * @license    http://framework.zend.com/license/new-bsd     New BSD License
 20:  * @version    $Id: PluginLoader.php 22603 2010-07-17 00:02:10Z ramon $
 21:  */
 22: 
 23: /** Zend_Loader_PluginLoader_Interface */
 24: require_once 'Zend/Loader/PluginLoader/Interface.php';
 25: 
 26: /** Zend_Loader */
 27: require_once 'Zend/Loader.php';
 28: 
 29: /**
 30:  * Generic plugin class loader
 31:  *
 32:  * @category   Zend
 33:  * @package    Zend_Loader
 34:  * @subpackage PluginLoader
 35:  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
 36:  * @license    http://framework.zend.com/license/new-bsd     New BSD License
 37:  */
 38: class Zend_Loader_PluginLoader implements Zend_Loader_PluginLoader_Interface
 39: {
 40:     /**
 41:      * Class map cache file
 42:      * @var string
 43:      */
 44:     protected static $_includeFileCache;
 45: 
 46:     /**
 47:      * Instance loaded plugin paths
 48:      *
 49:      * @var array
 50:      */
 51:     protected $_loadedPluginPaths = array();
 52: 
 53:     /**
 54:      * Instance loaded plugins
 55:      *
 56:      * @var array
 57:      */
 58:     protected $_loadedPlugins = array();
 59: 
 60:     /**
 61:      * Instance registry property
 62:      *
 63:      * @var array
 64:      */
 65:     protected $_prefixToPaths = array();
 66: 
 67:     /**
 68:      * Statically loaded plugin path mappings
 69:      *
 70:      * @var array
 71:      */
 72:     protected static $_staticLoadedPluginPaths = array();
 73: 
 74:     /**
 75:      * Statically loaded plugins
 76:      *
 77:      * @var array
 78:      */
 79:     protected static $_staticLoadedPlugins = array();
 80: 
 81:     /**
 82:      * Static registry property
 83:      *
 84:      * @var array
 85:      */
 86:     protected static $_staticPrefixToPaths = array();
 87: 
 88:     /**
 89:      * Whether to use a statically named registry for loading plugins
 90:      *
 91:      * @var string|null
 92:      */
 93:     protected $_useStaticRegistry = null;
 94: 
 95:     /**
 96:      * Constructor
 97:      *
 98:      * @param array $prefixToPaths
 99:      * @param string $staticRegistryName OPTIONAL
100:      */
101:     public function __construct(Array $prefixToPaths = array(), $staticRegistryName = null)
102:     {
103:         if (is_string($staticRegistryName) && !empty($staticRegistryName)) {
104:             $this->_useStaticRegistry = $staticRegistryName;
105:             if(!isset(self::$_staticPrefixToPaths[$staticRegistryName])) {
106:                 self::$_staticPrefixToPaths[$staticRegistryName] = array();
107:             }
108:             if(!isset(self::$_staticLoadedPlugins[$staticRegistryName])) {
109:                 self::$_staticLoadedPlugins[$staticRegistryName] = array();
110:             }
111:         }
112: 
113:         foreach ($prefixToPaths as $prefix => $path) {
114:             $this->addPrefixPath($prefix, $path);
115:         }
116:     }
117: 
118:     /**
119:      * Format prefix for internal use
120:      *
121:      * @param  string $prefix
122:      * @return string
123:      */
124:     protected function _formatPrefix($prefix)
125:     {
126:         if($prefix == "") {
127:             return $prefix;
128:         }
129: 
130:         $last = strlen($prefix) - 1;
131:         if ($prefix{$last} == '\\') {
132:             return $prefix;
133:         }
134: 
135:         return rtrim($prefix, '_') . '_';
136:     }
137: 
138:     /**
139:      * Add prefixed paths to the registry of paths
140:      *
141:      * @param string $prefix
142:      * @param string $path
143:      * @return Zend_Loader_PluginLoader
144:      */
145:     public function addPrefixPath($prefix, $path)
146:     {
147:         if (!is_string($prefix) || !is_string($path)) {
148:             require_once 'Zend/Loader/PluginLoader/Exception.php';
149:             throw new Zend_Loader_PluginLoader_Exception('Zend_Loader_PluginLoader::addPrefixPath() method only takes strings for prefix and path.');
150:         }
151: 
152:         $prefix = $this->_formatPrefix($prefix);
153:         $path   = rtrim($path, '/\\') . '/';
154: 
155:         if ($this->_useStaticRegistry) {
156:             self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix][] = $path;
157:         } else {
158:             if (!isset($this->_prefixToPaths[$prefix])) {
159:                 $this->_prefixToPaths[$prefix] = array();
160:             }
161:             if (!in_array($path, $this->_prefixToPaths[$prefix])) {
162:                 $this->_prefixToPaths[$prefix][] = $path;
163:             }
164:         }
165:         return $this;
166:     }
167: 
168:     /**
169:      * Get path stack
170:      *
171:      * @param  string $prefix
172:      * @return false|array False if prefix does not exist, array otherwise
173:      */
174:     public function getPaths($prefix = null)
175:     {
176:         if ((null !== $prefix) && is_string($prefix)) {
177:             $prefix = $this->_formatPrefix($prefix);
178:             if ($this->_useStaticRegistry) {
179:                 if (isset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix])) {
180:                     return self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix];
181:                 }
182: 
183:                 return false;
184:             }
185: 
186:             if (isset($this->_prefixToPaths[$prefix])) {
187:                 return $this->_prefixToPaths[$prefix];
188:             }
189: 
190:             return false;
191:         }
192: 
193:         if ($this->_useStaticRegistry) {
194:             return self::$_staticPrefixToPaths[$this->_useStaticRegistry];
195:         }
196: 
197:         return $this->_prefixToPaths;
198:     }
199: 
200:     /**
201:      * Clear path stack
202:      *
203:      * @param  string $prefix
204:      * @return bool False only if $prefix does not exist
205:      */
206:     public function clearPaths($prefix = null)
207:     {
208:         if ((null !== $prefix) && is_string($prefix)) {
209:             $prefix = $this->_formatPrefix($prefix);
210:             if ($this->_useStaticRegistry) {
211:                 if (isset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix])) {
212:                     unset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix]);
213:                     return true;
214:                 }
215: 
216:                 return false;
217:             }
218: 
219:             if (isset($this->_prefixToPaths[$prefix])) {
220:                 unset($this->_prefixToPaths[$prefix]);
221:                 return true;
222:             }
223: 
224:             return false;
225:         }
226: 
227:         if ($this->_useStaticRegistry) {
228:             self::$_staticPrefixToPaths[$this->_useStaticRegistry] = array();
229:         } else {
230:             $this->_prefixToPaths = array();
231:         }
232: 
233:         return true;
234:     }
235: 
236:     /**
237:      * Remove a prefix (or prefixed-path) from the registry
238:      *
239:      * @param string $prefix
240:      * @param string $path OPTIONAL
241:      * @return Zend_Loader_PluginLoader
242:      */
243:     public function removePrefixPath($prefix, $path = null)
244:     {
245:         $prefix = $this->_formatPrefix($prefix);
246:         if ($this->_useStaticRegistry) {
247:             $registry =& self::$_staticPrefixToPaths[$this->_useStaticRegistry];
248:         } else {
249:             $registry =& $this->_prefixToPaths;
250:         }
251: 
252:         if (!isset($registry[$prefix])) {
253:             require_once 'Zend/Loader/PluginLoader/Exception.php';
254:             throw new Zend_Loader_PluginLoader_Exception('Prefix ' . $prefix . ' was not found in the PluginLoader.');
255:         }
256: 
257:         if ($path != null) {
258:             $pos = array_search($path, $registry[$prefix]);
259:             if (false === $pos) {
260:                 require_once 'Zend/Loader/PluginLoader/Exception.php';
261:                 throw new Zend_Loader_PluginLoader_Exception('Prefix ' . $prefix . ' / Path ' . $path . ' was not found in the PluginLoader.');
262:             }
263:             unset($registry[$prefix][$pos]);
264:         } else {
265:             unset($registry[$prefix]);
266:         }
267: 
268:         return $this;
269:     }
270: 
271:     /**
272:      * Normalize plugin name
273:      *
274:      * @param  string $name
275:      * @return string
276:      */
277:     protected function _formatName($name)
278:     {
279:         return ucfirst((string) $name);
280:     }
281: 
282:     /**
283:      * Whether or not a Plugin by a specific name is loaded
284:      *
285:      * @param string $name
286:      * @return Zend_Loader_PluginLoader
287:      */
288:     public function isLoaded($name)
289:     {
290:         $name = $this->_formatName($name);
291:         if ($this->_useStaticRegistry) {
292:             return isset(self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name]);
293:         }
294: 
295:         return isset($this->_loadedPlugins[$name]);
296:     }
297: 
298:     /**
299:      * Return full class name for a named plugin
300:      *
301:      * @param string $name
302:      * @return string|false False if class not found, class name otherwise
303:      */
304:     public function getClassName($name)
305:     {
306:         $name = $this->_formatName($name);
307:         if ($this->_useStaticRegistry
308:             && isset(self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name])
309:         ) {
310:             return self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name];
311:         } elseif (isset($this->_loadedPlugins[$name])) {
312:             return $this->_loadedPlugins[$name];
313:         }
314: 
315:         return false;
316:     }
317: 
318:     /**
319:      * Get path to plugin class
320:      *
321:      * @param  mixed $name
322:      * @return string|false False if not found
323:      */
324:     public function getClassPath($name)
325:     {
326:         $name = $this->_formatName($name);
327:         if ($this->_useStaticRegistry
328:             && !empty(self::$_staticLoadedPluginPaths[$this->_useStaticRegistry][$name])
329:         ) {
330:             return self::$_staticLoadedPluginPaths[$this->_useStaticRegistry][$name];
331:         } elseif (!empty($this->_loadedPluginPaths[$name])) {
332:             return $this->_loadedPluginPaths[$name];
333:         }
334: 
335:         if ($this->isLoaded($name)) {
336:             $class = $this->getClassName($name);
337:             $r     = new ReflectionClass($class);
338:             $path  = $r->getFileName();
339:             if ($this->_useStaticRegistry) {
340:                 self::$_staticLoadedPluginPaths[$this->_useStaticRegistry][$name] = $path;
341:             } else {
342:                 $this->_loadedPluginPaths[$name] = $path;
343:             }
344:             return $path;
345:         }
346: 
347:         return false;
348:     }
349: 
350:     /**
351:      * Load a plugin via the name provided
352:      *
353:      * @param  string $name
354:      * @param  bool $throwExceptions Whether or not to throw exceptions if the
355:      * class is not resolved
356:      * @return string|false Class name of loaded class; false if $throwExceptions
357:      * if false and no class found
358:      * @throws Zend_Loader_Exception if class not found
359:      */
360:     public function load($name, $throwExceptions = true)
361:     {
362:         $name = $this->_formatName($name);
363:         if ($this->isLoaded($name)) {
364:             return $this->getClassName($name);
365:         }
366: 
367:         if ($this->_useStaticRegistry) {
368:             $registry = self::$_staticPrefixToPaths[$this->_useStaticRegistry];
369:         } else {
370:             $registry = $this->_prefixToPaths;
371:         }
372: 
373:         $registry  = array_reverse($registry, true);
374:         $found     = false;
375:         $classFile = str_replace('_', DIRECTORY_SEPARATOR, $name) . '.php';
376:         $incFile   = self::getIncludeFileCache();
377:         foreach ($registry as $prefix => $paths) {
378:             $className = $prefix . $name;
379: 
380:             if (class_exists($className, false)) {
381:                 $found = true;
382:                 break;
383:             }
384: 
385:             $paths     = array_reverse($paths, true);
386: 
387:             foreach ($paths as $path) {
388:                 $loadFile = $path . $classFile;
389:                 if (Zend_Loader::isReadable($loadFile)) {
390:                     include_once $loadFile;
391:                     if (class_exists($className, false)) {
392:                         if (null !== $incFile) {
393:                             self::_appendIncFile($loadFile);
394:                         }
395:                         $found = true;
396:                         break 2;
397:                     }
398:                 }
399:             }
400:         }
401: 
402:         if (!$found) {
403:             if (!$throwExceptions) {
404:                 return false;
405:             }
406: 
407:             $message = "Plugin by name '$name' was not found in the registry; used paths:";
408:             foreach ($registry as $prefix => $paths) {
409:                 $message .= "\n$prefix: " . implode(PATH_SEPARATOR, $paths);
410:             }
411:             require_once 'Zend/Loader/PluginLoader/Exception.php';
412:             throw new Zend_Loader_PluginLoader_Exception($message);
413:        }
414: 
415:         if ($this->_useStaticRegistry) {
416:             self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name]     = $className;
417:         } else {
418:             $this->_loadedPlugins[$name]     = $className;
419:         }
420:         return $className;
421:     }
422: 
423:     /**
424:      * Set path to class file cache
425:      *
426:      * Specify a path to a file that will add include_once statements for each
427:      * plugin class loaded. This is an opt-in feature for performance purposes.
428:      *
429:      * @param  string $file
430:      * @return void
431:      * @throws Zend_Loader_PluginLoader_Exception if file is not writeable or path does not exist
432:      */
433:     public static function setIncludeFileCache($file)
434:     {
435:         if (null === $file) {
436:             self::$_includeFileCache = null;
437:             return;
438:         }
439: 
440:         if (!file_exists($file) && !file_exists(dirname($file))) {
441:             require_once 'Zend/Loader/PluginLoader/Exception.php';
442:             throw new Zend_Loader_PluginLoader_Exception('Specified file does not exist and/or directory does not exist (' . $file . ')');
443:         }
444:         if (file_exists($file) && !is_writable($file)) {
445:             require_once 'Zend/Loader/PluginLoader/Exception.php';
446:             throw new Zend_Loader_PluginLoader_Exception('Specified file is not writeable (' . $file . ')');
447:         }
448:         if (!file_exists($file) && file_exists(dirname($file)) && !is_writable(dirname($file))) {
449:             require_once 'Zend/Loader/PluginLoader/Exception.php';
450:             throw new Zend_Loader_PluginLoader_Exception('Specified file is not writeable (' . $file . ')');
451:         }
452: 
453:         self::$_includeFileCache = $file;
454:     }
455: 
456:     /**
457:      * Retrieve class file cache path
458:      *
459:      * @return string|null
460:      */
461:     public static function getIncludeFileCache()
462:     {
463:         return self::$_includeFileCache;
464:     }
465: 
466:     /**
467:      * Append an include_once statement to the class file cache
468:      *
469:      * @param  string $incFile
470:      * @return void
471:      */
472:     protected static function _appendIncFile($incFile)
473:     {
474:         if (!file_exists(self::$_includeFileCache)) {
475:             $file = '<?php';
476:         } else {
477:             $file = file_get_contents(self::$_includeFileCache);
478:         }
479:         if (!strstr($file, $incFile)) {
480:             $file .= "\ninclude_once '$incFile';";
481:             file_put_contents(self::$_includeFileCache, $file);
482:         }
483:     }
484: }
485: 
Pry Framework API documentation generated by ApiGen 2.6.1