PageRenderTime 45ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/concrete/libraries/3rdparty/Zend/Loader/PluginLoader.php

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