bundle.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php namespace Laravel; defined('APP_PATH') or die('No direct script access.');
  2. class Bundle {
  3. /**
  4. * All of the application's bundles.
  5. *
  6. * @var array
  7. */
  8. public static $bundles = array();
  9. /**
  10. * A cache of the parsed bundle elements.
  11. *
  12. * @var array
  13. */
  14. public static $elements = array();
  15. /**
  16. * All of the bundles that have been started.
  17. *
  18. * @var array
  19. */
  20. public static $started = array();
  21. /**
  22. * Register a bundle for the application.
  23. *
  24. * @param string $bundle
  25. * @param string $location
  26. * @param string $handles
  27. * @return void
  28. */
  29. public static function register($bundle, $config = array())
  30. {
  31. $defaults = array('handles' => null, 'auto' => false);
  32. if ( ! isset($config['location']))
  33. {
  34. throw new \Exception("Location not set for bundle [$bundle]");
  35. }
  36. // We will trim the trailing slash from the location and add it back so we don't
  37. // have to worry about the developer adding or not adding it to the location
  38. // path for the bundle. This makes sure it is always there.
  39. $config['location'] = BUNDLE_PATH.rtrim($config['location'], DS).DS;
  40. static::$bundles[$bundle] = array_merge($defaults, $config);
  41. }
  42. /**
  43. * Load a bundle by running it's start-up script.
  44. *
  45. * If the bundle has already been started, no action will be taken.
  46. *
  47. * @param string $bundle
  48. * @return void
  49. */
  50. public static function start($bundle)
  51. {
  52. if (static::started($bundle)) return;
  53. if ($bundle !== DEFAULT_BUNDLE and ! static::exists($bundle))
  54. {
  55. throw new \Exception("Bundle [$bundle] has not been installed.");
  56. }
  57. // Each bundle may have a "start" script which is responsible for preparing
  58. // the bundle for use by the application. The start script may register any
  59. // classes the bundle uses with the auto-loader, or perhaps will start any
  60. // dependent bundles so that they are available.
  61. if (file_exists($path = static::path($bundle).'bundle'.EXT))
  62. {
  63. require_once $path;
  64. }
  65. // Each bundle may also have a "routes" file which is responsible for
  66. // registering the bundle's routes. This is kept separate from the
  67. // start script for reverse routing efficiency purposes.
  68. static::routes($bundle);
  69. static::$started[] = strtolower($bundle);
  70. }
  71. /**
  72. * Load the "routes" file for a given bundle.
  73. *
  74. * @param string $bundle
  75. * @return void
  76. */
  77. public static function routes($bundle)
  78. {
  79. if (file_exists($path = static::path($bundle).'routes'.EXT))
  80. {
  81. require_once $path;
  82. }
  83. }
  84. /**
  85. * Determine which bundle handles the given URI.
  86. *
  87. * If no bundle is assigned to handle the URI, the default bundle is returned.
  88. *
  89. * @param string $bundle
  90. * @return string
  91. */
  92. public static function handles($uri)
  93. {
  94. foreach (static::$bundles as $key => $value)
  95. {
  96. if (starts_with($uri, $value['handles'])) return $key;
  97. }
  98. return DEFAULT_BUNDLE;
  99. }
  100. /**
  101. * Deteremine if a bundle exists within the bundles directory.
  102. *
  103. * @param string $bundle
  104. * @return bool
  105. */
  106. public static function exists($bundle)
  107. {
  108. return in_array(strtolower($bundle), static::names());
  109. }
  110. /**
  111. * Determine if a given bundle has been started for the request.
  112. *
  113. * @param string $bundle
  114. * @return void
  115. */
  116. public static function started($bundle)
  117. {
  118. return in_array(strtolower($bundle), static::$started);
  119. }
  120. /**
  121. * Get the identifier prefix for the bundle.
  122. *
  123. * @param string $bundle
  124. * @return string
  125. */
  126. public static function prefix($bundle)
  127. {
  128. return ($bundle !== DEFAULT_BUNDLE) ? "{$bundle}::" : '';
  129. }
  130. /**
  131. * Get the class prefix for a given bundle.
  132. *
  133. * @param string $bundle
  134. * @return string
  135. */
  136. public static function class_prefix($bundle)
  137. {
  138. return ($bundle !== DEFAULT_BUNDLE) ? Str::classify($bundle).'_' : '';
  139. }
  140. /**
  141. * Return the root bundle path for a given bundle.
  142. *
  143. * <code>
  144. * // Returns the bundle path for the "admin" bundle
  145. * $path = Bundle::path('admin');
  146. *
  147. * // Returns the APP_PATH constant as the default bundle
  148. * $path = Bundle::path('application');
  149. * </code>
  150. *
  151. * @param string $bundle
  152. * @return string
  153. */
  154. public static function path($bundle)
  155. {
  156. return ($bundle == DEFAULT_BUNDLE) ? APP_PATH : static::$bundles[$bundle]['location'];
  157. }
  158. /**
  159. * Return the root asset path for the given bundle.
  160. *
  161. * @param string $bundle
  162. * @return string
  163. */
  164. public static function assets($bundle)
  165. {
  166. return ($bundle != DEFAULT_BUNDLE) ? URL::base()."/bundles/{$bundle}/" : URL::base().'/';
  167. }
  168. /**
  169. * Get the bundle name from a given identifier.
  170. *
  171. * <code>
  172. * // Returns "admin" as the bundle name for the identifier
  173. * $bundle = Bundle::name('admin::home.index');
  174. * </code>
  175. *
  176. * @param string $identifier
  177. * @return string
  178. */
  179. public static function name($identifier)
  180. {
  181. list($bundle, $element) = static::parse($identifier);
  182. return $bundle;
  183. }
  184. /**
  185. * Get the element name from a given identifier.
  186. *
  187. * <code>
  188. * // Returns "home.index" as the element name for the identifier
  189. * $bundle = Bundle::bundle('admin::home.index');
  190. * </code>
  191. *
  192. * @param string $identifier
  193. * @return string
  194. */
  195. public static function element($identifier)
  196. {
  197. list($bundle, $element) = static::parse($identifier);
  198. return $element;
  199. }
  200. /**
  201. * Reconstruct an identifier from a given bundle and element.
  202. *
  203. * <code>
  204. * // Returns "admin::home.index"
  205. * $identifier = Bundle::identifier('admin', 'home.index');
  206. *
  207. * // Returns "home.index"
  208. * $identifier = Bundle::identifier('application', 'home.index');
  209. * </code>
  210. *
  211. * @param string $bundle
  212. * @param string $element
  213. * @return string
  214. */
  215. public static function identifier($bundle, $element)
  216. {
  217. return (is_null($bundle) or $bundle == DEFAULT_BUNDLE) ? $element : $bundle.'::'.$element;
  218. }
  219. /**
  220. * Return the bundle name if it exists, else return the default bundle.
  221. *
  222. * @param string $bundle
  223. * @return string
  224. */
  225. public static function resolve($bundle)
  226. {
  227. return (static::exists($bundle)) ? $bundle : DEFAULT_BUNDLE;
  228. }
  229. /**
  230. * Parse a element identifier and return the bundle name and element.
  231. *
  232. * <code>
  233. * // Returns array(null, 'admin.user')
  234. * $element = Bundle::parse('admin.user');
  235. *
  236. * // Parses "admin::user" and returns array('admin', 'user')
  237. * $element = Bundle::parse('admin::user');
  238. * </code>
  239. *
  240. * @param string $identifier
  241. * @return array
  242. */
  243. public static function parse($identifier)
  244. {
  245. // The parsed elements are cached so we don't have to reparse them on each
  246. // subsequent request for the parsed element. So, if we've already parsed
  247. // the given element, we'll just return the cached copy.
  248. if (isset(static::$elements[$identifier]))
  249. {
  250. return static::$elements[$identifier];
  251. }
  252. if (strpos($identifier, '::') !== false)
  253. {
  254. $element = explode('::', strtolower($identifier));
  255. }
  256. // If no bundle is in the identifier, we will insert the default bundle
  257. // since classes like Config and Lang organize their items by bundle.
  258. // The "application" folder essentially behaves as a bundle.
  259. else
  260. {
  261. $element = array(DEFAULT_BUNDLE, strtolower($identifier));
  262. }
  263. return static::$elements[$identifier] = $element;
  264. }
  265. /**
  266. * Get the information for a given bundle.
  267. *
  268. * @param string $bundle
  269. * @return object
  270. */
  271. public static function get($bundle)
  272. {
  273. return (object) array_get(static::$bundles, $bundle);
  274. }
  275. /**
  276. * Get all of the installed bundles for the application.
  277. *
  278. * @return array
  279. */
  280. public static function all()
  281. {
  282. return static::$bundles;
  283. }
  284. /**
  285. * Get all of the installed bundle names.
  286. *
  287. * @return array
  288. */
  289. public static function names()
  290. {
  291. return array_keys(static::$bundles);
  292. }
  293. }