the whole shebang

This commit is contained in:
2014-11-25 16:42:40 +01:00
parent 7f74c0613e
commit ab1334c0cf
3686 changed files with 496409 additions and 1 deletions

View File

@@ -0,0 +1,255 @@
<?php namespace Illuminate\Config;
use Illuminate\Filesystem\Filesystem;
class FileLoader implements LoaderInterface {
/**
* The filesystem instance.
*
* @var \Illuminate\Filesystem\Filesystem
*/
protected $files;
/**
* The default configuration path.
*
* @var string
*/
protected $defaultPath;
/**
* All of the named path hints.
*
* @var array
*/
protected $hints = array();
/**
* A cache of whether namespaces and groups exists.
*
* @var array
*/
protected $exists = array();
/**
* Create a new file configuration loader.
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param string $defaultPath
* @return void
*/
public function __construct(Filesystem $files, $defaultPath)
{
$this->files = $files;
$this->defaultPath = $defaultPath;
}
/**
* Load the given configuration group.
*
* @param string $environment
* @param string $group
* @param string $namespace
* @return array
*/
public function load($environment, $group, $namespace = null)
{
$items = array();
// First we'll get the root configuration path for the environment which is
// where all of the configuration files live for that namespace, as well
// as any environment folders with their specific configuration items.
$path = $this->getPath($namespace);
if (is_null($path))
{
return $items;
}
// First we'll get the main configuration file for the groups. Once we have
// that we can check for any environment specific files, which will get
// merged on top of the main arrays to make the environments cascade.
$file = "{$path}/{$group}.php";
if ($this->files->exists($file))
{
$items = $this->files->getRequire($file);
}
// Finally we're ready to check for the environment specific configuration
// file which will be merged on top of the main arrays so that they get
// precedence over them if we are currently in an environments setup.
$file = "{$path}/{$environment}/{$group}.php";
if ($this->files->exists($file))
{
$items = $this->mergeEnvironment($items, $file);
}
return $items;
}
/**
* Merge the items in the given file into the items.
*
* @param array $items
* @param string $file
* @return array
*/
protected function mergeEnvironment(array $items, $file)
{
return array_replace_recursive($items, $this->files->getRequire($file));
}
/**
* Determine if the given group exists.
*
* @param string $group
* @param string $namespace
* @return bool
*/
public function exists($group, $namespace = null)
{
$key = $group.$namespace;
// We'll first check to see if we have determined if this namespace and
// group combination have been checked before. If they have, we will
// just return the cached result so we don't have to hit the disk.
if (isset($this->exists[$key]))
{
return $this->exists[$key];
}
$path = $this->getPath($namespace);
// To check if a group exists, we will simply get the path based on the
// namespace, and then check to see if this files exists within that
// namespace. False is returned if no path exists for a namespace.
if (is_null($path))
{
return $this->exists[$key] = false;
}
$file = "{$path}/{$group}.php";
// Finally, we can simply check if this file exists. We will also cache
// the value in an array so we don't have to go through this process
// again on subsequent checks for the existing of the config file.
$exists = $this->files->exists($file);
return $this->exists[$key] = $exists;
}
/**
* Apply any cascades to an array of package options.
*
* @param string $env
* @param string $package
* @param string $group
* @param array $items
* @return array
*/
public function cascadePackage($env, $package, $group, $items)
{
// First we will look for a configuration file in the packages configuration
// folder. If it exists, we will load it and merge it with these original
// options so that we will easily "cascade" a package's configurations.
$file = "packages/{$package}/{$group}.php";
if ($this->files->exists($path = $this->defaultPath.'/'.$file))
{
$items = array_merge($items, $this->getRequire($path));
}
// Once we have merged the regular package configuration we need to look for
// an environment specific configuration file. If one exists, we will get
// the contents and merge them on top of this array of options we have.
$path = $this->getPackagePath($env, $package, $group);
if ($this->files->exists($path))
{
$items = array_merge($items, $this->getRequire($path));
}
return $items;
}
/**
* Get the package path for an environment and group.
*
* @param string $env
* @param string $package
* @param string $group
* @return string
*/
protected function getPackagePath($env, $package, $group)
{
$file = "packages/{$package}/{$env}/{$group}.php";
return $this->defaultPath.'/'.$file;
}
/**
* Get the configuration path for a namespace.
*
* @param string $namespace
* @return string
*/
protected function getPath($namespace)
{
if (is_null($namespace))
{
return $this->defaultPath;
}
elseif (isset($this->hints[$namespace]))
{
return $this->hints[$namespace];
}
}
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param string $hint
* @return void
*/
public function addNamespace($namespace, $hint)
{
$this->hints[$namespace] = $hint;
}
/**
* Returns all registered namespaces with the config
* loader.
*
* @return array
*/
public function getNamespaces()
{
return $this->hints;
}
/**
* Get a file's contents by requiring it.
*
* @param string $path
* @return mixed
*/
protected function getRequire($path)
{
return $this->files->getRequire($path);
}
/**
* Get the Filesystem instance.
*
* @return \Illuminate\Filesystem\Filesystem
*/
public function getFilesystem()
{
return $this->files;
}
}

View File

@@ -0,0 +1,52 @@
<?php namespace Illuminate\Config;
interface LoaderInterface {
/**
* Load the given configuration group.
*
* @param string $environment
* @param string $group
* @param string $namespace
* @return array
*/
public function load($environment, $group, $namespace = null);
/**
* Determine if the given configuration group exists.
*
* @param string $group
* @param string $namespace
* @return bool
*/
public function exists($group, $namespace = null);
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param string $hint
* @return void
*/
public function addNamespace($namespace, $hint);
/**
* Returns all registered namespaces with the config
* loader.
*
* @return array
*/
public function getNamespaces();
/**
* Apply any cascades to an array of package options.
*
* @param string $environment
* @param string $package
* @param string $group
* @param array $items
* @return array
*/
public function cascadePackage($environment, $package, $group, $items);
}

View File

@@ -0,0 +1,414 @@
<?php namespace Illuminate\Config;
use Closure;
use ArrayAccess;
use Illuminate\Support\NamespacedItemResolver;
class Repository extends NamespacedItemResolver implements ArrayAccess {
/**
* The loader implementation.
*
* @var \Illuminate\Config\LoaderInterface
*/
protected $loader;
/**
* The current environment.
*
* @var string
*/
protected $environment;
/**
* All of the configuration items.
*
* @var array
*/
protected $items = array();
/**
* All of the registered packages.
*
* @var array
*/
protected $packages = array();
/**
* The after load callbacks for namespaces.
*
* @var array
*/
protected $afterLoad = array();
/**
* Create a new configuration repository.
*
* @param \Illuminate\Config\LoaderInterface $loader
* @param string $environment
* @return void
*/
public function __construct(LoaderInterface $loader, $environment)
{
$this->loader = $loader;
$this->environment = $environment;
}
/**
* Determine if the given configuration value exists.
*
* @param string $key
* @return bool
*/
public function has($key)
{
$default = microtime(true);
return $this->get($key, $default) !== $default;
}
/**
* Determine if a configuration group exists.
*
* @param string $key
* @return bool
*/
public function hasGroup($key)
{
list($namespace, $group, $item) = $this->parseKey($key);
return $this->loader->exists($group, $namespace);
}
/**
* Get the specified configuration value.
*
* @param string $key
* @param mixed $default
* @return mixed
*/
public function get($key, $default = null)
{
list($namespace, $group, $item) = $this->parseKey($key);
// Configuration items are actually keyed by "collection", which is simply a
// combination of each namespace and groups, which allows a unique way to
// identify the arrays of configuration items for the particular files.
$collection = $this->getCollection($group, $namespace);
$this->load($group, $namespace, $collection);
return array_get($this->items[$collection], $item, $default);
}
/**
* Set a given configuration value.
*
* @param string $key
* @param mixed $value
* @return void
*/
public function set($key, $value)
{
list($namespace, $group, $item) = $this->parseKey($key);
$collection = $this->getCollection($group, $namespace);
// We'll need to go ahead and lazy load each configuration groups even when
// we're just setting a configuration item so that the set item does not
// get overwritten if a different item in the group is requested later.
$this->load($group, $namespace, $collection);
if (is_null($item))
{
$this->items[$collection] = $value;
}
else
{
array_set($this->items[$collection], $item, $value);
}
}
/**
* Load the configuration group for the key.
*
* @param string $key
* @param string $namespace
* @param string $collection
* @return void
*/
protected function load($group, $namespace, $collection)
{
$env = $this->environment;
// If we've already loaded this collection, we will just bail out since we do
// not want to load it again. Once items are loaded a first time they will
// stay kept in memory within this class and not loaded from disk again.
if (isset($this->items[$collection]))
{
return;
}
$items = $this->loader->load($env, $group, $namespace);
// If we've already loaded this collection, we will just bail out since we do
// not want to load it again. Once items are loaded a first time they will
// stay kept in memory within this class and not loaded from disk again.
if (isset($this->afterLoad[$namespace]))
{
$items = $this->callAfterLoad($namespace, $group, $items);
}
$this->items[$collection] = $items;
}
/**
* Call the after load callback for a namespace.
*
* @param string $namespace
* @param string $group
* @param array $items
* @return array
*/
protected function callAfterLoad($namespace, $group, $items)
{
$callback = $this->afterLoad[$namespace];
return call_user_func($callback, $this, $group, $items);
}
/**
* Parse an array of namespaced segments.
*
* @param string $key
* @return array
*/
protected function parseNamespacedSegments($key)
{
list($namespace, $item) = explode('::', $key);
// If the namespace is registered as a package, we will just assume the group
// is equal to the namespace since all packages cascade in this way having
// a single file per package, otherwise we'll just parse them as normal.
if (in_array($namespace, $this->packages))
{
return $this->parsePackageSegments($key, $namespace, $item);
}
return parent::parseNamespacedSegments($key);
}
/**
* Parse the segments of a package namespace.
*
* @param string $namespace
* @param string $item
* @return array
*/
protected function parsePackageSegments($key, $namespace, $item)
{
$itemSegments = explode('.', $item);
// If the configuration file doesn't exist for the given package group we can
// assume that we should implicitly use the config file matching the name
// of the namespace. Generally packages should use one type or another.
if ( ! $this->loader->exists($itemSegments[0], $namespace))
{
return array($namespace, 'config', $item);
}
return parent::parseNamespacedSegments($key);
}
/**
* Register a package for cascading configuration.
*
* @param string $package
* @param string $hint
* @param string $namespace
* @return void
*/
public function package($package, $hint, $namespace = null)
{
$namespace = $this->getPackageNamespace($package, $namespace);
$this->packages[] = $namespace;
// First we will simply register the namespace with the repository so that it
// can be loaded. Once we have done that we'll register an after namespace
// callback so that we can cascade an application package configuration.
$this->addNamespace($namespace, $hint);
$this->afterLoading($namespace, function($me, $group, $items) use ($package)
{
$env = $me->getEnvironment();
$loader = $me->getLoader();
return $loader->cascadePackage($env, $package, $group, $items);
});
}
/**
* Get the configuration namespace for a package.
*
* @param string $package
* @param string $namespace
* @return string
*/
protected function getPackageNamespace($package, $namespace)
{
if (is_null($namespace))
{
list($vendor, $namespace) = explode('/', $package);
}
return $namespace;
}
/**
* Register an after load callback for a given namespace.
*
* @param string $namespace
* @param Closure $callback
* @return void
*/
public function afterLoading($namespace, Closure $callback)
{
$this->afterLoad[$namespace] = $callback;
}
/**
* Get the collection identifier.
*
* @param string $group
* @param string $namespace
* @return string
*/
protected function getCollection($group, $namespace = null)
{
$namespace = $namespace ?: '*';
return $namespace.'::'.$group;
}
/**
* Add a new namespace to the loader.
*
* @param string $namespace
* @param string $hint
* @return void
*/
public function addNamespace($namespace, $hint)
{
return $this->loader->addNamespace($namespace, $hint);
}
/**
* Returns all registered namespaces with the config
* loader.
*
* @return array
*/
public function getNamespaces()
{
return $this->loader->getNamespaces();
}
/**
* Get the loader implementation.
*
* @return \Illuminate\Config\LoaderInterface
*/
public function getLoader()
{
return $this->loader;
}
/**
* Set the loader implementation.
*
* @param \Illuminate\Config\LoaderInterface $loader
* @return void
*/
public function setLoader(LoaderInterface $loader)
{
$this->loader = $loader;
}
/**
* Get the current configuration environment.
*
* @return string
*/
public function getEnvironment()
{
return $this->environment;
}
/**
* Get the after load callback array.
*
* @return array
*/
public function getAfterLoadCallbacks()
{
return $this->afterLoad;
}
/**
* Get all of the configuration items.
*
* @return array
*/
public function getItems()
{
return $this->items;
}
/**
* Determine if the given configuration option exists.
*
* @param string $key
* @return bool
*/
public function offsetExists($key)
{
return $this->has($key);
}
/**
* Get a configuration option.
*
* @param string $key
* @return bool
*/
public function offsetGet($key)
{
return $this->get($key);
}
/**
* Set a configuration option.
*
* @param string $key
* @param string $value
* @return void
*/
public function offsetSet($key, $value)
{
$this->set($key, $value);
}
/**
* Unset a configuration option.
*
* @param string $key
* @return void
*/
public function offsetUnset($key)
{
$this->set($key, null);
}
}

View File

@@ -0,0 +1,28 @@
{
"name": "illuminate/config",
"license": "MIT",
"authors": [
{
"name": "Taylor Otwell",
"email": "taylorotwell@gmail.com"
}
],
"require": {
"php": ">=5.3.0",
"illuminate/filesystem": "4.0.x",
"illuminate/support": "4.0.x"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {"Illuminate\\Config": ""}
},
"target-dir": "Illuminate/Config",
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
}
},
"minimum-stability": "dev"
}