Base for a static organization website

CakePlugin.php 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. <?php
  2. /**
  3. * CakePlugin class
  4. *
  5. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  6. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice.
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  13. * @link http://cakephp.org CakePHP(tm) Project
  14. * @package Cake.Core
  15. * @since CakePHP(tm) v 2.0.0
  16. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  17. */
  18. /**
  19. * CakePlugin is responsible for loading and unloading plugins. It also can
  20. * retrieve plugin paths and load their bootstrap and routes files.
  21. *
  22. * @package Cake.Core
  23. * @link http://book.cakephp.org/2.0/en/plugins.html
  24. */
  25. class CakePlugin {
  26. /**
  27. * Holds a list of all loaded plugins and their configuration
  28. *
  29. * @var array
  30. */
  31. protected static $_plugins = array();
  32. /**
  33. * Loads a plugin and optionally loads bootstrapping, routing files or loads an initialization function
  34. *
  35. * Examples:
  36. *
  37. * `CakePlugin::load('DebugKit')`
  38. *
  39. * Will load the DebugKit plugin and will not load any bootstrap nor route files
  40. *
  41. * `CakePlugin::load('DebugKit', array('bootstrap' => true, 'routes' => true))`
  42. *
  43. * will load the bootstrap.php and routes.php files
  44. *
  45. * `CakePlugin::load('DebugKit', array('bootstrap' => false, 'routes' => true))`
  46. *
  47. * will load routes.php file but not bootstrap.php
  48. *
  49. * `CakePlugin::load('DebugKit', array('bootstrap' => array('config1', 'config2')))`
  50. *
  51. * will load config1.php and config2.php files
  52. *
  53. * `CakePlugin::load('DebugKit', array('bootstrap' => 'aCallableMethod'))`
  54. *
  55. * will run the aCallableMethod function to initialize it
  56. *
  57. * Bootstrap initialization functions can be expressed as a PHP callback type,
  58. * including closures. Callbacks will receive two parameters
  59. * (plugin name, plugin configuration)
  60. *
  61. * It is also possible to load multiple plugins at once. Examples:
  62. *
  63. * `CakePlugin::load(array('DebugKit', 'ApiGenerator'))`
  64. *
  65. * will load the DebugKit and ApiGenerator plugins
  66. *
  67. * `CakePlugin::load(array('DebugKit', 'ApiGenerator'), array('bootstrap' => true))`
  68. *
  69. * will load bootstrap file for both plugins
  70. *
  71. * ```
  72. * CakePlugin::load(array(
  73. * 'DebugKit' => array('routes' => true),
  74. * 'ApiGenerator'
  75. * ), array('bootstrap' => true))
  76. * ```
  77. *
  78. * Will only load the bootstrap for ApiGenerator and only the routes for DebugKit.
  79. * By using the `path` option you can specify an absolute path to the plugin. Make
  80. * sure that the path is slash terminated or your plugin will not be located properly.
  81. *
  82. * @param string|array $plugin name of the plugin to be loaded in CamelCase format or array or plugins to load
  83. * @param array $config configuration options for the plugin
  84. * @throws MissingPluginException if the folder for the plugin to be loaded is not found
  85. * @return void
  86. */
  87. public static function load($plugin, $config = array()) {
  88. if (is_array($plugin)) {
  89. foreach ($plugin as $name => $conf) {
  90. list($name, $conf) = (is_numeric($name)) ? array($conf, $config) : array($name, $conf);
  91. static::load($name, $conf);
  92. }
  93. return;
  94. }
  95. $config += array('bootstrap' => false, 'routes' => false, 'ignoreMissing' => false);
  96. if (empty($config['path'])) {
  97. foreach (App::path('plugins') as $path) {
  98. if (is_dir($path . $plugin)) {
  99. static::$_plugins[$plugin] = $config + array('path' => $path . $plugin . DS);
  100. break;
  101. }
  102. //Backwards compatibility to make easier to migrate to 2.0
  103. $underscored = Inflector::underscore($plugin);
  104. if (is_dir($path . $underscored)) {
  105. static::$_plugins[$plugin] = $config + array('path' => $path . $underscored . DS);
  106. break;
  107. }
  108. }
  109. } else {
  110. static::$_plugins[$plugin] = $config;
  111. }
  112. if (empty(static::$_plugins[$plugin]['path'])) {
  113. throw new MissingPluginException(array('plugin' => $plugin));
  114. }
  115. if (!empty(static::$_plugins[$plugin]['bootstrap'])) {
  116. static::bootstrap($plugin);
  117. }
  118. }
  119. /**
  120. * Will load all the plugins located in the configured plugins folders
  121. * If passed an options array, it will be used as a common default for all plugins to be loaded
  122. * It is possible to set specific defaults for each plugins in the options array. Examples:
  123. *
  124. * ```
  125. * CakePlugin::loadAll(array(
  126. * array('bootstrap' => true),
  127. * 'DebugKit' => array('routes' => true, 'bootstrap' => false),
  128. * ))
  129. * ```
  130. *
  131. * The above example will load the bootstrap file for all plugins, but for DebugKit it will only load
  132. * the routes file and will not look for any bootstrap script. If you are loading
  133. * many plugins that inconsistently support routes/bootstrap files, instead of detailing
  134. * each plugin you can use the `ignoreMissing` option:
  135. *
  136. * ```
  137. * CakePlugin::loadAll(array(
  138. * 'ignoreMissing' => true,
  139. * 'bootstrap' => true,
  140. * 'routes' => true,
  141. * ));
  142. * ```
  143. *
  144. * The ignoreMissing option will do additional file_exists() calls but is simpler
  145. * to use.
  146. *
  147. * @param array $options Options list. See CakePlugin::load() for valid options.
  148. * @return void
  149. */
  150. public static function loadAll($options = array()) {
  151. $plugins = App::objects('plugins');
  152. foreach ($plugins as $p) {
  153. $opts = isset($options[$p]) ? (array)$options[$p] : array();
  154. if (isset($options[0])) {
  155. $opts += $options[0];
  156. }
  157. static::load($p, $opts);
  158. }
  159. }
  160. /**
  161. * Returns the filesystem path for a plugin
  162. *
  163. * @param string $plugin name of the plugin in CamelCase format
  164. * @return string path to the plugin folder
  165. * @throws MissingPluginException if the folder for plugin was not found or plugin has not been loaded
  166. */
  167. public static function path($plugin) {
  168. if (empty(static::$_plugins[$plugin])) {
  169. throw new MissingPluginException(array('plugin' => $plugin));
  170. }
  171. return static::$_plugins[$plugin]['path'];
  172. }
  173. /**
  174. * Loads the bootstrapping files for a plugin, or calls the initialization setup in the configuration
  175. *
  176. * @param string $plugin name of the plugin
  177. * @return mixed
  178. * @see CakePlugin::load() for examples of bootstrap configuration
  179. */
  180. public static function bootstrap($plugin) {
  181. $config = static::$_plugins[$plugin];
  182. if ($config['bootstrap'] === false) {
  183. return false;
  184. }
  185. if (is_callable($config['bootstrap'])) {
  186. return call_user_func_array($config['bootstrap'], array($plugin, $config));
  187. }
  188. $path = static::path($plugin);
  189. if ($config['bootstrap'] === true) {
  190. return static::_includeFile(
  191. $path . 'Config' . DS . 'bootstrap.php',
  192. $config['ignoreMissing']
  193. );
  194. }
  195. $bootstrap = (array)$config['bootstrap'];
  196. foreach ($bootstrap as $file) {
  197. static::_includeFile(
  198. $path . 'Config' . DS . $file . '.php',
  199. $config['ignoreMissing']
  200. );
  201. }
  202. return true;
  203. }
  204. /**
  205. * Loads the routes file for a plugin, or all plugins configured to load their respective routes file
  206. *
  207. * @param string $plugin name of the plugin, if null will operate on all plugins having enabled the
  208. * loading of routes files
  209. * @return bool
  210. */
  211. public static function routes($plugin = null) {
  212. if ($plugin === null) {
  213. foreach (static::loaded() as $p) {
  214. static::routes($p);
  215. }
  216. return true;
  217. }
  218. $config = static::$_plugins[$plugin];
  219. if ($config['routes'] === false) {
  220. return false;
  221. }
  222. return (bool)static::_includeFile(
  223. static::path($plugin) . 'Config' . DS . 'routes.php',
  224. $config['ignoreMissing']
  225. );
  226. }
  227. /**
  228. * Returns true if the plugin $plugin is already loaded
  229. * If plugin is null, it will return a list of all loaded plugins
  230. *
  231. * @param string $plugin Plugin name to check.
  232. * @return mixed boolean true if $plugin is already loaded.
  233. * If $plugin is null, returns a list of plugins that have been loaded
  234. */
  235. public static function loaded($plugin = null) {
  236. if ($plugin) {
  237. return isset(static::$_plugins[$plugin]);
  238. }
  239. $return = array_keys(static::$_plugins);
  240. sort($return);
  241. return $return;
  242. }
  243. /**
  244. * Forgets a loaded plugin or all of them if first parameter is null
  245. *
  246. * @param string $plugin name of the plugin to forget
  247. * @return void
  248. */
  249. public static function unload($plugin = null) {
  250. if ($plugin === null) {
  251. static::$_plugins = array();
  252. } else {
  253. unset(static::$_plugins[$plugin]);
  254. }
  255. }
  256. /**
  257. * Include file, ignoring include error if needed if file is missing
  258. *
  259. * @param string $file File to include
  260. * @param bool $ignoreMissing Whether to ignore include error for missing files
  261. * @return mixed
  262. */
  263. protected static function _includeFile($file, $ignoreMissing = false) {
  264. if ($ignoreMissing && !is_file($file)) {
  265. return false;
  266. }
  267. return include $file;
  268. }
  269. }