Files
spa-api/laravel/bundle.php

476 lines
11 KiB
PHP
Raw Normal View History

2012-01-28 14:55:08 -06:00
<?php namespace Laravel; defined('DS') or die('No direct script access.');
2012-01-16 13:59:24 -06:00
2012-02-17 08:33:46 -06:00
use Laravel\Routing\Router;
2012-02-07 15:00:35 -06:00
use FilesystemIterator as fIterator;
2012-01-16 13:59:24 -06:00
class Bundle {
/**
* All of the application's bundles.
*
* @var array
*/
public static $bundles = array();
2012-01-16 13:59:24 -06:00
/**
* A cache of the parsed bundle elements.
*
* @var array
*/
public static $elements = array();
2012-01-16 13:59:24 -06:00
/**
* All of the bundles that have been started.
*
* @var array
*/
public static $started = array();
2012-02-06 16:54:44 -06:00
/**
* All of the bundles that have their routes files loaded.
*
* @var array
*/
public static $routed = array();
2012-02-08 08:28:16 -06:00
/**
2012-02-12 14:48:36 -06:00
* Register the bundle for the application.
2012-02-08 08:28:16 -06:00
*
2012-02-12 14:48:36 -06:00
* @param string $bundle
* @param array $config
2012-02-07 15:00:35 -06:00
* @return void
*/
2012-02-12 14:48:36 -06:00
public static function register($bundle, $config = array())
2012-02-07 15:00:35 -06:00
{
$defaults = array('handles' => null, 'auto' => false);
2012-01-26 17:01:17 -06:00
2012-02-12 14:48:36 -06:00
// If the given configuration is actually a string, we will assume it is a
// location and set the bundle name to match it. This is common for most
// bundles that simply live in the root bundle directory.
2012-02-12 14:48:36 -06:00
if (is_string($config))
2012-02-06 16:12:17 -06:00
{
2012-02-12 14:48:36 -06:00
$bundle = $config;
$config = array('location' => $bundle);
2012-02-06 16:12:17 -06:00
}
// If no location is set, we will set the location to match the name of
// the bundle. This is for bundles that are installed on the root of
2012-02-12 14:48:36 -06:00
// the bundle directory so a location was not set.
if ( ! isset($config['location']))
{
$config['location'] = $bundle;
}
2012-01-16 13:59:24 -06:00
2012-02-12 14:48:36 -06:00
static::$bundles[$bundle] = array_merge($defaults, $config);
2012-02-20 15:33:19 -06:00
// It is possible for the developer to specify auto-loader mappings
2012-02-20 15:33:19 -06:00
// directly on the bundle registration. This provides a convenient
// way to register mappings without a bootstrap.
2012-02-20 15:50:09 -06:00
if (isset($config['autoloads']))
{
2012-02-20 15:50:58 -06:00
static::autoloads($bundle, $config);
2012-02-20 15:50:09 -06:00
}
2012-02-07 15:41:28 -06:00
}
2012-01-16 13:59:24 -06:00
/**
* Load a bundle by running its start-up script.
2012-01-16 13:59:24 -06:00
*
* If the bundle has already been started, no action will be taken.
*
* @param string $bundle
* @return void
*/
public static function start($bundle)
{
if (static::started($bundle)) return;
2012-02-07 15:00:35 -06:00
if ( ! static::exists($bundle))
2012-01-16 13:59:24 -06:00
{
throw new \Exception("Bundle [$bundle] has not been installed.");
}
2012-02-16 13:59:48 -06:00
// Each bundle may have a start script which is responsible for preparing
// the bundle for use by the application. The start script may register
2012-04-30 15:09:56 -05:00
// any classes the bundle uses with the auto-loader class, etc.
if ( ! is_null($starter = static::option($bundle, 'starter')))
{
$starter();
}
elseif (file_exists($path = static::path($bundle).'start'.EXT))
2012-01-16 13:59:24 -06:00
{
require $path;
2012-01-16 13:59:24 -06:00
}
// Each bundle may also have a "routes" file which is responsible for
// registering the bundle's routes. This is kept separate from the
// start script for reverse routing efficiency purposes.
static::routes($bundle);
2012-02-16 16:26:39 -06:00
Event::fire("laravel.started: {$bundle}");
static::$started[] = strtolower($bundle);
2012-01-16 13:59:24 -06:00
}
/**
* Load the "routes" file for a given bundle.
*
* @param string $bundle
* @return void
*/
public static function routes($bundle)
{
2012-02-12 19:26:16 -06:00
if (static::routed($bundle)) return;
2012-02-06 16:54:44 -06:00
$path = static::path($bundle).'routes'.EXT;
// By setting the bundle property on the router, the router knows what
2012-02-12 14:48:36 -06:00
// value to replace the (:bundle) place-holder with when the bundle
// routes are added, keeping the routes flexible.
2012-02-17 08:33:46 -06:00
Router::$bundle = static::option($bundle, 'handles');
2012-02-12 14:48:36 -06:00
2012-02-06 16:54:44 -06:00
if ( ! static::routed($bundle) and file_exists($path))
2012-01-16 13:59:24 -06:00
{
2012-02-12 19:26:16 -06:00
static::$routed[] = $bundle;
require $path;
2012-01-16 13:59:24 -06:00
}
}
/**
* Register the auto-loading configuration for a bundle.
*
* @param string $bundle
* @param array $config
* @return void
*/
2012-02-20 15:50:58 -06:00
protected static function autoloads($bundle, $config)
{
$path = rtrim(Bundle::path($bundle), DS);
2012-02-20 15:50:09 -06:00
foreach ($config['autoloads'] as $type => $mappings)
{
// When registering each type of mapping we'll replace the (:bundle)
// place-holder with the path to the bundle's root directory, so
// the developer may dryly register the mappings.
$mappings = array_map(function($mapping) use ($path)
{
return str_replace('(:bundle)', $path, $mapping);
}, $mappings);
// Once the mappings are formatted, we will call the Autoloader
// function matching the mapping type and pass in the array of
// mappings so they can be registered and used.
Autoloader::$type($mappings);
}
}
2012-02-12 14:48:36 -06:00
/**
* Disable a bundle for the current request.
*
* @param string $bundle
* @return void
*/
public static function disable($bundle)
{
unset(static::$bundles[$bundle]);
}
2012-01-16 13:59:24 -06:00
/**
* Determine which bundle handles the given URI.
2012-01-16 13:59:24 -06:00
*
2012-03-25 22:38:35 -05:00
* The default bundle is returned if no other bundle is assigned.
2012-01-16 13:59:24 -06:00
*
2012-02-04 21:30:52 +00:00
* @param string $uri
* @return string
2012-01-16 13:59:24 -06:00
*/
public static function handles($uri)
2012-01-16 13:59:24 -06:00
{
2012-02-06 16:12:17 -06:00
$uri = rtrim($uri, '/').'/';
foreach (static::$bundles as $key => $value)
{
if (isset($value['handles']) and starts_with($uri, $value['handles'].'/') or $value['handles'] == '/')
2012-02-12 14:48:36 -06:00
{
return $key;
}
}
2012-01-16 13:59:24 -06:00
return DEFAULT_BUNDLE;
2012-01-16 13:59:24 -06:00
}
/**
* Determine if a bundle exists within the bundles directory.
2012-01-16 13:59:24 -06:00
*
* @param string $bundle
* @return bool
*/
public static function exists($bundle)
{
return $bundle == DEFAULT_BUNDLE or in_array(strtolower($bundle), static::names());
2012-01-16 13:59:24 -06:00
}
/**
* Determine if a given bundle has been started for the request.
*
* @param string $bundle
* @return void
*/
public static function started($bundle)
{
return in_array(strtolower($bundle), static::$started);
}
2012-02-06 16:54:44 -06:00
/**
* Determine if a given bundle has its routes file loaded.
*
* @param string $bundle
* @return void
*/
public static function routed($bundle)
{
return in_array(strtolower($bundle), static::$routed);
}
2012-01-16 13:59:24 -06:00
/**
* Get the identifier prefix for the bundle.
*
* @param string $bundle
* @return string
*/
public static function prefix($bundle)
{
return ($bundle !== DEFAULT_BUNDLE) ? "{$bundle}::" : '';
}
/**
* Get the class prefix for a given bundle.
*
* @param string $bundle
* @return string
*/
public static function class_prefix($bundle)
{
return ($bundle !== DEFAULT_BUNDLE) ? Str::classify($bundle).'_' : '';
}
/**
* Return the root bundle path for a given bundle.
*
* <code>
* // Returns the bundle path for the "admin" bundle
* $path = Bundle::path('admin');
*
2012-01-28 14:55:08 -06:00
* // Returns the path('app') constant as the default bundle
2012-01-16 13:59:24 -06:00
* $path = Bundle::path('application');
* </code>
*
* @param string $bundle
* @return string
*/
public static function path($bundle)
{
if (is_null($bundle) or $bundle === DEFAULT_BUNDLE)
{
return path('app');
}
elseif ($location = array_get(static::$bundles, $bundle.'.location'))
{
// If the bundle location starts with "path: ", we will assume that a raw
// path has been specified and will simply return it. Otherwise, we'll
// prepend the bundle directory path onto the location and return.
if (starts_with($location, 'path: '))
{
return str_finish(substr($location, 6), DS);
}
else
{
return str_finish(path('bundle').$location, DS);
}
}
2012-01-16 13:59:24 -06:00
}
/**
* Return the root asset path for the given bundle.
*
* @param string $bundle
* @return string
*/
public static function assets($bundle)
{
2012-02-17 08:31:17 -06:00
if (is_null($bundle)) return static::assets(DEFAULT_BUNDLE);
2012-04-23 23:43:09 -05:00
return ($bundle != DEFAULT_BUNDLE) ? "/bundles/{$bundle}/" : '/';
2012-01-16 13:59:24 -06:00
}
/**
* Get the bundle name from a given identifier.
*
* <code>
* // Returns "admin" as the bundle name for the identifier
* $bundle = Bundle::name('admin::home.index');
* </code>
*
* @param string $identifier
* @return string
*/
public static function name($identifier)
{
list($bundle, $element) = static::parse($identifier);
return $bundle;
}
/**
* Get the element name from a given identifier.
*
* <code>
* // Returns "home.index" as the element name for the identifier
* $bundle = Bundle::bundle('admin::home.index');
* </code>
*
* @param string $identifier
* @return string
*/
public static function element($identifier)
{
list($bundle, $element) = static::parse($identifier);
return $element;
}
/**
* Reconstruct an identifier from a given bundle and element.
*
* <code>
* // Returns "admin::home.index"
* $identifier = Bundle::identifier('admin', 'home.index');
*
* // Returns "home.index"
* $identifier = Bundle::identifier('application', 'home.index');
* </code>
*
* @param string $bundle
* @param string $element
* @return string
*/
public static function identifier($bundle, $element)
{
return (is_null($bundle) or $bundle == DEFAULT_BUNDLE) ? $element : $bundle.'::'.$element;
}
/**
* Return the bundle name if it exists, else return the default bundle.
*
* @param string $bundle
* @return string
*/
public static function resolve($bundle)
{
return (static::exists($bundle)) ? $bundle : DEFAULT_BUNDLE;
}
/**
* Parse an element identifier and return the bundle name and element.
2012-01-16 13:59:24 -06:00
*
* <code>
* // Returns array(null, 'admin.user')
* $element = Bundle::parse('admin.user');
*
* // Parses "admin::user" and returns array('admin', 'user')
* $element = Bundle::parse('admin::user');
* </code>
*
* @param string $identifier
* @return array
*/
public static function parse($identifier)
{
// The parsed elements are cached so we don't have to reparse them on each
// subsequent request for the parsed element. So if we've already parsed
// the given element, we'll just return the cached copy as the value.
2012-01-16 13:59:24 -06:00
if (isset(static::$elements[$identifier]))
{
return static::$elements[$identifier];
}
if (strpos($identifier, '::') !== false)
{
$element = explode('::', strtolower($identifier));
}
// If no bundle is in the identifier, we will insert the default bundle
// since classes like Config and Lang organize their items by bundle.
// The application folder essentially behaves as a default bundle.
2012-01-16 13:59:24 -06:00
else
{
$element = array(DEFAULT_BUNDLE, strtolower($identifier));
}
return static::$elements[$identifier] = $element;
}
/**
* Get the information for a given bundle.
*
* @param string $bundle
2012-02-12 14:48:36 -06:00
* @return object
*/
public static function get($bundle)
{
2012-02-09 23:35:08 -06:00
return array_get(static::$bundles, $bundle);
}
2012-02-09 23:32:19 -06:00
/**
* Get an option for a given bundle.
*
* @param string $bundle
* @param string $option
* @param mixed $default
2012-02-09 23:32:19 -06:00
* @return mixed
*/
public static function option($bundle, $option, $default = null)
2012-02-09 23:32:19 -06:00
{
$bundle = static::get($bundle);
if (is_null($bundle))
{
return value($default);
}
return array_get($bundle, $option, $default);
2012-02-09 23:32:19 -06:00
}
/**
2012-01-26 17:01:17 -06:00
* Get all of the installed bundles for the application.
2012-01-16 13:59:24 -06:00
*
* @return array
*/
public static function all()
2012-01-26 17:01:17 -06:00
{
return static::$bundles;
}
/**
* Get all of the installed bundle names.
*
* @return array
*/
public static function names()
2012-01-16 13:59:24 -06:00
{
return array_keys(static::$bundles);
2012-01-16 13:59:24 -06:00
}
/**
* Expand given bundle path of form "[bundle::]path/...".
*
* @param string $path
* @return string
*/
public static function expand($path)
{
list($bundle, $element) = static::parse($path);
return static::path($bundle).$element;
}
2012-01-16 13:59:24 -06:00
}