/standard/trunk/library/Zend/Loader/PluginLoader.php

https://github.com/bhaumik25/zend-framework · PHP · 339 lines · 177 code · 45 blank · 117 comment · 37 complexity · 85d42c1b36bf2df58da29ffe6bc87358 MD5 · raw file

  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-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /** Zend_Loader_PluginLoader_Interface */
  22. require_once 'Zend/Loader/PluginLoader/Interface.php';
  23. /** Zend_Loader */
  24. require_once 'Zend/Loader.php';
  25. /**
  26. * Generic plugin class loader
  27. *
  28. * @category Zend
  29. * @package Zend_Loader
  30. * @subpackage PluginLoader
  31. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  32. * @license http://framework.zend.com/license/new-bsd New BSD License
  33. */
  34. class Zend_Loader_PluginLoader implements Zend_Loader_PluginLoader_Interface
  35. {
  36. /**
  37. * Static registry property
  38. *
  39. * @var array
  40. */
  41. static protected $_staticPrefixToPaths = array();
  42. /**
  43. * Instance registry property
  44. *
  45. * @var array
  46. */
  47. protected $_prefixToPaths = array();
  48. /**
  49. * Statically loaded plugins
  50. *
  51. * @var array
  52. */
  53. static protected $_staticLoadedPlugins = array();
  54. /**
  55. * Instance loaded plugins
  56. *
  57. * @var array
  58. */
  59. protected $_loadedPlugins = array();
  60. /**
  61. * Whether to use a statically named registry for loading plugins
  62. *
  63. * @var string|null
  64. */
  65. protected $_useStaticRegistry = null;
  66. /**
  67. * Constructor
  68. *
  69. * @param array $prefixToPaths
  70. * @param string $staticRegistryName OPTIONAL
  71. */
  72. public function __construct(Array $prefixToPaths = array(), $staticRegistryName = null)
  73. {
  74. if (is_string($staticRegistryName) && !empty($staticRegistryName)) {
  75. $this->_useStaticRegistry = $staticRegistryName;
  76. self::$_staticPrefixToPaths[$staticRegistryName] = array();
  77. self::$_staticLoadedPlugins[$staticRegistryName] = array();
  78. }
  79. foreach ($prefixToPaths as $prefix => $path) {
  80. $this->addPrefixPath($prefix, $path);
  81. }
  82. }
  83. /**
  84. * Format prefix for internal use
  85. *
  86. * @param string $prefix
  87. * @return string
  88. */
  89. protected function _formatPrefix($prefix)
  90. {
  91. return rtrim($prefix, '_') . '_';
  92. }
  93. /**
  94. * Add prefixed paths to the registry of paths
  95. *
  96. * @param string $prefix
  97. * @param string $path
  98. * @return Zend_Loader_PluginLoader
  99. */
  100. public function addPrefixPath($prefix, $path)
  101. {
  102. if (!is_string($prefix) || !is_string($path)) {
  103. require_once 'Zend/Loader/PluginLoader/Exception.php';
  104. throw new Zend_Loader_PluginLoader_Exception('Zend_Loader_PluginLoader::addPrefixPath() method only takes strings for prefix and path.');
  105. }
  106. $prefix = $this->_formatPrefix($prefix);
  107. $path = rtrim($path, '/\\') . '/';
  108. if ($this->_useStaticRegistry) {
  109. self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix][] = $path;
  110. } else {
  111. $this->_prefixToPaths[$prefix][] = $path;
  112. }
  113. return $this;
  114. }
  115. /**
  116. * Get path stack
  117. *
  118. * @param string $prefix
  119. * @return false|array False if prefix does not exist, array otherwise
  120. */
  121. public function getPaths($prefix = null)
  122. {
  123. if ((null !== $prefix) && is_string($prefix)) {
  124. $prefix = $this->_formatPrefix($prefix);
  125. if ($this->_useStaticRegistry) {
  126. if (isset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix])) {
  127. return self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix];
  128. }
  129. return false;
  130. }
  131. if (isset($this->_prefixToPaths[$prefix])) {
  132. return $this->_prefixToPaths[$prefix];
  133. }
  134. return false;
  135. }
  136. if ($this->_useStaticRegistry) {
  137. return self::$_staticPrefixToPaths[$this->_useStaticRegistry];
  138. }
  139. return $this->_prefixToPaths;
  140. }
  141. /**
  142. * Clear path stack
  143. *
  144. * @param string $prefix
  145. * @return bool False only if $prefix does not exist
  146. */
  147. public function clearPaths($prefix = null)
  148. {
  149. if ((null !== $prefix) && is_string($prefix)) {
  150. $prefix = $this->_formatPrefix($prefix);
  151. if ($this->_useStaticRegistry) {
  152. if (isset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix])) {
  153. unset(self::$_staticPrefixToPaths[$this->_useStaticRegistry][$prefix]);
  154. return true;
  155. }
  156. return false;
  157. }
  158. if (isset($this->_prefixToPaths[$prefix])) {
  159. unset($this->_prefixToPaths[$prefix]);
  160. return true;
  161. }
  162. return false;
  163. }
  164. if ($this->_useStaticRegistry) {
  165. self::$_staticPrefixToPaths[$this->_useStaticRegistry] = array();
  166. } else {
  167. $this->_prefixToPaths = array();
  168. }
  169. return true;
  170. }
  171. /**
  172. * Remove a prefix (or prefixed-path) from the registry
  173. *
  174. * @param string $prefix
  175. * @param string $path OPTIONAL
  176. * @return Zend_Loader_PluginLoader
  177. */
  178. public function removePrefixPath($prefix, $path = null)
  179. {
  180. $prefix = $this->_formatPrefix($prefix);
  181. if ($this->_useStaticRegistry) {
  182. $registry =& self::$_staticPrefixToPaths[$this->_useStaticRegistry];
  183. } else {
  184. $registry =& $this->_prefixToPaths;
  185. }
  186. if (!isset($registry[$prefix])) {
  187. require_once 'Zend/Loader/PluginLoader/Exception.php';
  188. throw new Zend_Loader_PluginLoader_Exception('Prefix ' . $prefix . ' was not found in the PluginLoader.');
  189. }
  190. if ($path != null) {
  191. $pos = array_search($path, $registry[$prefix]);
  192. if ($pos === null) {
  193. require_once 'Zend/Loader/PluginLoader/Exception.php';
  194. throw new Zend_Loader_PluginLoader_Exception('Prefix ' . $prefix . ' / Path ' . $path . ' was not found in the PluginLoader.');
  195. }
  196. unset($registry[$prefix][$pos]);
  197. } else {
  198. unset($registry[$prefix]);
  199. }
  200. return $this;
  201. }
  202. /**
  203. * Normalize plugin name
  204. *
  205. * @param string $name
  206. * @return string
  207. */
  208. protected function _formatName($name)
  209. {
  210. return ucfirst((string) $name);
  211. }
  212. /**
  213. * Whether or not a Plugin by a specific name is loaded
  214. *
  215. * @param string $name
  216. * @return Zend_Loader_PluginLoader
  217. */
  218. public function isLoaded($name)
  219. {
  220. $name = $this->_formatName($name);
  221. if ($this->_useStaticRegistry) {
  222. return isset(self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name]);
  223. }
  224. return isset($this->_loadedPlugins[$name]);
  225. }
  226. /**
  227. * Return full class name for a named plugin
  228. *
  229. * @param string $name
  230. * @return string|false False if class not found, class name otherwise
  231. */
  232. public function getClassName($name)
  233. {
  234. $name = $this->_formatName($name);
  235. if ($this->_useStaticRegistry &&
  236. isset(self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name]))
  237. {
  238. return self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name];
  239. } elseif (isset($this->_loadedPlugins[$name])) {
  240. return $this->_loadedPlugins[$name];
  241. }
  242. return false;
  243. }
  244. /**
  245. * Load a plugin via the name provided
  246. *
  247. * @param string $name
  248. * @return string
  249. */
  250. public function load($name)
  251. {
  252. $name = $this->_formatName($name);
  253. if ($this->_useStaticRegistry) {
  254. $registry = self::$_staticPrefixToPaths[$this->_useStaticRegistry];
  255. } else {
  256. $registry = $this->_prefixToPaths;
  257. }
  258. if ($this->isLoaded($name)) {
  259. return $this->getClassName($name);
  260. }
  261. $found = false;
  262. $registry = array_reverse($registry, true);
  263. foreach ($registry as $prefix => $paths) {
  264. $paths = array_reverse($paths, true);
  265. foreach ($paths as $path) {
  266. $classFile = str_replace('_', DIRECTORY_SEPARATOR, $name) . '.php';
  267. $className = $prefix . $name;
  268. if (class_exists($className, false)) {
  269. $found = true;
  270. break 2;
  271. }
  272. if (Zend_Loader::isReadable($path . $classFile)) {
  273. include_once $path . $classFile;
  274. if (!class_exists($className, false)) {
  275. require_once 'Zend/Loader/PluginLoader/Exception.php';
  276. throw new Zend_Loader_PluginLoader_Exception('File ' . $classFile . ' was loaded but class named ' . $className . ' was not found within it.');
  277. }
  278. $found = true;
  279. break 2;
  280. }
  281. }
  282. }
  283. if ($found) {
  284. if ($this->_useStaticRegistry) {
  285. self::$_staticLoadedPlugins[$this->_useStaticRegistry][$name] = $className;
  286. } else {
  287. $this->_loadedPlugins[$name] = $className;
  288. }
  289. return $className;
  290. }
  291. require_once 'Zend/Loader/PluginLoader/Exception.php';
  292. throw new Zend_Loader_PluginLoader_Exception('Plugin by name ' . $name . ' was not found in the registry.');
  293. }
  294. }