gmarche/vendor/php-di/php-di/src/DI/ContainerBuilder.php

285 lines
7.3 KiB
PHP

<?php
namespace DI;
use DI\Definition\Source\AnnotationReader;
use DI\Definition\Source\Autowiring;
use DI\Definition\Source\CachedDefinitionSource;
use DI\Definition\Source\DefinitionArray;
use DI\Definition\Source\DefinitionFile;
use DI\Definition\Source\DefinitionSource;
use DI\Definition\Source\SourceChain;
use DI\Proxy\ProxyFactory;
use Doctrine\Common\Cache\Cache;
use InvalidArgumentException;
use Psr\Container\ContainerInterface;
/**
* Helper to create and configure a Container.
*
* With the default options, the container created is appropriate for the development environment.
*
* Example:
*
* $builder = new ContainerBuilder();
* $container = $builder->build();
*
* @since 3.2
* @author Matthieu Napoli <matthieu@mnapoli.fr>
*/
class ContainerBuilder
{
/**
* Name of the container class, used to create the container.
* @var string
*/
private $containerClass;
/**
* @var bool
*/
private $useAutowiring = true;
/**
* @var bool
*/
private $useAnnotations = false;
/**
* @var bool
*/
private $ignorePhpDocErrors = false;
/**
* @var Cache
*/
private $cache;
/**
* If true, write the proxies to disk to improve performances.
* @var bool
*/
private $writeProxiesToFile = false;
/**
* Directory where to write the proxies (if $writeProxiesToFile is enabled).
* @var string
*/
private $proxyDirectory;
/**
* If PHP-DI is wrapped in another container, this references the wrapper.
* @var ContainerInterface
*/
private $wrapperContainer;
/**
* @var DefinitionSource[]
*/
private $definitionSources = [];
/**
* Whether the container has already been built.
* @var bool
*/
private $locked = false;
/**
* Build a container configured for the dev environment.
*
* @return Container
*/
public static function buildDevContainer()
{
$builder = new self();
return $builder->build();
}
/**
* @param string $containerClass Name of the container class, used to create the container.
*/
public function __construct($containerClass = 'DI\Container')
{
$this->containerClass = $containerClass;
}
/**
* Build and return a container.
*
* @return Container
*/
public function build()
{
$sources = array_reverse($this->definitionSources);
if ($this->useAnnotations) {
$sources[] = new AnnotationReader($this->ignorePhpDocErrors);
} elseif ($this->useAutowiring) {
$sources[] = new Autowiring();
}
$chain = new SourceChain($sources);
if ($this->cache) {
$source = new CachedDefinitionSource($chain, $this->cache);
$chain->setRootDefinitionSource($source);
} else {
$source = $chain;
// Mutable definition source
$source->setMutableDefinitionSource(new DefinitionArray());
}
$proxyFactory = new ProxyFactory($this->writeProxiesToFile, $this->proxyDirectory);
$this->locked = true;
$containerClass = $this->containerClass;
return new $containerClass($source, $proxyFactory, $this->wrapperContainer);
}
/**
* Enable or disable the use of autowiring to guess injections.
*
* Enabled by default.
*
* @param bool $bool
* @return ContainerBuilder
*/
public function useAutowiring($bool)
{
$this->ensureNotLocked();
$this->useAutowiring = $bool;
return $this;
}
/**
* Enable or disable the use of annotations to guess injections.
*
* Disabled by default.
*
* @param bool $bool
* @return ContainerBuilder
*/
public function useAnnotations($bool)
{
$this->ensureNotLocked();
$this->useAnnotations = $bool;
return $this;
}
/**
* Enable or disable ignoring phpdoc errors (non-existent classes in `@param` or `@var`).
*
* @param bool $bool
* @return ContainerBuilder
*/
public function ignorePhpDocErrors($bool)
{
$this->ensureNotLocked();
$this->ignorePhpDocErrors = $bool;
return $this;
}
/**
* Enables the use of a cache for the definitions.
*
* @param Cache $cache Cache backend to use
* @return ContainerBuilder
*/
public function setDefinitionCache(Cache $cache)
{
$this->ensureNotLocked();
$this->cache = $cache;
return $this;
}
/**
* Configure the proxy generation.
*
* For dev environment, use writeProxiesToFile(false) (default configuration)
* For production environment, use writeProxiesToFile(true, 'tmp/proxies')
*
* @param bool $writeToFile If true, write the proxies to disk to improve performances
* @param string|null $proxyDirectory Directory where to write the proxies
* @throws InvalidArgumentException when writeToFile is set to true and the proxy directory is null
* @return ContainerBuilder
*/
public function writeProxiesToFile($writeToFile, $proxyDirectory = null)
{
$this->ensureNotLocked();
$this->writeProxiesToFile = $writeToFile;
if ($writeToFile && $proxyDirectory === null) {
throw new InvalidArgumentException(
'The proxy directory must be specified if you want to write proxies on disk'
);
}
$this->proxyDirectory = $proxyDirectory;
return $this;
}
/**
* If PHP-DI's container is wrapped by another container, we can
* set this so that PHP-DI will use the wrapper rather than itself for building objects.
*
* @param ContainerInterface $otherContainer
* @return $this
*/
public function wrapContainer(ContainerInterface $otherContainer)
{
$this->ensureNotLocked();
$this->wrapperContainer = $otherContainer;
return $this;
}
/**
* Add definitions to the container.
*
* @param string|array|DefinitionSource $definitions Can be an array of definitions, the
* name of a file containing definitions
* or a DefinitionSource object.
* @return $this
*/
public function addDefinitions($definitions)
{
$this->ensureNotLocked();
if (is_string($definitions)) {
// File
$definitions = new DefinitionFile($definitions);
} elseif (is_array($definitions)) {
$definitions = new DefinitionArray($definitions);
} elseif (! $definitions instanceof DefinitionSource) {
throw new InvalidArgumentException(sprintf(
'%s parameter must be a string, an array or a DefinitionSource object, %s given',
'ContainerBuilder::addDefinitions()',
is_object($definitions) ? get_class($definitions) : gettype($definitions)
));
}
$this->definitionSources[] = $definitions;
return $this;
}
private function ensureNotLocked()
{
if ($this->locked) {
throw new \LogicException('The ContainerBuilder cannot be modified after the container has been built');
}
}
}