- Patch #1497230 by Rob Loach, pdrake, effulgentsia: Use Dependency Injection to handle object definitions.
parent
1f2622c8b8
commit
0ca408e1d3
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Definition of Drupal\Core\Language\Language.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\Language;
|
||||
|
||||
/**
|
||||
* An object containing the information for an interface language.
|
||||
*
|
||||
* @todo To keep backwards compatibility with stdClass, we currently use
|
||||
* public scopes for the Language class's variables. We will change these to
|
||||
* full get/set functions in a follow-up issue: http://drupal.org/node/1512424
|
||||
*
|
||||
* @see language_default()
|
||||
*/
|
||||
class Language {
|
||||
// Properties within the Language are set up as the default language.
|
||||
public $name = 'English';
|
||||
public $langcode = 'en';
|
||||
public $direction = 0;
|
||||
public $enabled = 1;
|
||||
public $weight = 0;
|
||||
public $default = FALSE;
|
||||
public $method_id = NULL;
|
||||
|
||||
/**
|
||||
* Language constructor builds the default language object.
|
||||
*
|
||||
* @param array $options
|
||||
* The properties used to construct the language.
|
||||
*/
|
||||
public function __construct(array $options = array()) {
|
||||
// Set all the properties for the language.
|
||||
foreach ($options as $name => $value) {
|
||||
$this->$name = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend $this with properties from the given object.
|
||||
*
|
||||
* @todo Remove this function once $GLOBALS['language'] is gone.
|
||||
*/
|
||||
public function extend($obj) {
|
||||
$vars = get_object_vars($obj);
|
||||
foreach ($vars as $var => $value) {
|
||||
$this->$var = $value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
class Alias
|
||||
{
|
||||
private $id;
|
||||
private $public;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $id Alias identifier
|
||||
* @param Boolean $public If this alias is public
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($id, $public = true)
|
||||
{
|
||||
$this->id = strtolower($id);
|
||||
$this->public = $public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this DI Alias should be public or not.
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isPublic()
|
||||
{
|
||||
return $this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this Alias is public.
|
||||
*
|
||||
* @param Boolean $boolean If this Alias should be public
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setPublic($boolean)
|
||||
{
|
||||
$this->public = (Boolean) $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Id of this alias.
|
||||
*
|
||||
* @return string The alias id
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
137
core/vendor/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
vendored
Normal file
137
core/vendor/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Run this pass before passes that need to know more about the relation of
|
||||
* your services.
|
||||
*
|
||||
* This class will populate the ServiceReferenceGraph with information. You can
|
||||
* retrieve the graph in other passes from the compiler.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AnalyzeServiceReferencesPass implements RepeatablePassInterface
|
||||
{
|
||||
private $graph;
|
||||
private $container;
|
||||
private $currentId;
|
||||
private $currentDefinition;
|
||||
private $repeatedPass;
|
||||
private $onlyConstructorArguments;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Boolean $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
|
||||
*/
|
||||
public function __construct($onlyConstructorArguments = false)
|
||||
{
|
||||
$this->onlyConstructorArguments = (Boolean) $onlyConstructorArguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setRepeatedPass(RepeatedPass $repeatedPass)
|
||||
{
|
||||
$this->repeatedPass = $repeatedPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a ContainerBuilder object to populate the service reference graph.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->graph = $container->getCompiler()->getServiceReferenceGraph();
|
||||
$this->graph->clear();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->currentId = $id;
|
||||
$this->currentDefinition = $definition;
|
||||
$this->processArguments($definition->getArguments());
|
||||
|
||||
if (!$this->onlyConstructorArguments) {
|
||||
$this->processArguments($definition->getMethodCalls());
|
||||
$this->processArguments($definition->getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
$this->graph->connect($id, $alias, (string) $alias, $this->getDefinition((string) $alias), null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes service definitions for arguments to find relationships for the service graph.
|
||||
*
|
||||
* @param array $arguments An array of Reference or Definition objects relating to service definitions
|
||||
*/
|
||||
private function processArguments(array $arguments)
|
||||
{
|
||||
foreach ($arguments as $argument) {
|
||||
if (is_array($argument)) {
|
||||
$this->processArguments($argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$this->graph->connect(
|
||||
$this->currentId,
|
||||
$this->currentDefinition,
|
||||
$this->getDefinitionId((string) $argument),
|
||||
$this->getDefinition((string) $argument),
|
||||
$argument
|
||||
);
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$this->processArguments($argument->getArguments());
|
||||
$this->processArguments($argument->getMethodCalls());
|
||||
$this->processArguments($argument->getProperties());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a service definition given the full name or an alias.
|
||||
*
|
||||
* @param string $id A full id or alias for a service definition.
|
||||
*
|
||||
* @return Definition The definition related to the supplied id
|
||||
*/
|
||||
private function getDefinition($id)
|
||||
{
|
||||
$id = $this->getDefinitionId($id);
|
||||
|
||||
return null === $id ? null : $this->container->getDefinition($id);
|
||||
}
|
||||
|
||||
private function getDefinitionId($id)
|
||||
{
|
||||
while ($this->container->hasAlias($id)) {
|
||||
$id = (string) $this->container->getAlias($id);
|
||||
}
|
||||
|
||||
if (!$this->container->hasDefinition($id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
70
core/vendor/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
vendored
Normal file
70
core/vendor/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Checks your services for circular references
|
||||
*
|
||||
* References from method calls are ignored since we might be able to resolve
|
||||
* these references depending on the order in which services are called.
|
||||
*
|
||||
* Circular reference from method calls will only be detected at run-time.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class CheckCircularReferencesPass implements CompilerPassInterface
|
||||
{
|
||||
private $currentId;
|
||||
private $currentPath;
|
||||
|
||||
/**
|
||||
* Checks the ContainerBuilder object for circular references.
|
||||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder instances
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$graph = $container->getCompiler()->getServiceReferenceGraph();
|
||||
|
||||
foreach ($graph->getNodes() as $id => $node) {
|
||||
$this->currentId = $id;
|
||||
$this->currentPath = array($id);
|
||||
|
||||
$this->checkOutEdges($node->getOutEdges());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for circular references.
|
||||
*
|
||||
* @param array $edges An array of Nodes
|
||||
*
|
||||
* @throws ServiceCircularReferenceException When a circular reference is found.
|
||||
*/
|
||||
private function checkOutEdges(array $edges)
|
||||
{
|
||||
foreach ($edges as $edge) {
|
||||
$node = $edge->getDestNode();
|
||||
$this->currentPath[] = $id = $node->getId();
|
||||
|
||||
if ($this->currentId === $id) {
|
||||
throw new ServiceCircularReferenceException($this->currentId, $this->currentPath);
|
||||
}
|
||||
|
||||
$this->checkOutEdges($node->getOutEdges());
|
||||
array_pop($this->currentPath);
|
||||
}
|
||||
}
|
||||
}
|
79
core/vendor/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php
vendored
Normal file
79
core/vendor/Symfony/Component/DependencyInjection/Compiler/CheckDefinitionValidityPass.php
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* This pass validates each definition individually only taking the information
|
||||
* into account which is contained in the definition itself.
|
||||
*
|
||||
* Later passes can rely on the following, and specifically do not need to
|
||||
* perform these checks themselves:
|
||||
*
|
||||
* - non synthetic, non abstract services always have a class set
|
||||
* - synthetic services are always public
|
||||
* - synthetic services are always of non-prototype scope
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class CheckDefinitionValidityPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* Processes the ContainerBuilder to validate the Definition.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*
|
||||
* @throws RuntimeException When the Definition is invalid
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
// synthetic service is public
|
||||
if ($definition->isSynthetic() && !$definition->isPublic()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'A synthetic service ("%s") must be public.',
|
||||
$id
|
||||
));
|
||||
}
|
||||
|
||||
// synthetic service has non-prototype scope
|
||||
if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'A synthetic service ("%s") cannot be of scope "prototype".',
|
||||
$id
|
||||
));
|
||||
}
|
||||
|
||||
// non-synthetic, non-abstract service has class
|
||||
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
|
||||
if ($definition->getFactoryClass() || $definition->getFactoryService()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Please add the class to service "%s" even if it is constructed by a factory '
|
||||
.'since we might need to add method calls based on compile-time checks.',
|
||||
$id
|
||||
));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf(
|
||||
'The definition for "%s" has no class. If you intend to inject '
|
||||
.'this service dynamically at runtime, please mark it as synthetic=true. '
|
||||
.'If this is an abstract definition solely used by child definitions, '
|
||||
.'please add abstract=true, otherwise specify a class to get rid of this error.',
|
||||
$id
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Checks that all references are pointing to a valid service.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class CheckExceptionOnInvalidReferenceBehaviorPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
private $sourceId;
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$this->sourceId = $id;
|
||||
$this->processDefinition($definition);
|
||||
}
|
||||
}
|
||||
|
||||
private function processDefinition(Definition $definition)
|
||||
{
|
||||
$this->processReferences($definition->getArguments());
|
||||
$this->processReferences($definition->getMethodCalls());
|
||||
$this->processReferences($definition->getProperties());
|
||||
}
|
||||
|
||||
private function processReferences(array $arguments)
|
||||
{
|
||||
foreach ($arguments as $argument) {
|
||||
if (is_array($argument)) {
|
||||
$this->processReferences($argument);
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$this->processDefinition($argument);
|
||||
} elseif ($argument instanceof Reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $argument->getInvalidBehavior()) {
|
||||
$destId = (string) $argument;
|
||||
|
||||
if (!$this->container->has($destId)) {
|
||||
throw new ServiceNotFoundException($destId, $this->sourceId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
167
core/vendor/Symfony/Component/DependencyInjection/Compiler/CheckReferenceValidityPass.php
vendored
Normal file
167
core/vendor/Symfony/Component/DependencyInjection/Compiler/CheckReferenceValidityPass.php
vendored
Normal file
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ScopeCrossingInjectionException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ScopeWideningInjectionException;
|
||||
|
||||
/**
|
||||
* Checks the validity of references
|
||||
*
|
||||
* The following checks are performed by this pass:
|
||||
* - target definitions are not abstract
|
||||
* - target definitions are of equal or wider scope
|
||||
* - target definitions are in the same scope hierarchy
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class CheckReferenceValidityPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
private $currentId;
|
||||
private $currentDefinition;
|
||||
private $currentScope;
|
||||
private $currentScopeAncestors;
|
||||
private $currentScopeChildren;
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder to validate References.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
$children = $this->container->getScopeChildren();
|
||||
$ancestors = array();
|
||||
|
||||
$scopes = $this->container->getScopes();
|
||||
foreach ($scopes as $name => $parent) {
|
||||
$ancestors[$name] = array($parent);
|
||||
|
||||
while (isset($scopes[$parent])) {
|
||||
$ancestors[$name][] = $parent = $scopes[$parent];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->currentId = $id;
|
||||
$this->currentDefinition = $definition;
|
||||
$this->currentScope = $scope = $definition->getScope();
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER === $scope) {
|
||||
$this->currentScopeChildren = array_keys($scopes);
|
||||
$this->currentScopeAncestors = array();
|
||||
} elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
|
||||
$this->currentScopeChildren = $children[$scope];
|
||||
$this->currentScopeAncestors = $ancestors[$scope];
|
||||
}
|
||||
|
||||
$this->validateReferences($definition->getArguments());
|
||||
$this->validateReferences($definition->getMethodCalls());
|
||||
$this->validateReferences($definition->getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an array of References.
|
||||
*
|
||||
* @param array $arguments An array of Reference objects
|
||||
*
|
||||
* @throws RuntimeException when there is a reference to an abstract definition.
|
||||
*/
|
||||
private function validateReferences(array $arguments)
|
||||
{
|
||||
foreach ($arguments as $argument) {
|
||||
if (is_array($argument)) {
|
||||
$this->validateReferences($argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$targetDefinition = $this->getDefinition((string) $argument);
|
||||
|
||||
if (null !== $targetDefinition && $targetDefinition->isAbstract()) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'The definition "%s" has a reference to an abstract definition "%s". '
|
||||
.'Abstract definitions cannot be the target of references.',
|
||||
$this->currentId,
|
||||
$argument
|
||||
));
|
||||
}
|
||||
|
||||
$this->validateScope($argument, $targetDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the scope of a single Reference.
|
||||
*
|
||||
* @param Reference $reference
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @throws ScopeWideningInjectionException when the definition references a service of a narrower scope
|
||||
* @throws ScopeCrossingInjectionException when the definition references a service of another scope hierarchy
|
||||
*/
|
||||
private function validateScope(Reference $reference, Definition $definition = null)
|
||||
{
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $this->currentScope) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$reference->isStrict()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $definition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->currentScope === $scope = $definition->getScope()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$id = (string) $reference;
|
||||
|
||||
if (in_array($scope, $this->currentScopeChildren, true)) {
|
||||
throw new ScopeWideningInjectionException($this->currentId, $this->currentScope, $id, $scope);
|
||||
}
|
||||
|
||||
if (!in_array($scope, $this->currentScopeAncestors, true)) {
|
||||
throw new ScopeCrossingInjectionException($this->currentId, $this->currentScope, $id, $scope);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Definition given an id.
|
||||
*
|
||||
* @param string $id Definition identifier
|
||||
*
|
||||
* @return Definition
|
||||
*/
|
||||
private function getDefinition($id)
|
||||
{
|
||||
if (!$this->container->hasDefinition($id)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->container->getDefinition($id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
|
||||
/**
|
||||
* This class is used to remove circular dependencies between individual passes.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Compiler
|
||||
{
|
||||
private $passConfig;
|
||||
private $log;
|
||||
private $loggingFormatter;
|
||||
private $serviceReferenceGraph;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->passConfig = new PassConfig();
|
||||
$this->serviceReferenceGraph = new ServiceReferenceGraph();
|
||||
$this->loggingFormatter = new LoggingFormatter();
|
||||
$this->log = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PassConfig.
|
||||
*
|
||||
* @return PassConfig The PassConfig instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getPassConfig()
|
||||
{
|
||||
return $this->passConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ServiceReferenceGraph.
|
||||
*
|
||||
* @return ServiceReferenceGraph The ServiceReferenceGraph instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getServiceReferenceGraph()
|
||||
{
|
||||
return $this->serviceReferenceGraph;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the logging formatter which can be used by compilation passes.
|
||||
*
|
||||
* @return LoggingFormatter
|
||||
*/
|
||||
public function getLoggingFormatter()
|
||||
{
|
||||
return $this->loggingFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pass to the PassConfig.
|
||||
*
|
||||
* @param CompilerPassInterface $pass A compiler pass
|
||||
* @param string $type The type of the pass
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
|
||||
{
|
||||
$this->passConfig->addPass($pass, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a log message.
|
||||
*
|
||||
* @param string $string The log message
|
||||
*/
|
||||
public function addLogMessage($string)
|
||||
{
|
||||
$this->log[] = $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the log.
|
||||
*
|
||||
* @return array Log array
|
||||
*/
|
||||
public function getLog()
|
||||
{
|
||||
return $this->log;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the Compiler and process all Passes.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function compile(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($this->passConfig->getPasses() as $pass) {
|
||||
$pass->process($container);
|
||||
}
|
||||
}
|
||||
}
|
33
core/vendor/Symfony/Component/DependencyInjection/Compiler/CompilerPassInterface.php
vendored
Normal file
33
core/vendor/Symfony/Component/DependencyInjection/Compiler/CompilerPassInterface.php
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Interface that must be implemented by compilation passes
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* You can modify the container here before it is dumped to PHP code.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function process(ContainerBuilder $container);
|
||||
}
|
137
core/vendor/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php
vendored
Normal file
137
core/vendor/Symfony/Component/DependencyInjection/Compiler/InlineServiceDefinitionsPass.php
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Inline service definitions where this is possible.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||
{
|
||||
private $repeatedPass;
|
||||
private $graph;
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
private $currentId;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setRepeatedPass(RepeatedPass $repeatedPass)
|
||||
{
|
||||
$this->repeatedPass = $repeatedPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder for inline service definitions.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
$this->graph = $this->compiler->getServiceReferenceGraph();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$this->currentId = $id;
|
||||
|
||||
$definition->setArguments(
|
||||
$this->inlineArguments($container, $definition->getArguments())
|
||||
);
|
||||
|
||||
$definition->setMethodCalls(
|
||||
$this->inlineArguments($container, $definition->getMethodCalls())
|
||||
);
|
||||
|
||||
$definition->setProperties(
|
||||
$this->inlineArguments($container, $definition->getProperties())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes inline arguments.
|
||||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param array $arguments An array of arguments
|
||||
*/
|
||||
private function inlineArguments(ContainerBuilder $container, array $arguments)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if (is_array($argument)) {
|
||||
$arguments[$k] = $this->inlineArguments($container, $argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
if (!$container->hasDefinition($id = (string) $argument)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isInlinableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
||||
$this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
|
||||
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) {
|
||||
$arguments[$k] = $definition;
|
||||
} else {
|
||||
$arguments[$k] = clone $definition;
|
||||
}
|
||||
}
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
|
||||
$argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
|
||||
$argument->setProperties($this->inlineArguments($container, $argument->getProperties()));
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the definition is inlineable.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return Boolean If the definition is inlineable
|
||||
*/
|
||||
private function isInlinableDefinition(ContainerBuilder $container, $id, Definition $definition)
|
||||
{
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($definition->isPublic()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->graph->hasNode($id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$ids = array();
|
||||
foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
|
||||
$ids[] = $edge->getSourceNode()->getId();
|
||||
}
|
||||
|
||||
if (count(array_unique($ids)) > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $container->getDefinition(reset($ids))->getScope() === $definition->getScope();
|
||||
}
|
||||
}
|
46
core/vendor/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php
vendored
Normal file
46
core/vendor/Symfony/Component/DependencyInjection/Compiler/LoggingFormatter.php
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
|
||||
/**
|
||||
* Used to format logging messages during the compilation.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class LoggingFormatter
|
||||
{
|
||||
public function formatRemoveService(CompilerPassInterface $pass, $id, $reason)
|
||||
{
|
||||
return $this->format($pass, sprintf('Removed service "%s"; reason: %s', $id, $reason));
|
||||
}
|
||||
|
||||
public function formatInlineService(CompilerPassInterface $pass, $id, $target)
|
||||
{
|
||||
return $this->format($pass, sprintf('Inlined service "%s" to "%s".', $id, $target));
|
||||
}
|
||||
|
||||
public function formatUpdateReference(CompilerPassInterface $pass, $serviceId, $oldDestId, $newDestId)
|
||||
{
|
||||
return $this->format($pass, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $serviceId, $oldDestId, $newDestId));
|
||||
}
|
||||
|
||||
public function formatResolveInheritance(CompilerPassInterface $pass, $childId, $parentId)
|
||||
{
|
||||
return $this->format($pass, sprintf('Resolving inheritance for "%s" (parent: %s).', $childId, $parentId));
|
||||
}
|
||||
|
||||
public function format(CompilerPassInterface $pass, $message)
|
||||
{
|
||||
return sprintf('%s: %s', get_class($pass), $message);
|
||||
}
|
||||
}
|
51
core/vendor/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php
vendored
Normal file
51
core/vendor/Symfony/Component/DependencyInjection/Compiler/MergeExtensionConfigurationPass.php
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Merges extension configs into the container builder
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class MergeExtensionConfigurationPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$parameters = $container->getParameterBag()->all();
|
||||
$definitions = $container->getDefinitions();
|
||||
$aliases = $container->getAliases();
|
||||
|
||||
foreach ($container->getExtensions() as $name => $extension) {
|
||||
if (!$config = $container->getExtensionConfig($name)) {
|
||||
// this extension was not called
|
||||
continue;
|
||||
}
|
||||
$config = $container->getParameterBag()->resolveValue($config);
|
||||
|
||||
$tmpContainer = new ContainerBuilder($container->getParameterBag());
|
||||
$tmpContainer->addObjectResource($extension);
|
||||
|
||||
$extension->load($config, $tmpContainer);
|
||||
|
||||
$container->merge($tmpContainer);
|
||||
}
|
||||
|
||||
$container->addDefinitions($definitions);
|
||||
$container->addAliases($aliases);
|
||||
$container->getParameterBag()->add($parameters);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* Compiler Pass Configuration
|
||||
*
|
||||
* This class has a default configuration embedded.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class PassConfig
|
||||
{
|
||||
const TYPE_AFTER_REMOVING = 'afterRemoving';
|
||||
const TYPE_BEFORE_OPTIMIZATION = 'beforeOptimization';
|
||||
const TYPE_BEFORE_REMOVING = 'beforeRemoving';
|
||||
const TYPE_OPTIMIZE = 'optimization';
|
||||
const TYPE_REMOVE = 'removing';
|
||||
|
||||
private $mergePass;
|
||||
private $afterRemovingPasses;
|
||||
private $beforeOptimizationPasses;
|
||||
private $beforeRemovingPasses;
|
||||
private $optimizationPasses;
|
||||
private $removingPasses;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->mergePass = new MergeExtensionConfigurationPass();
|
||||
|
||||
$this->afterRemovingPasses = array();
|
||||
$this->beforeOptimizationPasses = array();
|
||||
$this->beforeRemovingPasses = array();
|
||||
|
||||
$this->optimizationPasses = array(
|
||||
new ResolveDefinitionTemplatesPass(),
|
||||
new ResolveParameterPlaceHoldersPass(),
|
||||
new CheckDefinitionValidityPass(),
|
||||
new ResolveReferencesToAliasesPass(),
|
||||
new ResolveInvalidReferencesPass(),
|
||||
new AnalyzeServiceReferencesPass(true),
|
||||
new CheckCircularReferencesPass(),
|
||||
new CheckReferenceValidityPass(),
|
||||
);
|
||||
|
||||
$this->removingPasses = array(
|
||||
new RemovePrivateAliasesPass(),
|
||||
new RemoveAbstractDefinitionsPass(),
|
||||
new ReplaceAliasByActualDefinitionPass(),
|
||||
new RepeatedPass(array(
|
||||
new AnalyzeServiceReferencesPass(),
|
||||
new InlineServiceDefinitionsPass(),
|
||||
new AnalyzeServiceReferencesPass(),
|
||||
new RemoveUnusedDefinitionsPass(),
|
||||
)),
|
||||
new CheckExceptionOnInvalidReferenceBehaviorPass(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all passes in order to be processed.
|
||||
*
|
||||
* @return array An array of all passes to process
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getPasses()
|
||||
{
|
||||
return array_merge(
|
||||
array($this->mergePass),
|
||||
$this->beforeOptimizationPasses,
|
||||
$this->optimizationPasses,
|
||||
$this->beforeRemovingPasses,
|
||||
$this->removingPasses,
|
||||
$this->afterRemovingPasses
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a pass.
|
||||
*
|
||||
* @param CompilerPassInterface $pass A Compiler pass
|
||||
* @param string $type The pass type
|
||||
*
|
||||
* @throws InvalidArgumentException when a pass type doesn't exist
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION)
|
||||
{
|
||||
$property = $type.'Passes';
|
||||
if (!isset($this->$property)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
|
||||
}
|
||||
|
||||
$passes = &$this->$property;
|
||||
$passes[] = $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the AfterRemoving pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getAfterRemovingPasses()
|
||||
{
|
||||
return $this->afterRemovingPasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the BeforeOptimization pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getBeforeOptimizationPasses()
|
||||
{
|
||||
return $this->beforeOptimizationPasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the BeforeRemoving pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getBeforeRemovingPasses()
|
||||
{
|
||||
return $this->beforeRemovingPasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the Optimization pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getOptimizationPasses()
|
||||
{
|
||||
return $this->optimizationPasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the Removing pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getRemovingPasses()
|
||||
{
|
||||
return $this->removingPasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the Merge pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getMergePass()
|
||||
{
|
||||
return $this->mergePass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Merge Pass.
|
||||
*
|
||||
* @param CompilerPassInterface $pass The merge pass
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setMergePass(CompilerPassInterface $pass)
|
||||
{
|
||||
$this->mergePass = $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the AfterRemoving passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setAfterRemovingPasses(array $passes)
|
||||
{
|
||||
$this->afterRemovingPasses = $passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the BeforeOptimization passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setBeforeOptimizationPasses(array $passes)
|
||||
{
|
||||
$this->beforeOptimizationPasses = $passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the BeforeRemoving passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setBeforeRemovingPasses(array $passes)
|
||||
{
|
||||
$this->beforeRemovingPasses = $passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Optimization passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setOptimizationPasses(array $passes)
|
||||
{
|
||||
$this->optimizationPasses = $passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Removing passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setRemovingPasses(array $passes)
|
||||
{
|
||||
$this->removingPasses = $passes;
|
||||
}
|
||||
}
|
39
core/vendor/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php
vendored
Normal file
39
core/vendor/Symfony/Component/DependencyInjection/Compiler/RemoveAbstractDefinitionsPass.php
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Removes abstract Definitions
|
||||
*
|
||||
*/
|
||||
class RemoveAbstractDefinitionsPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* Removes abstract definitions from the ContainerBuilder
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$compiler = $container->getCompiler();
|
||||
$formatter = $compiler->getLoggingFormatter();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isAbstract()) {
|
||||
$container->removeDefinition($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'abstract'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
core/vendor/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php
vendored
Normal file
44
core/vendor/Symfony/Component/DependencyInjection/Compiler/RemovePrivateAliasesPass.php
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Remove private aliases from the container. They were only used to establish
|
||||
* dependencies between services, and these dependencies have been resolved in
|
||||
* one of the previous passes.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RemovePrivateAliasesPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* Removes private aliases from the ContainerBuilder
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$compiler = $container->getCompiler();
|
||||
$formatter = $compiler->getLoggingFormatter();
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
if ($alias->isPublic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$container->removeAlias($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'private alias'));
|
||||
}
|
||||
}
|
||||
}
|
84
core/vendor/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php
vendored
Normal file
84
core/vendor/Symfony/Component/DependencyInjection/Compiler/RemoveUnusedDefinitionsPass.php
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Removes unused service definitions from the container.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RemoveUnusedDefinitionsPass implements RepeatablePassInterface
|
||||
{
|
||||
private $repeatedPass;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function setRepeatedPass(RepeatedPass $repeatedPass)
|
||||
{
|
||||
$this->repeatedPass = $repeatedPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder to remove unused definitions.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$compiler = $container->getCompiler();
|
||||
$formatter = $compiler->getLoggingFormatter();
|
||||
$graph = $compiler->getServiceReferenceGraph();
|
||||
|
||||
$hasChanged = false;
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isPublic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($graph->hasNode($id)) {
|
||||
$edges = $graph->getNode($id)->getInEdges();
|
||||
$referencingAliases = array();
|
||||
$sourceIds = array();
|
||||
foreach ($edges as $edge) {
|
||||
$node = $edge->getSourceNode();
|
||||
$sourceIds[] = $node->getId();
|
||||
|
||||
if ($node->isAlias()) {
|
||||
$referencingAliases[] = $node->getValue();
|
||||
}
|
||||
}
|
||||
$isReferenced = (count(array_unique($sourceIds)) - count($referencingAliases)) > 0;
|
||||
} else {
|
||||
$referencingAliases = array();
|
||||
$isReferenced = false;
|
||||
}
|
||||
|
||||
if (1 === count($referencingAliases) && false === $isReferenced) {
|
||||
$container->setDefinition((string) reset($referencingAliases), $definition);
|
||||
$definition->setPublic(true);
|
||||
$container->removeDefinition($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'replaces alias '.reset($referencingAliases)));
|
||||
} elseif (0 === count($referencingAliases) && false === $isReferenced) {
|
||||
$container->removeDefinition($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'unused'));
|
||||
$hasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasChanged) {
|
||||
$this->repeatedPass->setRepeat();
|
||||
}
|
||||
}
|
||||
}
|
28
core/vendor/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php
vendored
Normal file
28
core/vendor/Symfony/Component/DependencyInjection/Compiler/RepeatablePassInterface.php
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
/**
|
||||
* Interface that must be implemented by passes that are run as part of an
|
||||
* RepeatedPass.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface RepeatablePassInterface extends CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* Sets the RepeatedPass interface.
|
||||
*
|
||||
* @param RepeatedPass $repeatedPass
|
||||
*/
|
||||
function setRepeatedPass(RepeatedPass $repeatedPass);
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* A pass that might be run repeatedly.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RepeatedPass implements CompilerPassInterface
|
||||
{
|
||||
private $repeat;
|
||||
private $passes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $passes An array of RepeatablePassInterface objects
|
||||
* @throws InvalidArgumentException if a pass is not a RepeatablePassInterface instance
|
||||
*/
|
||||
public function __construct(array $passes)
|
||||
{
|
||||
foreach ($passes as $pass) {
|
||||
if (!$pass instanceof RepeatablePassInterface) {
|
||||
throw new InvalidArgumentException('$passes must be an array of RepeatablePassInterface.');
|
||||
}
|
||||
|
||||
$pass->setRepeatedPass($this);
|
||||
}
|
||||
|
||||
$this->passes = $passes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the repeatable passes that run more than once.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->repeat = false;
|
||||
foreach ($this->passes as $pass) {
|
||||
$pass->process($container);
|
||||
}
|
||||
|
||||
if ($this->repeat) {
|
||||
$this->process($container);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the pass should repeat
|
||||
*/
|
||||
public function setRepeat()
|
||||
{
|
||||
$this->repeat = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the passes
|
||||
*
|
||||
* @return array An array of RepeatablePassInterface objects
|
||||
*/
|
||||
public function getPasses()
|
||||
{
|
||||
return $this->passes;
|
||||
}
|
||||
}
|
116
core/vendor/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php
vendored
Normal file
116
core/vendor/Symfony/Component/DependencyInjection/Compiler/ReplaceAliasByActualDefinitionPass.php
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Replaces aliases with actual service definitions, effectively removing these
|
||||
* aliases.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
|
||||
{
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
private $sourceId;
|
||||
|
||||
/**
|
||||
* Process the Container to replace aliases with service definitions.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
$aliasId = (string) $alias;
|
||||
|
||||
$definition = $container->getDefinition($aliasId);
|
||||
|
||||
if ($definition->isPublic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$definition->setPublic(true);
|
||||
$container->setDefinition($id, $definition);
|
||||
$container->removeDefinition($aliasId);
|
||||
|
||||
$this->updateReferences($container, $aliasId, $id);
|
||||
|
||||
// we have to restart the process due to concurrent modification of
|
||||
// the container
|
||||
$this->process($container);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates references to remove aliases.
|
||||
*
|
||||
* @param ContainerBuilder $container The container
|
||||
* @param string $currentId The alias identifier being replaced
|
||||
* @param string $newId The id of the service the alias points to
|
||||
*/
|
||||
private function updateReferences($container, $currentId, $newId)
|
||||
{
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
if ($currentId === (string) $alias) {
|
||||
$container->setAlias($id, $newId);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$this->sourceId = $id;
|
||||
|
||||
$definition->setArguments(
|
||||
$this->updateArgumentReferences($definition->getArguments(), $currentId, $newId)
|
||||
);
|
||||
|
||||
$definition->setMethodCalls(
|
||||
$this->updateArgumentReferences($definition->getMethodCalls(), $currentId, $newId)
|
||||
);
|
||||
|
||||
$definition->setProperties(
|
||||
$this->updateArgumentReferences($definition->getProperties(), $currentId, $newId)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates argument references.
|
||||
*
|
||||
* @param array $arguments An array of Arguments
|
||||
* @param string $currentId The alias identifier
|
||||
* @param string $newId The identifier the alias points to
|
||||
*/
|
||||
private function updateArgumentReferences(array $arguments, $currentId, $newId)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if (is_array($argument)) {
|
||||
$arguments[$k] = $this->updateArgumentReferences($argument, $currentId, $newId);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
if ($currentId === (string) $argument) {
|
||||
$arguments[$k] = new Reference($newId, $argument->getInvalidBehavior());
|
||||
$this->compiler->addLogMessage($this->formatter->formatUpdateReference($this, $this->sourceId, $currentId, $newId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
}
|
148
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
vendored
Normal file
148
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveDefinitionTemplatesPass.php
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* This replaces all DefinitionDecorator instances with their equivalent fully
|
||||
* merged Definition instance.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
|
||||
/**
|
||||
* Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
|
||||
foreach (array_keys($container->getDefinitions()) as $id) {
|
||||
// yes, we are specifically fetching the definition from the
|
||||
// container to ensure we are not operating on stale data
|
||||
$definition = $container->getDefinition($id);
|
||||
if (!$definition instanceof DefinitionDecorator || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->resolveDefinition($id, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the definition
|
||||
*
|
||||
* @param string $id The definition identifier
|
||||
* @param DefinitionDecorator $definition
|
||||
*
|
||||
* @return Definition
|
||||
*/
|
||||
private function resolveDefinition($id, DefinitionDecorator $definition)
|
||||
{
|
||||
if (!$this->container->hasDefinition($parent = $definition->getParent())) {
|
||||
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $id));
|
||||
}
|
||||
|
||||
$parentDef = $this->container->getDefinition($parent);
|
||||
if ($parentDef instanceof DefinitionDecorator) {
|
||||
$parentDef = $this->resolveDefinition($parent, $parentDef);
|
||||
}
|
||||
|
||||
$this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $id, $parent));
|
||||
$def = new Definition();
|
||||
|
||||
// merge in parent definition
|
||||
// purposely ignored attributes: scope, abstract, tags
|
||||
$def->setClass($parentDef->getClass());
|
||||
$def->setArguments($parentDef->getArguments());
|
||||
$def->setMethodCalls($parentDef->getMethodCalls());
|
||||
$def->setProperties($parentDef->getProperties());
|
||||
$def->setFactoryClass($parentDef->getFactoryClass());
|
||||
$def->setFactoryMethod($parentDef->getFactoryMethod());
|
||||
$def->setFactoryService($parentDef->getFactoryService());
|
||||
$def->setConfigurator($parentDef->getConfigurator());
|
||||
$def->setFile($parentDef->getFile());
|
||||
$def->setPublic($parentDef->isPublic());
|
||||
|
||||
// overwrite with values specified in the decorator
|
||||
$changes = $definition->getChanges();
|
||||
if (isset($changes['class'])) {
|
||||
$def->setClass($definition->getClass());
|
||||
}
|
||||
if (isset($changes['factory_class'])) {
|
||||
$def->setFactoryClass($definition->getFactoryClass());
|
||||
}
|
||||
if (isset($changes['factory_method'])) {
|
||||
$def->setFactoryMethod($definition->getFactoryMethod());
|
||||
}
|
||||
if (isset($changes['factory_service'])) {
|
||||
$def->setFactoryService($definition->getFactoryService());
|
||||
}
|
||||
if (isset($changes['configurator'])) {
|
||||
$def->setConfigurator($definition->getConfigurator());
|
||||
}
|
||||
if (isset($changes['file'])) {
|
||||
$def->setFile($definition->getFile());
|
||||
}
|
||||
if (isset($changes['public'])) {
|
||||
$def->setPublic($definition->isPublic());
|
||||
}
|
||||
|
||||
// merge arguments
|
||||
foreach ($definition->getArguments() as $k => $v) {
|
||||
if (is_numeric($k)) {
|
||||
$def->addArgument($v);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 !== strpos($k, 'index_')) {
|
||||
throw new RuntimeException(sprintf('Invalid argument key "%s" found.', $k));
|
||||
}
|
||||
|
||||
$index = (integer) substr($k, strlen('index_'));
|
||||
$def->replaceArgument($index, $v);
|
||||
}
|
||||
|
||||
// merge properties
|
||||
foreach ($definition->getProperties() as $k => $v) {
|
||||
$def->setProperty($k, $v);
|
||||
}
|
||||
|
||||
// append method calls
|
||||
if (count($calls = $definition->getMethodCalls()) > 0) {
|
||||
$def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
|
||||
}
|
||||
|
||||
// these attributes are always taken from the child
|
||||
$def->setAbstract($definition->isAbstract());
|
||||
$def->setScope($definition->getScope());
|
||||
$def->setTags($definition->getTags());
|
||||
|
||||
// set new definition on container
|
||||
$this->container->setDefinition($id, $def);
|
||||
|
||||
return $def;
|
||||
}
|
||||
}
|
103
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php
vendored
Normal file
103
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveInvalidReferencesPass.php
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Emulates the invalid behavior if the reference is not found within the
|
||||
* container.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ResolveInvalidReferencesPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* Process the ContainerBuilder to resolve invalid references.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
foreach ($container->getDefinitions() as $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$definition->setArguments(
|
||||
$this->processArguments($definition->getArguments())
|
||||
);
|
||||
|
||||
$calls = array();
|
||||
foreach ($definition->getMethodCalls() as $call) {
|
||||
try {
|
||||
$calls[] = array($call[0], $this->processArguments($call[1], true));
|
||||
} catch (RuntimeException $ignore) {
|
||||
// this call is simply removed
|
||||
}
|
||||
}
|
||||
$definition->setMethodCalls($calls);
|
||||
|
||||
$properties = array();
|
||||
foreach ($definition->getProperties() as $name => $value) {
|
||||
try {
|
||||
$value = $this->processArguments(array($value), true);
|
||||
$properties[$name] = reset($value);
|
||||
} catch (RuntimeException $ignore) {
|
||||
// ignore property
|
||||
}
|
||||
}
|
||||
$definition->setProperties($properties);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes arguments to determine invalid references.
|
||||
*
|
||||
* @param array $arguments An array of Reference objects
|
||||
* @param Boolean $inMethodCall
|
||||
*/
|
||||
private function processArguments(array $arguments, $inMethodCall = false)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if (is_array($argument)) {
|
||||
$arguments[$k] = $this->processArguments($argument, $inMethodCall);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$id = (string) $argument;
|
||||
|
||||
$invalidBehavior = $argument->getInvalidBehavior();
|
||||
$exists = $this->container->has($id);
|
||||
|
||||
// resolve invalid behavior
|
||||
if ($exists && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
|
||||
$arguments[$k] = new Reference($id);
|
||||
} elseif (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
$arguments[$k] = null;
|
||||
} elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
if ($inMethodCall) {
|
||||
throw new RuntimeException('Method shouldn\'t be called.');
|
||||
}
|
||||
|
||||
$arguments[$k] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
}
|
61
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php
vendored
Normal file
61
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
|
||||
|
||||
/**
|
||||
* Resolves all parameter placeholders "%somevalue%" to their real values.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* Processes the ContainerBuilder to resolve parameter placeholders.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$parameterBag = $container->getParameterBag();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
try {
|
||||
$definition->setClass($parameterBag->resolveValue($definition->getClass()));
|
||||
$definition->setFile($parameterBag->resolveValue($definition->getFile()));
|
||||
$definition->setArguments($parameterBag->resolveValue($definition->getArguments()));
|
||||
|
||||
$calls = array();
|
||||
foreach ($definition->getMethodCalls() as $name => $arguments) {
|
||||
$calls[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($arguments);
|
||||
}
|
||||
$definition->setMethodCalls($calls);
|
||||
|
||||
$definition->setProperties($parameterBag->resolveValue($definition->getProperties()));
|
||||
} catch (ParameterNotFoundException $e) {
|
||||
$e->setSourceId($id);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$aliases = array();
|
||||
foreach ($container->getAliases() as $name => $target) {
|
||||
$aliases[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($target);
|
||||
}
|
||||
$container->setAliases($aliases);
|
||||
|
||||
$parameterBag->resolve();
|
||||
}
|
||||
}
|
93
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php
vendored
Normal file
93
core/vendor/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php
vendored
Normal file
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Replaces all references to aliases with references to the actual service.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder to replace references to aliases with actual service references.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
foreach ($container->getDefinitions() as $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$definition->setArguments($this->processArguments($definition->getArguments()));
|
||||
$definition->setMethodCalls($this->processArguments($definition->getMethodCalls()));
|
||||
$definition->setProperties($this->processArguments($definition->getProperties()));
|
||||
}
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
$aliasId = (string) $alias;
|
||||
if ($aliasId !== $defId = $this->getDefinitionId($aliasId)) {
|
||||
$container->setAlias($id, new Alias($defId, $alias->isPublic()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the arguments to replace aliases.
|
||||
*
|
||||
* @param array $arguments An array of References
|
||||
*
|
||||
* @return array An array of References
|
||||
*/
|
||||
private function processArguments(array $arguments)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if (is_array($argument)) {
|
||||
$arguments[$k] = $this->processArguments($argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$defId = $this->getDefinitionId($id = (string) $argument);
|
||||
|
||||
if ($defId !== $id) {
|
||||
$arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves an alias into a definition id.
|
||||
*
|
||||
* @param string $id The definition or alias id to resolve
|
||||
*
|
||||
* @return string The definition id with aliases resolved
|
||||
*/
|
||||
private function getDefinitionId($id)
|
||||
{
|
||||
while ($this->container->hasAlias($id)) {
|
||||
$id = (string) $this->container->getAlias($id);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
}
|
117
core/vendor/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php
vendored
Normal file
117
core/vendor/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraph.php
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* This is a directed graph of your services.
|
||||
*
|
||||
* This information can be used by your compiler passes instead of collecting
|
||||
* it themselves which improves performance quite a lot.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ServiceReferenceGraph
|
||||
{
|
||||
private $nodes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->nodes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the graph has a specific node.
|
||||
*
|
||||
* @param string $id Id to check
|
||||
*/
|
||||
public function hasNode($id)
|
||||
{
|
||||
return isset($this->nodes[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a node by identifier.
|
||||
*
|
||||
* @param string $id The id to retrieve
|
||||
*
|
||||
* @return ServiceReferenceGraphNode The node matching the supplied identifier
|
||||
*
|
||||
* @throws InvalidArgumentException if no node matches the supplied identifier
|
||||
*/
|
||||
public function getNode($id)
|
||||
{
|
||||
if (!isset($this->nodes[$id])) {
|
||||
throw new InvalidArgumentException(sprintf('There is no node with id "%s".', $id));
|
||||
}
|
||||
|
||||
return $this->nodes[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all nodes.
|
||||
*
|
||||
* @return array An array of all ServiceReferenceGraphNode objects
|
||||
*/
|
||||
public function getNodes()
|
||||
{
|
||||
return $this->nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all nodes.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->nodes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects 2 nodes together in the Graph.
|
||||
*
|
||||
* @param string $sourceId
|
||||
* @param string $sourceValue
|
||||
* @param string $destId
|
||||
* @param string $destValue
|
||||
* @param string $reference
|
||||
*/
|
||||
public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null)
|
||||
{
|
||||
$sourceNode = $this->createNode($sourceId, $sourceValue);
|
||||
$destNode = $this->createNode($destId, $destValue);
|
||||
$edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference);
|
||||
|
||||
$sourceNode->addOutEdge($edge);
|
||||
$destNode->addInEdge($edge);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a graph node.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $value
|
||||
*
|
||||
* @return ServiceReferenceGraphNode
|
||||
*/
|
||||
private function createNode($id, $value)
|
||||
{
|
||||
if (isset($this->nodes[$id]) && $this->nodes[$id]->getValue() === $value) {
|
||||
return $this->nodes[$id];
|
||||
}
|
||||
|
||||
return $this->nodes[$id] = new ServiceReferenceGraphNode($id, $value);
|
||||
}
|
||||
}
|
70
core/vendor/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php
vendored
Normal file
70
core/vendor/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphEdge.php
vendored
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
/**
|
||||
* Represents an edge in your service graph.
|
||||
*
|
||||
* Value is typically a reference.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ServiceReferenceGraphEdge
|
||||
{
|
||||
private $sourceNode;
|
||||
private $destNode;
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ServiceReferenceGraphNode $sourceNode
|
||||
* @param ServiceReferenceGraphNode $destNode
|
||||
* @param string $value
|
||||
*/
|
||||
public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null)
|
||||
{
|
||||
$this->sourceNode = $sourceNode;
|
||||
$this->destNode = $destNode;
|
||||
$this->value = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the edge
|
||||
*
|
||||
* @return ServiceReferenceGraphNode
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the source node
|
||||
*
|
||||
* @return ServiceReferenceGraphNode
|
||||
*/
|
||||
public function getSourceNode()
|
||||
{
|
||||
return $this->sourceNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the destination node
|
||||
*
|
||||
* @return ServiceReferenceGraphNode
|
||||
*/
|
||||
public function getDestNode()
|
||||
{
|
||||
return $this->destNode;
|
||||
}
|
||||
}
|
124
core/vendor/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php
vendored
Normal file
124
core/vendor/Symfony/Component/DependencyInjection/Compiler/ServiceReferenceGraphNode.php
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
|
||||
/**
|
||||
* Represents a node in your service graph.
|
||||
*
|
||||
* Value is typically a definition, or an alias.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ServiceReferenceGraphNode
|
||||
{
|
||||
private $id;
|
||||
private $inEdges;
|
||||
private $outEdges;
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $id The node identifier
|
||||
* @param mixed $value The node value
|
||||
*/
|
||||
public function __construct($id, $value)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->value = $value;
|
||||
$this->inEdges = array();
|
||||
$this->outEdges = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an in edge to this node.
|
||||
*
|
||||
* @param ServiceReferenceGraphEdge $edge
|
||||
*/
|
||||
public function addInEdge(ServiceReferenceGraphEdge $edge)
|
||||
{
|
||||
$this->inEdges[] = $edge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an out edge to this node.
|
||||
*
|
||||
* @param ServiceReferenceGraphEdge $edge
|
||||
*/
|
||||
public function addOutEdge(ServiceReferenceGraphEdge $edge)
|
||||
{
|
||||
$this->outEdges[] = $edge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value of this node is an Alias.
|
||||
*
|
||||
* @return Boolean True if the value is an Alias instance
|
||||
*/
|
||||
public function isAlias()
|
||||
{
|
||||
return $this->value instanceof Alias;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the value of this node is a Definition.
|
||||
*
|
||||
* @return Boolean True if the value is a Definition instance
|
||||
*/
|
||||
public function isDefinition()
|
||||
{
|
||||
return $this->value instanceof Definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identifier.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the in edges.
|
||||
*
|
||||
* @return array The in ServiceReferenceGraphEdge array
|
||||
*/
|
||||
public function getInEdges()
|
||||
{
|
||||
return $this->inEdges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the out edges.
|
||||
*
|
||||
* @return array The out ServiceReferenceGraphEdge array
|
||||
*/
|
||||
public function getOutEdges()
|
||||
{
|
||||
return $this->outEdges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of this Node
|
||||
*
|
||||
* @return mixed The value
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,455 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||
|
||||
/**
|
||||
* Container is a dependency injection container.
|
||||
*
|
||||
* It gives access to object instances (services).
|
||||
*
|
||||
* Services and parameters are simple key/pair stores.
|
||||
*
|
||||
* Parameter and service keys are case insensitive.
|
||||
*
|
||||
* A service id can contain lowercased letters, digits, underscores, and dots.
|
||||
* Underscores are used to separate words, and dots to group services
|
||||
* under namespaces:
|
||||
*
|
||||
* <ul>
|
||||
* <li>request</li>
|
||||
* <li>mysql_session_storage</li>
|
||||
* <li>symfony.mysql_session_storage</li>
|
||||
* </ul>
|
||||
*
|
||||
* A service can also be defined by creating a method named
|
||||
* getXXXService(), where XXX is the camelized version of the id:
|
||||
*
|
||||
* <ul>
|
||||
* <li>request -> getRequestService()</li>
|
||||
* <li>mysql_session_storage -> getMysqlSessionStorageService()</li>
|
||||
* <li>symfony.mysql_session_storage -> getSymfony_MysqlSessionStorageService()</li>
|
||||
* </ul>
|
||||
*
|
||||
* The container can have three possible behaviors when a service does not exist:
|
||||
*
|
||||
* * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default)
|
||||
* * NULL_ON_INVALID_REFERENCE: Returns null
|
||||
* * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference
|
||||
* (for instance, ignore a setter if the service does not exist)
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Container implements ContainerInterface
|
||||
{
|
||||
protected $parameterBag;
|
||||
protected $services;
|
||||
protected $scopes;
|
||||
protected $scopeChildren;
|
||||
protected $scopedServices;
|
||||
protected $scopeStacks;
|
||||
protected $loading = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ParameterBagInterface $parameterBag A ParameterBagInterface instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct(ParameterBagInterface $parameterBag = null)
|
||||
{
|
||||
$this->parameterBag = null === $parameterBag ? new ParameterBag() : $parameterBag;
|
||||
|
||||
$this->services = array();
|
||||
$this->scopes = array();
|
||||
$this->scopeChildren = array();
|
||||
$this->scopedServices = array();
|
||||
$this->scopeStacks = array();
|
||||
|
||||
$this->set('service_container', $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the container.
|
||||
*
|
||||
* This method does two things:
|
||||
*
|
||||
* * Parameter values are resolved;
|
||||
* * The parameter bag is frozen.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
$this->parameterBag->resolve();
|
||||
|
||||
$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the container parameter bag are frozen.
|
||||
*
|
||||
* @return Boolean true if the container parameter bag are frozen, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isFrozen()
|
||||
{
|
||||
return $this->parameterBag instanceof FrozenParameterBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the service container parameter bag.
|
||||
*
|
||||
* @return ParameterBagInterface A ParameterBagInterface instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getParameterBag()
|
||||
{
|
||||
return $this->parameterBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return mixed The parameter value
|
||||
*
|
||||
* @throws InvalidArgumentException if the parameter is not defined
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getParameter($name)
|
||||
{
|
||||
return $this->parameterBag->get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a parameter exists.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return Boolean The presence of parameter in container
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasParameter($name)
|
||||
{
|
||||
return $this->parameterBag->has($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
* @param mixed $value The parameter value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setParameter($name, $value)
|
||||
{
|
||||
$this->parameterBag->set($name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope of the service
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function set($id, $service, $scope = self::SCOPE_CONTAINER)
|
||||
{
|
||||
if (self::SCOPE_PROTOTYPE === $scope) {
|
||||
throw new InvalidArgumentException('You cannot set services of scope "prototype".');
|
||||
}
|
||||
|
||||
$id = strtolower($id);
|
||||
|
||||
if (self::SCOPE_CONTAINER !== $scope) {
|
||||
if (!isset($this->scopedServices[$scope])) {
|
||||
throw new RuntimeException('You cannot set services of inactive scopes.');
|
||||
}
|
||||
|
||||
$this->scopedServices[$scope][$id] = $service;
|
||||
}
|
||||
|
||||
$this->services[$id] = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given service is defined.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return Boolean true if the service is defined, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function has($id)
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
return isset($this->services[$id]) || method_exists($this, 'get'.strtr($id, array('_' => '', '.' => '_')).'Service');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a service.
|
||||
*
|
||||
* If a service is both defined through a set() method and
|
||||
* with a set*Service() method, the former has always precedence.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param integer $invalidBehavior The behavior when the service does not exist
|
||||
*
|
||||
* @return object The associated service
|
||||
*
|
||||
* @throws InvalidArgumentException if the service is not defined
|
||||
*
|
||||
* @see Reference
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
if (isset($this->services[$id])) {
|
||||
return $this->services[$id];
|
||||
}
|
||||
|
||||
if (isset($this->loading[$id])) {
|
||||
throw new ServiceCircularReferenceException($id, array_keys($this->loading));
|
||||
}
|
||||
|
||||
if (method_exists($this, $method = 'get'.strtr($id, array('_' => '', '.' => '_')).'Service')) {
|
||||
$this->loading[$id] = true;
|
||||
|
||||
try {
|
||||
$service = $this->$method();
|
||||
} catch (\Exception $e) {
|
||||
unset($this->loading[$id]);
|
||||
throw $e;
|
||||
}
|
||||
|
||||
unset($this->loading[$id]);
|
||||
|
||||
return $service;
|
||||
}
|
||||
|
||||
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
throw new ServiceNotFoundException($id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all service ids.
|
||||
*
|
||||
* @return array An array of all defined service ids
|
||||
*/
|
||||
public function getServiceIds()
|
||||
{
|
||||
$ids = array();
|
||||
$r = new \ReflectionClass($this);
|
||||
foreach ($r->getMethods() as $method) {
|
||||
if (preg_match('/^get(.+)Service$/', $method->getName(), $match)) {
|
||||
$ids[] = self::underscore($match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique(array_merge($ids, array_keys($this->services)));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when you enter a scope
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function enterScope($name)
|
||||
{
|
||||
if (!isset($this->scopes[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) {
|
||||
throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name]));
|
||||
}
|
||||
|
||||
// check if a scope of this name is already active, if so we need to
|
||||
// remove all services of this scope, and those of any of its child
|
||||
// scopes from the global services map
|
||||
if (isset($this->scopedServices[$name])) {
|
||||
$services = array($this->services, $name => $this->scopedServices[$name]);
|
||||
unset($this->scopedServices[$name]);
|
||||
|
||||
foreach ($this->scopeChildren[$name] as $child) {
|
||||
$services[$child] = $this->scopedServices[$child];
|
||||
unset($this->scopedServices[$child]);
|
||||
}
|
||||
|
||||
// update global map
|
||||
$this->services = call_user_func_array('array_diff_key', $services);
|
||||
array_shift($services);
|
||||
|
||||
// add stack entry for this scope so we can restore the removed services later
|
||||
if (!isset($this->scopeStacks[$name])) {
|
||||
$this->scopeStacks[$name] = new \SplStack();
|
||||
}
|
||||
$this->scopeStacks[$name]->push($services);
|
||||
}
|
||||
|
||||
$this->scopedServices[$name] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called to leave the current scope, and move back to the parent
|
||||
* scope.
|
||||
*
|
||||
* @param string $name The name of the scope to leave
|
||||
*
|
||||
* @throws InvalidArgumentException if the scope is not active
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function leaveScope($name)
|
||||
{
|
||||
if (!isset($this->scopedServices[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
|
||||
}
|
||||
|
||||
// remove all services of this scope, or any of its child scopes from
|
||||
// the global service map
|
||||
$services = array($this->services, $this->scopedServices[$name]);
|
||||
unset($this->scopedServices[$name]);
|
||||
foreach ($this->scopeChildren[$name] as $child) {
|
||||
if (!isset($this->scopedServices[$child])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$services[] = $this->scopedServices[$child];
|
||||
unset($this->scopedServices[$child]);
|
||||
}
|
||||
$this->services = call_user_func_array('array_diff_key', $services);
|
||||
|
||||
// check if we need to restore services of a previous scope of this type
|
||||
if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) {
|
||||
$services = $this->scopeStacks[$name]->pop();
|
||||
$this->scopedServices += $services;
|
||||
|
||||
array_unshift($services, $this->services);
|
||||
$this->services = call_user_func_array('array_merge', $services);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a scope to the container.
|
||||
*
|
||||
* @param ScopeInterface $scope
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addScope(ScopeInterface $scope)
|
||||
{
|
||||
$name = $scope->getName();
|
||||
$parentScope = $scope->getParentName();
|
||||
|
||||
if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
|
||||
}
|
||||
if (isset($this->scopes[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name));
|
||||
}
|
||||
if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) {
|
||||
throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope));
|
||||
}
|
||||
|
||||
$this->scopes[$name] = $parentScope;
|
||||
$this->scopeChildren[$name] = array();
|
||||
|
||||
// normalize the child relations
|
||||
while ($parentScope !== self::SCOPE_CONTAINER) {
|
||||
$this->scopeChildren[$parentScope][] = $name;
|
||||
$parentScope = $this->scopes[$parentScope];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container has a certain scope
|
||||
*
|
||||
* @param string $name The name of the scope
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasScope($name)
|
||||
{
|
||||
return isset($this->scopes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this scope is currently active
|
||||
*
|
||||
* This does not actually check if the passed scope actually exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isScopeActive($name)
|
||||
{
|
||||
return isset($this->scopedServices[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Camelizes a string.
|
||||
*
|
||||
* @param string $id A string to camelize
|
||||
*
|
||||
* @return string The camelized string
|
||||
*/
|
||||
static public function camelize($id)
|
||||
{
|
||||
return preg_replace_callback('/(^|_|\.)+(.)/', function ($match) { return ('.' === $match[1] ? '_' : '').strtoupper($match[2]); }, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* A string to underscore.
|
||||
*
|
||||
* @param string $id The string to underscore
|
||||
*
|
||||
* @return string The underscored string
|
||||
*/
|
||||
static public function underscore($id)
|
||||
{
|
||||
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), strtr($id, '_', '.')));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* A simple implementation of ContainerAwareInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class ContainerAware implements ContainerAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var ContainerInterface
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Sets the Container associated with this Controller.
|
||||
*
|
||||
* @param ContainerInterface $container A ContainerInterface instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setContainer(ContainerInterface $container = null)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
}
|
31
core/vendor/Symfony/Component/DependencyInjection/ContainerAwareInterface.php
vendored
Normal file
31
core/vendor/Symfony/Component/DependencyInjection/ContainerAwareInterface.php
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* ContainerAwareInterface should be implemented by classes that depends on a Container.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface ContainerAwareInterface
|
||||
{
|
||||
/**
|
||||
* Sets the Container.
|
||||
*
|
||||
* @param ContainerInterface $container A ContainerInterface instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function setContainer(ContainerInterface $container = null);
|
||||
}
|
|
@ -0,0 +1,867 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\Compiler;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
||||
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
|
||||
/**
|
||||
* ContainerBuilder is a DI container that provides an API to easily describe services.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class ContainerBuilder extends Container implements TaggedContainerInterface
|
||||
{
|
||||
private $extensions = array();
|
||||
private $extensionsByNs = array();
|
||||
private $definitions = array();
|
||||
private $aliases = array();
|
||||
private $resources = array();
|
||||
private $extensionConfigs = array();
|
||||
private $compiler;
|
||||
|
||||
/**
|
||||
* Registers an extension.
|
||||
*
|
||||
* @param ExtensionInterface $extension An extension instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function registerExtension(ExtensionInterface $extension)
|
||||
{
|
||||
$this->extensions[$extension->getAlias()] = $extension;
|
||||
|
||||
if (false !== $extension->getNamespace()) {
|
||||
$this->extensionsByNs[$extension->getNamespace()] = $extension;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an extension by alias or namespace.
|
||||
*
|
||||
* @param string $name An alias or a namespace
|
||||
*
|
||||
* @return ExtensionInterface An extension instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getExtension($name)
|
||||
{
|
||||
if (isset($this->extensions[$name])) {
|
||||
return $this->extensions[$name];
|
||||
}
|
||||
|
||||
if (isset($this->extensionsByNs[$name])) {
|
||||
return $this->extensionsByNs[$name];
|
||||
}
|
||||
|
||||
throw new LogicException(sprintf('Container extension "%s" is not registered', $name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered extensions.
|
||||
*
|
||||
* @return array An array of ExtensionInterface
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getExtensions()
|
||||
{
|
||||
return $this->extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we have an extension.
|
||||
*
|
||||
* @param string $name The name of the extension
|
||||
*
|
||||
* @return Boolean If the extension exists
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasExtension($name)
|
||||
{
|
||||
return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of resources loaded to build this configuration.
|
||||
*
|
||||
* @return ResourceInterface[] An array of resources
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getResources()
|
||||
{
|
||||
return array_unique($this->resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a resource for this configuration.
|
||||
*
|
||||
* @param ResourceInterface $resource A resource instance
|
||||
*
|
||||
* @return ContainerBuilder The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addResource(ResourceInterface $resource)
|
||||
{
|
||||
$this->resources[] = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setResources(array $resources)
|
||||
{
|
||||
$this->resources = $resources;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the object class hierarchy as resources.
|
||||
*
|
||||
* @param object $object An object instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addObjectResource($object)
|
||||
{
|
||||
$parent = new \ReflectionObject($object);
|
||||
do {
|
||||
$this->addResource(new FileResource($parent->getFileName()));
|
||||
} while ($parent = $parent->getParentClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration for an extension.
|
||||
*
|
||||
* @param string $extension The extension alias or namespace
|
||||
* @param array $values An array of values that customizes the extension
|
||||
*
|
||||
* @return ContainerBuilder The current instance
|
||||
* @throws BadMethodCallException When this ContainerBuilder is frozen
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function loadFromExtension($extension, array $values = array())
|
||||
{
|
||||
if ($this->isFrozen()) {
|
||||
throw new BadMethodCallException('Cannot load from an extension on a frozen container.');
|
||||
}
|
||||
|
||||
$namespace = $this->getExtension($extension)->getAlias();
|
||||
|
||||
$this->extensionConfigs[$namespace][] = $values;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a compiler pass.
|
||||
*
|
||||
* @param CompilerPassInterface $pass A compiler pass
|
||||
* @param string $type The type of compiler pass
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
|
||||
{
|
||||
if (null === $this->compiler) {
|
||||
$this->compiler = new Compiler();
|
||||
}
|
||||
|
||||
$this->compiler->addPass($pass, $type);
|
||||
|
||||
$this->addObjectResource($pass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the compiler pass config which can then be modified.
|
||||
*
|
||||
* @return PassConfig The compiler pass config
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getCompilerPassConfig()
|
||||
{
|
||||
if (null === $this->compiler) {
|
||||
$this->compiler = new Compiler();
|
||||
}
|
||||
|
||||
return $this->compiler->getPassConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the compiler.
|
||||
*
|
||||
* @return Compiler The compiler
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getCompiler()
|
||||
{
|
||||
if (null === $this->compiler) {
|
||||
$this->compiler = new Compiler();
|
||||
}
|
||||
|
||||
return $this->compiler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Scopes.
|
||||
*
|
||||
* @return array An array of scopes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getScopes()
|
||||
{
|
||||
return $this->scopes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all Scope children.
|
||||
*
|
||||
* @return array An array of scope children.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getScopeChildren()
|
||||
{
|
||||
return $this->scopeChildren;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope
|
||||
*
|
||||
* @throws BadMethodCallException When this ContainerBuilder is frozen
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function set($id, $service, $scope = self::SCOPE_CONTAINER)
|
||||
{
|
||||
if ($this->isFrozen()) {
|
||||
throw new BadMethodCallException('Setting service on a frozen container is not allowed');
|
||||
}
|
||||
|
||||
$id = strtolower($id);
|
||||
|
||||
unset($this->definitions[$id], $this->aliases[$id]);
|
||||
|
||||
parent::set($id, $service, $scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a service definition.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function removeDefinition($id)
|
||||
{
|
||||
unset($this->definitions[strtolower($id)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given service is defined.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return Boolean true if the service is defined, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function has($id)
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
return isset($this->definitions[$id]) || isset($this->aliases[$id]) || parent::has($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a service.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param integer $invalidBehavior The behavior when the service does not exist
|
||||
*
|
||||
* @return object The associated service
|
||||
*
|
||||
* @throws InvalidArgumentException if the service is not defined
|
||||
* @throws LogicException if the service has a circular reference to itself
|
||||
*
|
||||
* @see Reference
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
try {
|
||||
return parent::get($id, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
if (isset($this->loading[$id])) {
|
||||
throw new LogicException(sprintf('The service "%s" has a circular reference to itself.', $id), 0, $e);
|
||||
}
|
||||
|
||||
if (!$this->hasDefinition($id) && isset($this->aliases[$id])) {
|
||||
return $this->get($this->aliases[$id]);
|
||||
}
|
||||
|
||||
try {
|
||||
$definition = $this->getDefinition($id);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->loading[$id] = true;
|
||||
|
||||
$service = $this->createService($definition, $id);
|
||||
|
||||
unset($this->loading[$id]);
|
||||
|
||||
return $service;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges a ContainerBuilder with the current ContainerBuilder configuration.
|
||||
*
|
||||
* Service definitions overrides the current defined ones.
|
||||
*
|
||||
* But for parameters, they are overridden by the current ones. It allows
|
||||
* the parameters passed to the container constructor to have precedence
|
||||
* over the loaded ones.
|
||||
*
|
||||
* $container = new ContainerBuilder(array('foo' => 'bar'));
|
||||
* $loader = new LoaderXXX($container);
|
||||
* $loader->load('resource_name');
|
||||
* $container->register('foo', new stdClass());
|
||||
*
|
||||
* In the above example, even if the loaded resource defines a foo
|
||||
* parameter, the value will still be 'bar' as defined in the ContainerBuilder
|
||||
* constructor.
|
||||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder instance to merge.
|
||||
*
|
||||
*
|
||||
* @throws BadMethodCallException When this ContainerBuilder is frozen
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function merge(ContainerBuilder $container)
|
||||
{
|
||||
if ($this->isFrozen()) {
|
||||
throw new BadMethodCallException('Cannot merge on a frozen container.');
|
||||
}
|
||||
|
||||
$this->addDefinitions($container->getDefinitions());
|
||||
$this->addAliases($container->getAliases());
|
||||
$this->getParameterBag()->add($container->getParameterBag()->all());
|
||||
|
||||
foreach ($container->getResources() as $resource) {
|
||||
$this->addResource($resource);
|
||||
}
|
||||
|
||||
foreach ($this->extensions as $name => $extension) {
|
||||
if (!isset($this->extensionConfigs[$name])) {
|
||||
$this->extensionConfigs[$name] = array();
|
||||
}
|
||||
|
||||
$this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration array for the given extension.
|
||||
*
|
||||
* @param string $name The name of the extension
|
||||
*
|
||||
* @return array An array of configuration
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getExtensionConfig($name)
|
||||
{
|
||||
if (!isset($this->extensionConfigs[$name])) {
|
||||
$this->extensionConfigs[$name] = array();
|
||||
}
|
||||
|
||||
return $this->extensionConfigs[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the container.
|
||||
*
|
||||
* This method passes the container to compiler
|
||||
* passes whose job is to manipulate and optimize
|
||||
* the container.
|
||||
*
|
||||
* The main compiler passes roughly do four things:
|
||||
*
|
||||
* * The extension configurations are merged;
|
||||
* * Parameter values are resolved;
|
||||
* * The parameter bag is frozen;
|
||||
* * Extension loading is disabled.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function compile()
|
||||
{
|
||||
if (null === $this->compiler) {
|
||||
$this->compiler = new Compiler();
|
||||
}
|
||||
|
||||
foreach ($this->compiler->getPassConfig()->getPasses() as $pass) {
|
||||
$this->addObjectResource($pass);
|
||||
}
|
||||
|
||||
$this->compiler->compile($this);
|
||||
|
||||
$this->extensionConfigs = array();
|
||||
|
||||
parent::compile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all service ids.
|
||||
*
|
||||
* @return array An array of all defined service ids
|
||||
*/
|
||||
public function getServiceIds()
|
||||
{
|
||||
return array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliases), parent::getServiceIds()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the service aliases.
|
||||
*
|
||||
* @param array $aliases An array of aliases
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addAliases(array $aliases)
|
||||
{
|
||||
foreach ($aliases as $alias => $id) {
|
||||
$this->setAlias($alias, $id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service aliases.
|
||||
*
|
||||
* @param array $aliases An array of service definitions
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setAliases(array $aliases)
|
||||
{
|
||||
$this->aliases = array();
|
||||
$this->addAliases($aliases);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an alias for an existing service.
|
||||
*
|
||||
* @param string $alias The alias to create
|
||||
* @param mixed $id The service to alias
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setAlias($alias, $id)
|
||||
{
|
||||
$alias = strtolower($alias);
|
||||
|
||||
if (is_string($id)) {
|
||||
$id = new Alias($id);
|
||||
} elseif (!$id instanceof Alias) {
|
||||
throw new InvalidArgumentException('$id must be a string, or an Alias object.');
|
||||
}
|
||||
|
||||
if ($alias === strtolower($id)) {
|
||||
throw new InvalidArgumentException('An alias can not reference itself, got a circular reference on "'.$alias.'".');
|
||||
}
|
||||
|
||||
unset($this->definitions[$alias]);
|
||||
|
||||
$this->aliases[$alias] = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an alias.
|
||||
*
|
||||
* @param string $alias The alias to remove
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function removeAlias($alias)
|
||||
{
|
||||
unset($this->aliases[strtolower($alias)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if an alias exists under the given identifier.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return Boolean true if the alias exists, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasAlias($id)
|
||||
{
|
||||
return isset($this->aliases[strtolower($id)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all defined aliases.
|
||||
*
|
||||
* @return array An array of aliases
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getAliases()
|
||||
{
|
||||
return $this->aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an alias.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return string The aliased service identifier
|
||||
*
|
||||
* @throws InvalidArgumentException if the alias does not exist
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getAlias($id)
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
if (!$this->hasAlias($id)) {
|
||||
throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
|
||||
}
|
||||
|
||||
return $this->aliases[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service definition.
|
||||
*
|
||||
* This methods allows for simple registration of service definition
|
||||
* with a fluid interface.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param string $class The service class
|
||||
*
|
||||
* @return Definition A Definition instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function register($id, $class = null)
|
||||
{
|
||||
return $this->setDefinition(strtolower($id), new Definition($class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the service definitions.
|
||||
*
|
||||
* @param Definition[] $definitions An array of service definitions
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addDefinitions(array $definitions)
|
||||
{
|
||||
foreach ($definitions as $id => $definition) {
|
||||
$this->setDefinition($id, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service definitions.
|
||||
*
|
||||
* @param array $definitions An array of service definitions
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setDefinitions(array $definitions)
|
||||
{
|
||||
$this->definitions = array();
|
||||
$this->addDefinitions($definitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all service definitions.
|
||||
*
|
||||
* @return array An array of Definition instances
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getDefinitions()
|
||||
{
|
||||
return $this->definitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a service definition.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param Definition $definition A Definition instance
|
||||
*
|
||||
* @throws BadMethodCallException When this ContainerBuilder is frozen
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setDefinition($id, Definition $definition)
|
||||
{
|
||||
if ($this->isFrozen()) {
|
||||
throw new BadMethodCallException('Adding definition to a frozen container is not allowed');
|
||||
}
|
||||
|
||||
$id = strtolower($id);
|
||||
|
||||
unset($this->aliases[$id]);
|
||||
|
||||
return $this->definitions[$id] = $definition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a service definition exists under the given identifier.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return Boolean true if the service definition exists, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasDefinition($id)
|
||||
{
|
||||
return array_key_exists(strtolower($id), $this->definitions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a service definition.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return Definition A Definition instance
|
||||
*
|
||||
* @throws InvalidArgumentException if the service definition does not exist
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getDefinition($id)
|
||||
{
|
||||
$id = strtolower($id);
|
||||
|
||||
if (!$this->hasDefinition($id)) {
|
||||
throw new InvalidArgumentException(sprintf('The service definition "%s" does not exist.', $id));
|
||||
}
|
||||
|
||||
return $this->definitions[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a service definition by id or alias.
|
||||
*
|
||||
* The method "unaliases" recursively to return a Definition instance.
|
||||
*
|
||||
* @param string $id The service identifier or alias
|
||||
*
|
||||
* @return Definition A Definition instance
|
||||
*
|
||||
* @throws InvalidArgumentException if the service definition does not exist
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function findDefinition($id)
|
||||
{
|
||||
while ($this->hasAlias($id)) {
|
||||
$id = (string) $this->getAlias($id);
|
||||
}
|
||||
|
||||
return $this->getDefinition($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a service for a service definition.
|
||||
*
|
||||
* @param Definition $definition A service definition instance
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return object The service described by the service definition
|
||||
*
|
||||
* @throws RuntimeException When factory specification is incomplete or scope is inactive
|
||||
* @throws InvalidArgumentException When configure callable is not callable
|
||||
*/
|
||||
private function createService(Definition $definition, $id)
|
||||
{
|
||||
if (null !== $definition->getFile()) {
|
||||
require_once $this->getParameterBag()->resolveValue($definition->getFile());
|
||||
}
|
||||
|
||||
$arguments = $this->resolveServices($this->getParameterBag()->resolveValue($definition->getArguments()));
|
||||
|
||||
if (null !== $definition->getFactoryMethod()) {
|
||||
if (null !== $definition->getFactoryClass()) {
|
||||
$factory = $this->getParameterBag()->resolveValue($definition->getFactoryClass());
|
||||
} elseif (null !== $definition->getFactoryService()) {
|
||||
$factory = $this->get($this->getParameterBag()->resolveValue($definition->getFactoryService()));
|
||||
} else {
|
||||
throw new RuntimeException('Cannot create service from factory method without a factory service or factory class.');
|
||||
}
|
||||
|
||||
$service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments);
|
||||
} else {
|
||||
$r = new \ReflectionClass($this->getParameterBag()->resolveValue($definition->getClass()));
|
||||
|
||||
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
|
||||
}
|
||||
|
||||
if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
|
||||
if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
|
||||
throw new RuntimeException('You tried to create a service of an inactive scope.');
|
||||
}
|
||||
|
||||
$this->services[$lowerId = strtolower($id)] = $service;
|
||||
|
||||
if (self::SCOPE_CONTAINER !== $scope) {
|
||||
$this->scopedServices[$scope][$lowerId] = $service;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($definition->getMethodCalls() as $call) {
|
||||
$services = self::getServiceConditionals($call[1]);
|
||||
|
||||
$ok = true;
|
||||
foreach ($services as $s) {
|
||||
if (!$this->has($s)) {
|
||||
$ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ok) {
|
||||
call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->resolveValue($call[1])));
|
||||
}
|
||||
}
|
||||
|
||||
$properties = $this->resolveServices($this->getParameterBag()->resolveValue($definition->getProperties()));
|
||||
foreach ($properties as $name => $value) {
|
||||
$service->$name = $value;
|
||||
}
|
||||
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
if (is_array($callable) && is_object($callable[0]) && $callable[0] instanceof Reference) {
|
||||
$callable[0] = $this->get((string) $callable[0]);
|
||||
} elseif (is_array($callable)) {
|
||||
$callable[0] = $this->getParameterBag()->resolveValue($callable[0]);
|
||||
}
|
||||
|
||||
if (!is_callable($callable)) {
|
||||
throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service)));
|
||||
}
|
||||
|
||||
call_user_func($callable, $service);
|
||||
}
|
||||
|
||||
return $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces service references by the real service instance.
|
||||
*
|
||||
* @param mixed $value A value
|
||||
*
|
||||
* @return mixed The same value with all service references replaced by the real service instances
|
||||
*/
|
||||
public function resolveServices($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
foreach ($value as &$v) {
|
||||
$v = $this->resolveServices($v);
|
||||
}
|
||||
} elseif (is_object($value) && $value instanceof Reference) {
|
||||
$value = $this->get((string) $value, $value->getInvalidBehavior());
|
||||
} elseif (is_object($value) && $value instanceof Definition) {
|
||||
$value = $this->createService($value, null);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns service ids for a given tag.
|
||||
*
|
||||
* @param string $name The tag name
|
||||
*
|
||||
* @return array An array of tags
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function findTaggedServiceIds($name)
|
||||
{
|
||||
$tags = array();
|
||||
foreach ($this->getDefinitions() as $id => $definition) {
|
||||
if ($definition->getTag($name)) {
|
||||
$tags[$id] = $definition->getTag($name);
|
||||
}
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Service Conditionals.
|
||||
*
|
||||
* @param mixed $value An array of conditionals to return.
|
||||
*
|
||||
* @return array An array of Service conditionals
|
||||
*/
|
||||
static public function getServiceConditionals($value)
|
||||
{
|
||||
$services = array();
|
||||
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $v) {
|
||||
$services = array_unique(array_merge($services, self::getServiceConditionals($v)));
|
||||
}
|
||||
} elseif (is_object($value) && $value instanceof Reference && $value->getInvalidBehavior() === ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
|
||||
$services[] = (string) $value;
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* ContainerInterface is the interface implemented by service container classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface ContainerInterface
|
||||
{
|
||||
const EXCEPTION_ON_INVALID_REFERENCE = 1;
|
||||
const NULL_ON_INVALID_REFERENCE = 2;
|
||||
const IGNORE_ON_INVALID_REFERENCE = 3;
|
||||
const SCOPE_CONTAINER = 'container';
|
||||
const SCOPE_PROTOTYPE = 'prototype';
|
||||
|
||||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope of the service
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function set($id, $service, $scope = self::SCOPE_CONTAINER);
|
||||
|
||||
/**
|
||||
* Gets a service.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param int $invalidBehavior The behavior when the service does not exist
|
||||
*
|
||||
* @return object The associated service
|
||||
*
|
||||
* @throws InvalidArgumentException if the service is not defined
|
||||
*
|
||||
* @see Reference
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE);
|
||||
|
||||
/**
|
||||
* Returns true if the given service is defined.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
*
|
||||
* @return Boolean true if the service is defined, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function has($id);
|
||||
|
||||
/**
|
||||
* Gets a parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return mixed The parameter value
|
||||
*
|
||||
* @throws InvalidArgumentException if the parameter is not defined
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function getParameter($name);
|
||||
|
||||
/**
|
||||
* Checks if a parameter exists.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return Boolean The presence of parameter in container
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function hasParameter($name);
|
||||
|
||||
/**
|
||||
* Sets a parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
* @param mixed $value The parameter value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function setParameter($name, $value);
|
||||
|
||||
/**
|
||||
* Enters the given scope
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function enterScope($name);
|
||||
|
||||
/**
|
||||
* Leaves the current scope, and re-enters the parent scope
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function leaveScope($name);
|
||||
|
||||
/**
|
||||
* Adds a scope to the container
|
||||
*
|
||||
* @param ScopeInterface $scope
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function addScope(ScopeInterface $scope);
|
||||
|
||||
/**
|
||||
* Whether this container has the given scope
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function hasScope($name);
|
||||
|
||||
/**
|
||||
* Determines whether the given scope is currently active.
|
||||
*
|
||||
* It does however not check if the scope actually exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function isScopeActive($name);
|
||||
}
|
|
@ -0,0 +1,639 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
|
||||
|
||||
/**
|
||||
* Definition represents a service definition.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Definition
|
||||
{
|
||||
private $class;
|
||||
private $file;
|
||||
private $factoryClass;
|
||||
private $factoryMethod;
|
||||
private $factoryService;
|
||||
private $scope;
|
||||
private $properties;
|
||||
private $calls;
|
||||
private $configurator;
|
||||
private $tags;
|
||||
private $public;
|
||||
private $synthetic;
|
||||
private $abstract;
|
||||
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $class The service class
|
||||
* @param array $arguments An array of arguments to pass to the service constructor
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($class = null, array $arguments = array())
|
||||
{
|
||||
$this->class = $class;
|
||||
$this->arguments = $arguments;
|
||||
$this->calls = array();
|
||||
$this->scope = ContainerInterface::SCOPE_CONTAINER;
|
||||
$this->tags = array();
|
||||
$this->public = true;
|
||||
$this->synthetic = false;
|
||||
$this->abstract = false;
|
||||
$this->properties = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the class that acts as a factory using the factory method,
|
||||
* which will be invoked statically.
|
||||
*
|
||||
* @param string $factoryClass The factory class name
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFactoryClass($factoryClass)
|
||||
{
|
||||
$this->factoryClass = $factoryClass;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory class.
|
||||
*
|
||||
* @return string The factory class name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getFactoryClass()
|
||||
{
|
||||
return $this->factoryClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the factory method able to create an instance of this class.
|
||||
*
|
||||
* @param string $factoryMethod The factory method name
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFactoryMethod($factoryMethod)
|
||||
{
|
||||
$this->factoryMethod = $factoryMethod;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory method.
|
||||
*
|
||||
* @return string The factory method name
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getFactoryMethod()
|
||||
{
|
||||
return $this->factoryMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the service that acts as a factory using the factory method.
|
||||
*
|
||||
* @param string $factoryService The factory service id
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFactoryService($factoryService)
|
||||
{
|
||||
$this->factoryService = $factoryService;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory service id.
|
||||
*
|
||||
* @return string The factory service id
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getFactoryService()
|
||||
{
|
||||
return $this->factoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service class.
|
||||
*
|
||||
* @param string $class The service class
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service class.
|
||||
*
|
||||
* @return string The service class
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the arguments to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param array $arguments An array of arguments
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setArguments(array $arguments)
|
||||
{
|
||||
$this->arguments = $arguments;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function setProperties(array $properties)
|
||||
{
|
||||
$this->properties = $properties;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function getProperties()
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function setProperty($name, $value)
|
||||
{
|
||||
$this->properties[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param mixed $argument An argument
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addArgument($argument)
|
||||
{
|
||||
$this->arguments[] = $argument;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific argument
|
||||
*
|
||||
* @param integer $index
|
||||
* @param mixed $argument
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function replaceArgument($index, $argument)
|
||||
{
|
||||
if ($index < 0 || $index > count($this->arguments) - 1) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
|
||||
}
|
||||
|
||||
$this->arguments[$index] = $argument;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the arguments to pass to the service constructor/factory method.
|
||||
*
|
||||
* @return array The array of arguments
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getArguments()
|
||||
{
|
||||
return $this->arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param integer $index
|
||||
*
|
||||
* @return mixed The argument value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getArgument($index)
|
||||
{
|
||||
if ($index < 0 || $index > count($this->arguments) - 1) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1));
|
||||
}
|
||||
|
||||
return $this->arguments[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the methods to call after service initialization.
|
||||
*
|
||||
* @param array $calls An array of method calls
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setMethodCalls(array $calls = array())
|
||||
{
|
||||
$this->calls = array();
|
||||
foreach ($calls as $call) {
|
||||
$this->addMethodCall($call[0], $call[1]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a method to call after service initialization.
|
||||
*
|
||||
* @param string $method The method name to call
|
||||
* @param array $arguments An array of arguments to pass to the method call
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @throws InvalidArgumentException on empty $method param
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addMethodCall($method, array $arguments = array())
|
||||
{
|
||||
if (empty($method)) {
|
||||
throw new InvalidArgumentException(sprintf('Method name cannot be empty.'));
|
||||
}
|
||||
$this->calls[] = array($method, $arguments);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a method to call after service initialization.
|
||||
*
|
||||
* @param string $method The method name to remove
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function removeMethodCall($method)
|
||||
{
|
||||
foreach ($this->calls as $i => $call) {
|
||||
if ($call[0] === $method) {
|
||||
unset($this->calls[$i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current definition has a given method to call after service initialization.
|
||||
*
|
||||
* @param string $method The method name to search for
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasMethodCall($method)
|
||||
{
|
||||
foreach ($this->calls as $call) {
|
||||
if ($call[0] === $method) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the methods to call after service initialization.
|
||||
*
|
||||
* @return array An array of method calls
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getMethodCalls()
|
||||
{
|
||||
return $this->calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets tags for this definition
|
||||
*
|
||||
* @param array $tags
|
||||
*
|
||||
* @return Definition the current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setTags(array $tags)
|
||||
{
|
||||
$this->tags = $tags;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all tags.
|
||||
*
|
||||
* @return array An array of tags
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getTags()
|
||||
{
|
||||
return $this->tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a tag by name.
|
||||
*
|
||||
* @param string $name The tag name
|
||||
*
|
||||
* @return array An array of attributes
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getTag($name)
|
||||
{
|
||||
return isset($this->tags[$name]) ? $this->tags[$name] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a tag for this definition.
|
||||
*
|
||||
* @param string $name The tag name
|
||||
* @param array $attributes An array of attributes
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function addTag($name, array $attributes = array())
|
||||
{
|
||||
$this->tags[$name][] = $attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this definition has a tag with the given name
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function hasTag($name)
|
||||
{
|
||||
return isset($this->tags[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the tags for this definition.
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function clearTags()
|
||||
{
|
||||
$this->tags = array();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a file to require before creating the service.
|
||||
*
|
||||
* @param string $file A full pathname to include
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFile($file)
|
||||
{
|
||||
$this->file = $file;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file to require before creating the service.
|
||||
*
|
||||
* @return string The full pathname to include
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getFile()
|
||||
{
|
||||
return $this->file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scope of the service
|
||||
*
|
||||
* @param string $scope Whether the service must be shared or not
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setScope($scope)
|
||||
{
|
||||
$this->scope = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scope of the service
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getScope()
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of this service.
|
||||
*
|
||||
* @param Boolean $boolean
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setPublic($boolean)
|
||||
{
|
||||
$this->public = (Boolean) $boolean;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this service is public facing
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isPublic()
|
||||
{
|
||||
return $this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this definition is synthetic, that is not constructed by the
|
||||
* container, but dynamically injected.
|
||||
*
|
||||
* @param Boolean $boolean
|
||||
*
|
||||
* @return Definition the current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setSynthetic($boolean)
|
||||
{
|
||||
$this->synthetic = (Boolean) $boolean;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this definition is synthetic, that is not constructed by the
|
||||
* container, but dynamically injected.
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isSynthetic()
|
||||
{
|
||||
return $this->synthetic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this definition is abstract, that means it merely serves as a
|
||||
* template for other definitions.
|
||||
*
|
||||
* @param Boolean $boolean
|
||||
*
|
||||
* @return Definition the current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setAbstract($boolean)
|
||||
{
|
||||
$this->abstract = (Boolean) $boolean;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this definition is abstract, that means it merely serves as a
|
||||
* template for other definitions.
|
||||
*
|
||||
* @return Boolean
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function isAbstract()
|
||||
{
|
||||
return $this->abstract;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a configurator to call after the service is fully initialized.
|
||||
*
|
||||
* @param mixed $callable A PHP callable
|
||||
*
|
||||
* @return Definition The current instance
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setConfigurator($callable)
|
||||
{
|
||||
$this->configurator = $callable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configurator to call after the service is fully initialized.
|
||||
*
|
||||
* @return mixed The PHP callable to call
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getConfigurator()
|
||||
{
|
||||
return $this->configurator;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
|
||||
|
||||
/**
|
||||
* This definition decorates another definition.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class DefinitionDecorator extends Definition
|
||||
{
|
||||
private $parent;
|
||||
private $changes;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param Definition $parent The Definition instance to decorate.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($parent)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->parent = $parent;
|
||||
$this->changes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Definition being decorated.
|
||||
*
|
||||
* @return Definition
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all changes tracked for the Definition object.
|
||||
*
|
||||
* @return array An array of changes for this Definition
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getChanges()
|
||||
{
|
||||
return $this->changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->changes['class'] = true;
|
||||
|
||||
return parent::setClass($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFactoryClass($class)
|
||||
{
|
||||
$this->changes['factory_class'] = true;
|
||||
|
||||
return parent::setFactoryClass($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFactoryMethod($method)
|
||||
{
|
||||
$this->changes['factory_method'] = true;
|
||||
|
||||
return parent::setFactoryMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFactoryService($service)
|
||||
{
|
||||
$this->changes['factory_service'] = true;
|
||||
|
||||
return parent::setFactoryService($service);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setConfigurator($callable)
|
||||
{
|
||||
$this->changes['configurator'] = true;
|
||||
|
||||
return parent::setConfigurator($callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setFile($file)
|
||||
{
|
||||
$this->changes['file'] = true;
|
||||
|
||||
return parent::setFile($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setPublic($boolean)
|
||||
{
|
||||
$this->changes['public'] = true;
|
||||
|
||||
return parent::setPublic($boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* If replaceArgument() has been used to replace an argument, this method
|
||||
* will return the replacement value.
|
||||
*
|
||||
* @param integer $index
|
||||
*
|
||||
* @return mixed The argument value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function getArgument($index)
|
||||
{
|
||||
if (array_key_exists('index_'.$index, $this->arguments)) {
|
||||
return $this->arguments['index_'.$index];
|
||||
}
|
||||
|
||||
$lastIndex = count(array_filter(array_keys($this->arguments), 'is_int')) - 1;
|
||||
|
||||
if ($index < 0 || $index > $lastIndex) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, $lastIndex));
|
||||
}
|
||||
|
||||
return $this->arguments[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* You should always use this method when overwriting existing arguments
|
||||
* of the parent definition.
|
||||
*
|
||||
* If you directly call setArguments() keep in mind that you must follow
|
||||
* certain conventions when you want to overwrite the arguments of the
|
||||
* parent definition, otherwise your arguments will only be appended.
|
||||
*
|
||||
* @param integer $index
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return DefinitionDecorator the current instance
|
||||
* @throws InvalidArgumentException when $index isn't an integer
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function replaceArgument($index, $value)
|
||||
{
|
||||
if (!is_int($index)) {
|
||||
throw new InvalidArgumentException('$index must be an integer.');
|
||||
}
|
||||
|
||||
$this->arguments['index_'.$index] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Dumper is the abstract class for all built-in dumpers.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
abstract class Dumper implements DumperInterface
|
||||
{
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ContainerBuilder $container The service container to dump
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
}
|
33
core/vendor/Symfony/Component/DependencyInjection/Dumper/DumperInterface.php
vendored
Normal file
33
core/vendor/Symfony/Component/DependencyInjection/Dumper/DumperInterface.php
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
/**
|
||||
* DumperInterface is the interface implemented by service container dumper classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface DumperInterface
|
||||
{
|
||||
/**
|
||||
* Dumps the service container.
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string The representation of the service container
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function dump(array $options = array());
|
||||
}
|
273
core/vendor/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php
vendored
Normal file
273
core/vendor/Symfony/Component/DependencyInjection/Dumper/GraphvizDumper.php
vendored
Normal file
|
@ -0,0 +1,273 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* GraphvizDumper dumps a service container as a graphviz file.
|
||||
*
|
||||
* You can convert the generated dot file with the dot utility (http://www.graphviz.org/):
|
||||
*
|
||||
* dot -Tpng container.dot > foo.png
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class GraphvizDumper extends Dumper
|
||||
{
|
||||
private $nodes;
|
||||
private $edges;
|
||||
private $options = array(
|
||||
'graph' => array('ratio' => 'compress'),
|
||||
'node' => array('fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'),
|
||||
'edge' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5),
|
||||
'node.instance' => array('fillcolor' => '#9999ff', 'style' => 'filled'),
|
||||
'node.definition' => array('fillcolor' => '#eeeeee'),
|
||||
'node.missing' => array('fillcolor' => '#ff9999', 'style' => 'filled'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Dumps the service container as a graphviz graph.
|
||||
*
|
||||
* Available options:
|
||||
*
|
||||
* * graph: The default options for the whole graph
|
||||
* * node: The default options for nodes
|
||||
* * edge: The default options for edges
|
||||
* * node.instance: The default options for services that are defined directly by object instances
|
||||
* * node.definition: The default options for services that are defined via service definition instances
|
||||
* * node.missing: The default options for missing services
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string The dot representation of the service container
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
{
|
||||
foreach (array('graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing') as $key) {
|
||||
if (isset($options[$key])) {
|
||||
$this->options[$key] = array_merge($this->options[$key], $options[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->nodes = $this->findNodes();
|
||||
|
||||
$this->edges = array();
|
||||
foreach ($this->container->getDefinitions() as $id => $definition) {
|
||||
$this->edges[$id] = array_merge(
|
||||
$this->findEdges($id, $definition->getArguments(), true, ''),
|
||||
$this->findEdges($id, $definition->getProperties(), false, '')
|
||||
);
|
||||
|
||||
foreach ($definition->getMethodCalls() as $call) {
|
||||
$this->edges[$id] = array_merge(
|
||||
$this->edges[$id],
|
||||
$this->findEdges($id, $call[1], false, $call[0].'()')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->startDot().$this->addNodes().$this->addEdges().$this->endDot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all nodes.
|
||||
*
|
||||
* @return string A string representation of all nodes
|
||||
*/
|
||||
private function addNodes()
|
||||
{
|
||||
$code = '';
|
||||
foreach ($this->nodes as $id => $node) {
|
||||
$aliases = $this->getAliases($id);
|
||||
|
||||
$code .= sprintf(" node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id.($aliases ? ' ('.implode(', ', $aliases).')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes']));
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all edges.
|
||||
*
|
||||
* @return string A string representation of all edges
|
||||
*/
|
||||
private function addEdges()
|
||||
{
|
||||
$code = '';
|
||||
foreach ($this->edges as $id => $edges) {
|
||||
foreach ($edges as $edge) {
|
||||
$code .= sprintf(" node_%s -> node_%s [label=\"%s\" style=\"%s\"];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed');
|
||||
}
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all edges belonging to a specific service id.
|
||||
*
|
||||
* @param string $id The service id used to find edges
|
||||
* @param array $arguments An array of arguments
|
||||
* @param Boolean $required
|
||||
* @param string $name
|
||||
*
|
||||
* @return array An array of edges
|
||||
*/
|
||||
private function findEdges($id, $arguments, $required, $name)
|
||||
{
|
||||
$edges = array();
|
||||
foreach ($arguments as $argument) {
|
||||
if (is_object($argument) && $argument instanceof Parameter) {
|
||||
$argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null;
|
||||
} elseif (is_string($argument) && preg_match('/^%([^%]+)%$/', $argument, $match)) {
|
||||
$argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null;
|
||||
}
|
||||
|
||||
if ($argument instanceof Reference) {
|
||||
if (!$this->container->has((string) $argument)) {
|
||||
$this->nodes[(string) $argument] = array('name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']);
|
||||
}
|
||||
|
||||
$edges[] = array('name' => $name, 'required' => $required, 'to' => $argument);
|
||||
} elseif (is_array($argument)) {
|
||||
$edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name));
|
||||
}
|
||||
}
|
||||
|
||||
return $edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all nodes.
|
||||
*
|
||||
* @return array An array of all nodes
|
||||
*/
|
||||
private function findNodes()
|
||||
{
|
||||
$nodes = array();
|
||||
|
||||
$container = clone $this->container;
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $this->container->getParameterBag()->resolveValue($definition->getClass())), 'attributes' => array_merge($this->options['node.definition'], array('style' => ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope() ? 'filled' : 'dotted')));
|
||||
|
||||
$container->setDefinition($id, new Definition('stdClass'));
|
||||
}
|
||||
|
||||
foreach ($container->getServiceIds() as $id) {
|
||||
$service = $container->get($id);
|
||||
|
||||
if (in_array($id, array_keys($container->getAliases()))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$container->hasDefinition($id)) {
|
||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', get_class($service)), 'attributes' => $this->options['node.instance']);
|
||||
}
|
||||
}
|
||||
|
||||
return $nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start dot.
|
||||
*
|
||||
* @return string The string representation of a start dot
|
||||
*/
|
||||
private function startDot()
|
||||
{
|
||||
return sprintf("digraph sc {\n %s\n node [%s];\n edge [%s];\n\n",
|
||||
$this->addOptions($this->options['graph']),
|
||||
$this->addOptions($this->options['node']),
|
||||
$this->addOptions($this->options['edge'])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end dot.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function endDot()
|
||||
{
|
||||
return "}\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds attributes
|
||||
*
|
||||
* @param array $attributes An array of attributes
|
||||
*
|
||||
* @return string A comma separated list of attributes
|
||||
*/
|
||||
private function addAttributes($attributes)
|
||||
{
|
||||
$code = array();
|
||||
foreach ($attributes as $k => $v) {
|
||||
$code[] = sprintf('%s="%s"', $k, $v);
|
||||
}
|
||||
|
||||
return $code ? ', '.implode(', ', $code) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string A space separated list of options
|
||||
*/
|
||||
private function addOptions($options)
|
||||
{
|
||||
$code = array();
|
||||
foreach ($options as $k => $v) {
|
||||
$code[] = sprintf('%s="%s"', $k, $v);
|
||||
}
|
||||
|
||||
return implode(' ', $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dotizes an identifier.
|
||||
*
|
||||
* @param string $id The identifier to dotize
|
||||
*
|
||||
* @return string A dotized string
|
||||
*/
|
||||
private function dotize($id)
|
||||
{
|
||||
return strtolower(preg_replace('/[^\w]/i', '_', $id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles an array of aliases for a specified service id.
|
||||
*
|
||||
* @param string $id A service id
|
||||
*
|
||||
* @return array An array of aliases
|
||||
*/
|
||||
private function getAliases($id)
|
||||
{
|
||||
$aliases = array();
|
||||
foreach ($this->container->getAliases() as $alias => $origin) {
|
||||
if ($id == $origin) {
|
||||
$aliases[] = $alias;
|
||||
}
|
||||
}
|
||||
|
||||
return $aliases;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,301 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* XmlDumper dumps a service container as an XML string.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Martin Haso? <martin.hason@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class XmlDumper extends Dumper
|
||||
{
|
||||
/**
|
||||
* @var \DOMDocument
|
||||
*/
|
||||
private $document;
|
||||
|
||||
/**
|
||||
* Dumps the service container as an XML string.
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string An xml string representing of the service container
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
{
|
||||
$this->document = new \DOMDocument('1.0', 'utf-8');
|
||||
$this->document->formatOutput = true;
|
||||
|
||||
$container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container');
|
||||
$container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
||||
$container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd');
|
||||
|
||||
$this->addParameters($container);
|
||||
$this->addServices($container);
|
||||
|
||||
$this->document->appendChild($container);
|
||||
$xml = $this->document->saveXML();
|
||||
$this->document = null;
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds parameters.
|
||||
*
|
||||
* @param DOMElement $parent
|
||||
*/
|
||||
private function addParameters(\DOMElement $parent)
|
||||
{
|
||||
$data = $this->container->getParameterBag()->all();
|
||||
if (!$data) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->container->isFrozen()) {
|
||||
$data = $this->escape($data);
|
||||
}
|
||||
|
||||
$parameters = $this->document->createElement('parameters');
|
||||
$parent->appendChild($parameters);
|
||||
$this->convertParameters($data, 'parameter', $parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds method calls.
|
||||
*
|
||||
* @param array $methodcalls
|
||||
* @param DOMElement $parent
|
||||
*/
|
||||
private function addMethodCalls(array $methodcalls, \DOMElement $parent)
|
||||
{
|
||||
foreach ($methodcalls as $methodcall) {
|
||||
$call = $this->document->createElement('call');
|
||||
$call->setAttribute('method', $methodcall[0]);
|
||||
if (count($methodcall[1])) {
|
||||
$this->convertParameters($methodcall[1], 'argument', $call);
|
||||
}
|
||||
$parent->appendChild($call);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service.
|
||||
*
|
||||
* @param Definition $definition
|
||||
* @param string $id
|
||||
* @param DOMElement $parent
|
||||
*/
|
||||
private function addService($definition, $id, \DOMElement $parent)
|
||||
{
|
||||
$service = $this->document->createElement('service');
|
||||
if (null !== $id) {
|
||||
$service->setAttribute('id', $id);
|
||||
}
|
||||
if ($definition->getClass()) {
|
||||
$service->setAttribute('class', $definition->getClass());
|
||||
}
|
||||
if ($definition->getFactoryMethod()) {
|
||||
$service->setAttribute('factory-method', $definition->getFactoryMethod());
|
||||
}
|
||||
if ($definition->getFactoryService()) {
|
||||
$service->setAttribute('factory-service', $definition->getFactoryService());
|
||||
}
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
|
||||
$service->setAttribute('scope', $scope);
|
||||
}
|
||||
if (!$definition->isPublic()) {
|
||||
$service->setAttribute('public', 'false');
|
||||
}
|
||||
|
||||
foreach ($definition->getTags() as $name => $tags) {
|
||||
foreach ($tags as $attributes) {
|
||||
$tag = $this->document->createElement('tag');
|
||||
$tag->setAttribute('name', $name);
|
||||
foreach ($attributes as $key => $value) {
|
||||
$tag->setAttribute($key, $value);
|
||||
}
|
||||
$service->appendChild($tag);
|
||||
}
|
||||
}
|
||||
|
||||
if ($definition->getFile()) {
|
||||
$file = $this->document->createElement('file');
|
||||
$file->appendChild($this->document->createTextNode($definition->getFile()));
|
||||
$service->appendChild($file);
|
||||
}
|
||||
|
||||
if ($parameters = $definition->getArguments()) {
|
||||
$this->convertParameters($parameters, 'argument', $service);
|
||||
}
|
||||
|
||||
if ($parameters = $definition->getProperties()) {
|
||||
$this->convertParameters($parameters, 'property', $service, 'name');
|
||||
}
|
||||
|
||||
$this->addMethodCalls($definition->getMethodCalls(), $service);
|
||||
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
$configurator = $this->document->createElement('configurator');
|
||||
if (is_array($callable)) {
|
||||
$configurator->setAttribute((is_object($callable[0]) && $callable[0] instanceof Reference ? 'service' : 'class'), $callable[0]);
|
||||
$configurator->setAttribute('method', $callable[1]);
|
||||
} else {
|
||||
$configurator->setAttribute('function', $callable);
|
||||
}
|
||||
$service->appendChild($configurator);
|
||||
}
|
||||
|
||||
$parent->appendChild($service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service alias.
|
||||
*
|
||||
* @param string $alias
|
||||
* @param string $id
|
||||
* @param DOMElement $parent
|
||||
*/
|
||||
private function addServiceAlias($alias, $id, \DOMElement $parent)
|
||||
{
|
||||
$service = $this->document->createElement('service');
|
||||
$service->setAttribute('id', $alias);
|
||||
$service->setAttribute('alias', $id);
|
||||
if (!$id->isPublic()) {
|
||||
$service->setAttribute('public', 'false');
|
||||
}
|
||||
$parent->appendChild($service);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds services.
|
||||
*
|
||||
* @param DOMElement $parent
|
||||
*/
|
||||
private function addServices(\DOMElement $parent)
|
||||
{
|
||||
$definitions = $this->container->getDefinitions();
|
||||
if (!$definitions) {
|
||||
return;
|
||||
}
|
||||
|
||||
$services = $this->document->createElement('services');
|
||||
foreach ($definitions as $id => $definition) {
|
||||
$this->addService($definition, $id, $services);
|
||||
}
|
||||
|
||||
foreach ($this->container->getAliases() as $alias => $id) {
|
||||
$this->addServiceAlias($alias, $id, $services);
|
||||
}
|
||||
$parent->appendChild($services);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts parameters.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param string $type
|
||||
* @param DOMElement $parent
|
||||
* @param string $keyAttribute
|
||||
*/
|
||||
private function convertParameters($parameters, $type, \DOMElement $parent, $keyAttribute = 'key')
|
||||
{
|
||||
$withKeys = array_keys($parameters) !== range(0, count($parameters) - 1);
|
||||
foreach ($parameters as $key => $value) {
|
||||
$element = $this->document->createElement($type);
|
||||
if ($withKeys) {
|
||||
$element->setAttribute($keyAttribute, $key);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$element->setAttribute('type', 'collection');
|
||||
$this->convertParameters($value, $type, $element, 'key');
|
||||
} elseif (is_object($value) && $value instanceof Reference) {
|
||||
$element->setAttribute('type', 'service');
|
||||
$element->setAttribute('id', (string) $value);
|
||||
$behaviour = $value->getInvalidBehavior();
|
||||
if ($behaviour == ContainerInterface::NULL_ON_INVALID_REFERENCE) {
|
||||
$element->setAttribute('on-invalid', 'null');
|
||||
} elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
|
||||
$element->setAttribute('on-invalid', 'ignore');
|
||||
}
|
||||
} elseif (is_object($value) && $value instanceof Definition) {
|
||||
$element->setAttribute('type', 'service');
|
||||
$this->addService($value, null, $element);
|
||||
} else {
|
||||
if (in_array($value, array('null', 'true', 'false'), true)) {
|
||||
$element->setAttribute('type', 'string');
|
||||
}
|
||||
$text = $this->document->createTextNode(self::phpToXml($value));
|
||||
$element->appendChild($text);
|
||||
}
|
||||
$parent->appendChild($element);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes arguments
|
||||
*
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function escape($arguments)
|
||||
{
|
||||
$args = array();
|
||||
foreach ($arguments as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$args[$k] = $this->escape($v);
|
||||
} elseif (is_string($v)) {
|
||||
$args[$k] = str_replace('%', '%%', $v);
|
||||
} else {
|
||||
$args[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts php types to xml types.
|
||||
*
|
||||
* @param mixed $value Value to convert
|
||||
*/
|
||||
static public function phpToXml($value)
|
||||
{
|
||||
switch (true) {
|
||||
case null === $value:
|
||||
return 'null';
|
||||
case true === $value:
|
||||
return 'true';
|
||||
case false === $value:
|
||||
return 'false';
|
||||
case is_object($value) && $value instanceof Parameter:
|
||||
return '%'.$value.'%';
|
||||
case is_object($value) || is_resource($value):
|
||||
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
|
||||
default:
|
||||
return (string) $value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,278 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* YamlDumper dumps a service container as a YAML string.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class YamlDumper extends Dumper
|
||||
{
|
||||
/**
|
||||
* Dumps the service container as an YAML string.
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string A YAML string representing of the service container
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
{
|
||||
return $this->addParameters()."\n".$this->addServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addService($id, $definition)
|
||||
{
|
||||
$code = " $id:\n";
|
||||
if ($definition->getClass()) {
|
||||
$code .= sprintf(" class: %s\n", $definition->getClass());
|
||||
}
|
||||
|
||||
$tagsCode = '';
|
||||
foreach ($definition->getTags() as $name => $tags) {
|
||||
foreach ($tags as $attributes) {
|
||||
$att = array();
|
||||
foreach ($attributes as $key => $value) {
|
||||
$att[] = sprintf('%s: %s', Yaml::dump($key), Yaml::dump($value));
|
||||
}
|
||||
$att = $att ? ', '.implode(' ', $att) : '';
|
||||
|
||||
$tagsCode .= sprintf(" - { name: %s%s }\n", Yaml::dump($name), $att);
|
||||
}
|
||||
}
|
||||
if ($tagsCode) {
|
||||
$code .= " tags:\n".$tagsCode;
|
||||
}
|
||||
|
||||
if ($definition->getFile()) {
|
||||
$code .= sprintf(" file: %s\n", $definition->getFile());
|
||||
}
|
||||
|
||||
if ($definition->getFactoryMethod()) {
|
||||
$code .= sprintf(" factory_method: %s\n", $definition->getFactoryMethod());
|
||||
}
|
||||
|
||||
if ($definition->getFactoryService()) {
|
||||
$code .= sprintf(" factory_service: %s\n", $definition->getFactoryService());
|
||||
}
|
||||
|
||||
if ($definition->getArguments()) {
|
||||
$code .= sprintf(" arguments: %s\n", Yaml::dump($this->dumpValue($definition->getArguments()), 0));
|
||||
}
|
||||
|
||||
if ($definition->getProperties()) {
|
||||
$code .= sprintf(" properties: %s\n", Yaml::dump($this->dumpValue($definition->getProperties()), 0));
|
||||
}
|
||||
|
||||
if ($definition->getMethodCalls()) {
|
||||
$code .= sprintf(" calls:\n %s\n", str_replace("\n", "\n ", Yaml::dump($this->dumpValue($definition->getMethodCalls()), 1)));
|
||||
}
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
|
||||
$code .= sprintf(" scope: %s\n", $scope);
|
||||
}
|
||||
|
||||
if ($callable = $definition->getConfigurator()) {
|
||||
if (is_array($callable)) {
|
||||
if (is_object($callable[0]) && $callable[0] instanceof Reference) {
|
||||
$callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]);
|
||||
} else {
|
||||
$callable = array($callable[0], $callable[1]);
|
||||
}
|
||||
}
|
||||
|
||||
$code .= sprintf(" configurator: %s\n", Yaml::dump($callable, 0));
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service alias
|
||||
*
|
||||
* @param string $alias
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addServiceAlias($alias, $id)
|
||||
{
|
||||
if ($id->isPublic()) {
|
||||
return sprintf(" %s: @%s\n", $alias, $id);
|
||||
} else {
|
||||
return sprintf(" %s:\n alias: %s\n public: false", $alias, $id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds services
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addServices()
|
||||
{
|
||||
if (!$this->container->getDefinitions()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$code = "services:\n";
|
||||
foreach ($this->container->getDefinitions() as $id => $definition) {
|
||||
$code .= $this->addService($id, $definition);
|
||||
}
|
||||
|
||||
foreach ($this->container->getAliases() as $alias => $id) {
|
||||
$code .= $this->addServiceAlias($alias, $id);
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds parameters
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addParameters()
|
||||
{
|
||||
if (!$this->container->getParameterBag()->all()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->container->isFrozen()) {
|
||||
$parameters = $this->prepareParameters($this->container->getParameterBag()->all());
|
||||
} else {
|
||||
$parameters = $this->container->getParameterBag()->all();
|
||||
}
|
||||
|
||||
return Yaml::dump(array('parameters' => $parameters), 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the value to YAML format
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @throws RuntimeException When trying to dump object or resource
|
||||
*/
|
||||
private function dumpValue($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$code = array();
|
||||
foreach ($value as $k => $v) {
|
||||
$code[$k] = $this->dumpValue($v);
|
||||
}
|
||||
|
||||
return $code;
|
||||
} elseif (is_object($value) && $value instanceof Reference) {
|
||||
return $this->getServiceCall((string) $value, $value);
|
||||
} elseif (is_object($value) && $value instanceof Parameter) {
|
||||
return $this->getParameterCall((string) $value);
|
||||
} elseif (is_object($value) || is_resource($value)) {
|
||||
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the service call.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Reference $reference
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getServiceCall($id, Reference $reference = null)
|
||||
{
|
||||
if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) {
|
||||
return sprintf('@?%s', $id);
|
||||
}
|
||||
|
||||
return sprintf('@%s', $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets parameter call.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getParameterCall($id)
|
||||
{
|
||||
return sprintf('%%%s%%', $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares parameters
|
||||
*
|
||||
* @param array $parameters
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function prepareParameters($parameters)
|
||||
{
|
||||
$filtered = array();
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$value = $this->prepareParameters($value);
|
||||
} elseif ($value instanceof Reference) {
|
||||
$value = '@'.$value;
|
||||
}
|
||||
|
||||
$filtered[$key] = $value;
|
||||
}
|
||||
|
||||
return $this->escape($filtered);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes arguments
|
||||
*
|
||||
* @param array $arguments
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function escape($arguments)
|
||||
{
|
||||
$args = array();
|
||||
foreach ($arguments as $k => $v) {
|
||||
if (is_array($v)) {
|
||||
$args[$k] = $this->escape($v);
|
||||
} elseif (is_string($v)) {
|
||||
$args[$k] = str_replace('%', '%%', $v);
|
||||
} else {
|
||||
$args[$k] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
19
core/vendor/Symfony/Component/DependencyInjection/Exception/BadMethodCallException.php
vendored
Normal file
19
core/vendor/Symfony/Component/DependencyInjection/Exception/BadMethodCallException.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Base BadMethodCallException for Dependency Injection component.
|
||||
*/
|
||||
class BadMethodCallException extends \BadMethodCallException implements ExceptionInterface
|
||||
{
|
||||
}
|
22
core/vendor/Symfony/Component/DependencyInjection/Exception/ExceptionInterface.php
vendored
Normal file
22
core/vendor/Symfony/Component/DependencyInjection/Exception/ExceptionInterface.php
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Base ExceptionInterface for Dependency Injection component.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
{
|
||||
}
|
41
core/vendor/Symfony/Component/DependencyInjection/Exception/InactiveScopeException.php
vendored
Normal file
41
core/vendor/Symfony/Component/DependencyInjection/Exception/InactiveScopeException.php
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when you try to create a service of an inactive scope.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class InactiveScopeException extends RuntimeException
|
||||
{
|
||||
private $serviceId;
|
||||
private $scope;
|
||||
|
||||
public function __construct($serviceId, $scope)
|
||||
{
|
||||
parent::__construct(sprintf('You cannot create a service ("%s") of an inactive scope ("%s").', $serviceId, $scope));
|
||||
|
||||
$this->serviceId = $serviceId;
|
||||
$this->scope = $scope;
|
||||
}
|
||||
|
||||
public function getServiceId()
|
||||
{
|
||||
return $this->serviceId;
|
||||
}
|
||||
|
||||
public function getScope()
|
||||
{
|
||||
return $this->scope;
|
||||
}
|
||||
}
|
21
core/vendor/Symfony/Component/DependencyInjection/Exception/InvalidArgumentException.php
vendored
Normal file
21
core/vendor/Symfony/Component/DependencyInjection/Exception/InvalidArgumentException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Base InvalidArgumentException for Dependency Injection component.
|
||||
*
|
||||
* @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
|
||||
*/
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface
|
||||
{
|
||||
}
|
19
core/vendor/Symfony/Component/DependencyInjection/Exception/LogicException.php
vendored
Normal file
19
core/vendor/Symfony/Component/DependencyInjection/Exception/LogicException.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Base LogicException for Dependency Injection component.
|
||||
*/
|
||||
class LogicException extends \LogicException implements ExceptionInterface
|
||||
{
|
||||
}
|
19
core/vendor/Symfony/Component/DependencyInjection/Exception/OutOfBoundsException.php
vendored
Normal file
19
core/vendor/Symfony/Component/DependencyInjection/Exception/OutOfBoundsException.php
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Base OutOfBoundsException for Dependency Injection component.
|
||||
*/
|
||||
class OutOfBoundsException extends \OutOfBoundsException implements ExceptionInterface
|
||||
{
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a circular reference in a parameter is detected.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ParameterCircularReferenceException extends RuntimeException
|
||||
{
|
||||
private $parameters;
|
||||
|
||||
public function __construct($parameters)
|
||||
{
|
||||
parent::__construct(sprintf('Circular reference detected for parameter "%s" ("%s" > "%s").', $parameters[0], implode('" > "', $parameters), $parameters[0]));
|
||||
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
}
|
80
core/vendor/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php
vendored
Normal file
80
core/vendor/Symfony/Component/DependencyInjection/Exception/ParameterNotFoundException.php
vendored
Normal file
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a non-existent parameter is used.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ParameterNotFoundException extends InvalidArgumentException
|
||||
{
|
||||
private $key;
|
||||
private $sourceId;
|
||||
private $sourceKey;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $key The requested parameter key
|
||||
* @param string $sourceId The service id that references the non-existent parameter
|
||||
* @param string $sourceKey The parameter key that references the non-existent parameter
|
||||
*/
|
||||
public function __construct($key, $sourceId = null, $sourceKey = null)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->sourceId = $sourceId;
|
||||
$this->sourceKey = $sourceKey;
|
||||
|
||||
$this->updateRepr();
|
||||
}
|
||||
|
||||
public function updateRepr()
|
||||
{
|
||||
if (null !== $this->sourceId) {
|
||||
$this->message = sprintf('The service "%s" has a dependency on a non-existent parameter "%s".', $this->sourceId, $this->key);
|
||||
} elseif (null !== $this->sourceKey) {
|
||||
$this->message = sprintf('The parameter "%s" has a dependency on a non-existent parameter "%s".', $this->sourceKey, $this->key);
|
||||
} else {
|
||||
$this->message = sprintf('You have requested a non-existent parameter "%s".', $this->key);
|
||||
}
|
||||
}
|
||||
|
||||
public function getKey()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function getSourceId()
|
||||
{
|
||||
return $this->sourceId;
|
||||
}
|
||||
|
||||
public function getSourceKey()
|
||||
{
|
||||
return $this->sourceKey;
|
||||
}
|
||||
|
||||
public function setSourceId($sourceId)
|
||||
{
|
||||
$this->sourceId = $sourceId;
|
||||
|
||||
$this->updateRepr();
|
||||
}
|
||||
|
||||
public function setSourceKey($sourceKey)
|
||||
{
|
||||
$this->sourceKey = $sourceKey;
|
||||
|
||||
$this->updateRepr();
|
||||
}
|
||||
}
|
21
core/vendor/Symfony/Component/DependencyInjection/Exception/RuntimeException.php
vendored
Normal file
21
core/vendor/Symfony/Component/DependencyInjection/Exception/RuntimeException.php
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Base RuntimeException for Dependency Injection component.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class RuntimeException extends \RuntimeException implements ExceptionInterface
|
||||
{
|
||||
}
|
65
core/vendor/Symfony/Component/DependencyInjection/Exception/ScopeCrossingInjectionException.php
vendored
Normal file
65
core/vendor/Symfony/Component/DependencyInjection/Exception/ScopeCrossingInjectionException.php
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when the a scope crossing injection is detected.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ScopeCrossingInjectionException extends RuntimeException
|
||||
{
|
||||
private $sourceServiceId;
|
||||
private $sourceScope;
|
||||
private $destServiceId;
|
||||
private $destScope;
|
||||
|
||||
public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope)
|
||||
{
|
||||
parent::__construct(sprintf(
|
||||
'Scope Crossing Injection detected: The definition "%s" references the service "%s" which belongs to another scope hierarchy. '
|
||||
.'This service might not be available consistently. Generally, it is safer to either move the definition "%s" to scope "%s", or '
|
||||
.'declare "%s" as a child scope of "%s". If you can be sure that the other scope is always active, you can set the reference to strict=false to get rid of this error.',
|
||||
$sourceServiceId,
|
||||
$destServiceId,
|
||||
$sourceServiceId,
|
||||
$destScope,
|
||||
$sourceScope,
|
||||
$destScope
|
||||
));
|
||||
|
||||
$this->sourceServiceId = $sourceServiceId;
|
||||
$this->sourceScope = $sourceScope;
|
||||
$this->destServiceId = $destServiceId;
|
||||
$this->destScope = $destScope;
|
||||
}
|
||||
|
||||
public function getSourceServiceId()
|
||||
{
|
||||
return $this->sourceServiceId;
|
||||
}
|
||||
|
||||
public function getSourceScope()
|
||||
{
|
||||
return $this->sourceScope;
|
||||
}
|
||||
|
||||
public function getDestServiceId()
|
||||
{
|
||||
return $this->destServiceId;
|
||||
}
|
||||
|
||||
public function getDestScope()
|
||||
{
|
||||
return $this->destScope;
|
||||
}
|
||||
}
|
64
core/vendor/Symfony/Component/DependencyInjection/Exception/ScopeWideningInjectionException.php
vendored
Normal file
64
core/vendor/Symfony/Component/DependencyInjection/Exception/ScopeWideningInjectionException.php
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Thrown when a scope widening injection is detected.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ScopeWideningInjectionException extends RuntimeException
|
||||
{
|
||||
private $sourceServiceId;
|
||||
private $sourceScope;
|
||||
private $destServiceId;
|
||||
private $destScope;
|
||||
|
||||
public function __construct($sourceServiceId, $sourceScope, $destServiceId, $destScope)
|
||||
{
|
||||
parent::__construct(sprintf(
|
||||
'Scope Widening Injection detected: The definition "%s" references the service "%s" which belongs to a narrower scope. '
|
||||
.'Generally, it is safer to either move "%s" to scope "%s" or alternatively rely on the provider pattern by injecting the container itself, and requesting the service "%s" each time it is needed. '
|
||||
.'In rare, special cases however that might not be necessary, then you can set the reference to strict=false to get rid of this error.',
|
||||
$sourceServiceId,
|
||||
$destServiceId,
|
||||
$sourceServiceId,
|
||||
$destScope,
|
||||
$destServiceId
|
||||
));
|
||||
|
||||
$this->sourceServiceId = $sourceServiceId;
|
||||
$this->sourceScope = $sourceScope;
|
||||
$this->destServiceId = $destServiceId;
|
||||
$this->destScope = $destScope;
|
||||
}
|
||||
|
||||
public function getSourceServiceId()
|
||||
{
|
||||
return $this->sourceServiceId;
|
||||
}
|
||||
|
||||
public function getSourceScope()
|
||||
{
|
||||
return $this->sourceScope;
|
||||
}
|
||||
|
||||
public function getDestServiceId()
|
||||
{
|
||||
return $this->destServiceId;
|
||||
}
|
||||
|
||||
public function getDestScope()
|
||||
{
|
||||
return $this->destScope;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a circular reference is detected.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ServiceCircularReferenceException extends RuntimeException
|
||||
{
|
||||
private $serviceId;
|
||||
private $path;
|
||||
|
||||
public function __construct($serviceId, array $path)
|
||||
{
|
||||
parent::__construct(sprintf('Circular reference detected for service "%s", path: "%s".', $serviceId, implode(' -> ', $path)));
|
||||
|
||||
$this->serviceId = $serviceId;
|
||||
$this->path = $path;
|
||||
}
|
||||
|
||||
public function getServiceId()
|
||||
{
|
||||
return $this->serviceId;
|
||||
}
|
||||
|
||||
public function getPath()
|
||||
{
|
||||
return $this->path;
|
||||
}
|
||||
}
|
47
core/vendor/Symfony/Component/DependencyInjection/Exception/ServiceNotFoundException.php
vendored
Normal file
47
core/vendor/Symfony/Component/DependencyInjection/Exception/ServiceNotFoundException.php
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a non-existent service is requested.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ServiceNotFoundException extends InvalidArgumentException
|
||||
{
|
||||
private $id;
|
||||
private $sourceId;
|
||||
|
||||
public function __construct($id, $sourceId = null)
|
||||
{
|
||||
if (null === $sourceId) {
|
||||
$msg = sprintf('You have requested a non-existent service "%s".', $id);
|
||||
} else {
|
||||
$msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id);
|
||||
}
|
||||
|
||||
parent::__construct($msg);
|
||||
|
||||
$this->id = $id;
|
||||
$this->sourceId = $sourceId;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getSourceId()
|
||||
{
|
||||
return $this->sourceId;
|
||||
}
|
||||
}
|
32
core/vendor/Symfony/Component/DependencyInjection/Extension/ConfigurationExtensionInterface.php
vendored
Normal file
32
core/vendor/Symfony/Component/DependencyInjection/Extension/ConfigurationExtensionInterface.php
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Extension;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* ConfigurationExtensionInterface is the interface implemented by container extension classes.
|
||||
*
|
||||
* @author Kevin Bond <kevinbond@gmail.com>
|
||||
*/
|
||||
interface ConfigurationExtensionInterface
|
||||
{
|
||||
/**
|
||||
* Returns extension configuration
|
||||
*
|
||||
* @param array $config $config An array of configuration values
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
*
|
||||
* @return ConfigurationInterface|null The configuration or null
|
||||
*/
|
||||
function getConfiguration(array $config, ContainerBuilder $container);
|
||||
}
|
65
core/vendor/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php
vendored
Normal file
65
core/vendor/Symfony/Component/DependencyInjection/Extension/ExtensionInterface.php
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Extension;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* ExtensionInterface is the interface implemented by container extension classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface ExtensionInterface
|
||||
{
|
||||
/**
|
||||
* Loads a specific configuration.
|
||||
*
|
||||
* @param array $config An array of configuration values
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
*
|
||||
* @throws InvalidArgumentException When provided tag is not defined in this extension
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function load(array $config, ContainerBuilder $container);
|
||||
|
||||
/**
|
||||
* Returns the namespace to be used for this extension (XML namespace).
|
||||
*
|
||||
* @return string The XML namespace
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function getNamespace();
|
||||
|
||||
/**
|
||||
* Returns the base path for the XSD files.
|
||||
*
|
||||
* @return string The XSD base path
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function getXsdValidationBasePath();
|
||||
|
||||
/**
|
||||
* Returns the recommended alias to use in XML.
|
||||
*
|
||||
* This alias is also the mandatory prefix to use when using YAML.
|
||||
*
|
||||
* @return string The alias
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function getAlias();
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2004-2012 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\Config\Loader\Loader;
|
||||
|
||||
/**
|
||||
* ClosureLoader loads service definitions from a PHP closure.
|
||||
*
|
||||
* The Closure has access to the container as its first argument.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ClosureLoader extends Loader
|
||||
{
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
*/
|
||||
public function __construct(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a Closure.
|
||||
*
|
||||
* @param \Closure $closure The resource
|
||||
* @param string $type The resource type
|
||||
*/
|
||||
public function load($closure, $type = null)
|
||||
{
|
||||
call_user_func($closure, $this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean true if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return $resource instanceof \Closure;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
|
||||
/**
|
||||
* FileLoader is the abstract class used by all built-in loaders that are file based.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class FileLoader extends BaseFileLoader
|
||||
{
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param ContainerBuilder $container A ContainerBuilder instance
|
||||
* @param FileLocator $locator A FileLocator instance
|
||||
*/
|
||||
public function __construct(ContainerBuilder $container, FileLocator $locator)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
parent::__construct($locator);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* IniFileLoader loads parameters from INI files.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class IniFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a resource.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @throws InvalidArgumentException When ini file is not valid
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
$result = parse_ini_file($path, true);
|
||||
if (false === $result || array() === $result) {
|
||||
throw new InvalidArgumentException(sprintf('The "%s" file is not valid.', $file));
|
||||
}
|
||||
|
||||
if (isset($result['parameters']) && is_array($result['parameters'])) {
|
||||
foreach ($result['parameters'] as $key => $value) {
|
||||
$this->container->setParameter($key, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean true if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'ini' === pathinfo($resource, PATHINFO_EXTENSION);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
|
||||
/**
|
||||
* PhpFileLoader loads service definitions from a PHP file.
|
||||
*
|
||||
* The PHP file is required and the $container variable can be
|
||||
* used form the file to change the container.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class PhpFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a PHP file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
// the container and loader variables are exposed to the included file below
|
||||
$container = $this->container;
|
||||
$loader = $this;
|
||||
|
||||
$path = $this->locator->locate($file);
|
||||
$this->setCurrentDir(dirname($path));
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
include $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean true if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'php' === pathinfo($resource, PATHINFO_EXTENSION);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,505 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\SimpleXMLElement;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* XmlFileLoader loads XML files service definitions.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class XmlFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads an XML file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$xml = $this->parseFile($path);
|
||||
$xml->registerXPathNamespace('container', 'http://symfony.com/schema/dic/services');
|
||||
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
// anonymous services
|
||||
$xml = $this->processAnonymousServices($xml, $path);
|
||||
|
||||
// imports
|
||||
$this->parseImports($xml, $path);
|
||||
|
||||
// parameters
|
||||
$this->parseParameters($xml, $path);
|
||||
|
||||
// extensions
|
||||
$this->loadFromExtensions($xml);
|
||||
|
||||
// services
|
||||
$this->parseDefinitions($xml, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean true if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'xml' === pathinfo($resource, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses parameters
|
||||
*
|
||||
* @param SimpleXMLElement $xml
|
||||
* @param string $file
|
||||
*/
|
||||
private function parseParameters(SimpleXMLElement $xml, $file)
|
||||
{
|
||||
if (!$xml->parameters) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->container->getParameterBag()->add($xml->parameters->getArgumentsAsPhp('parameter'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses imports
|
||||
*
|
||||
* @param SimpleXMLElement $xml
|
||||
* @param string $file
|
||||
*/
|
||||
private function parseImports(SimpleXMLElement $xml, $file)
|
||||
{
|
||||
if (false === $imports = $xml->xpath('//container:imports/container:import')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($imports as $import) {
|
||||
$this->setCurrentDir(dirname($file));
|
||||
$this->import((string) $import['resource'], null, (Boolean) $import->getAttributeAsPhp('ignore-errors'), $file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses multiple definitions
|
||||
*
|
||||
* @param SimpleXMLElement $xml
|
||||
* @param string $file
|
||||
*/
|
||||
private function parseDefinitions(SimpleXMLElement $xml, $file)
|
||||
{
|
||||
if (false === $services = $xml->xpath('//container:services/container:service')) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($services as $service) {
|
||||
$this->parseDefinition((string) $service['id'], $service, $file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an individual Definition
|
||||
*
|
||||
* @param string $id
|
||||
* @param SimpleXMLElement $service
|
||||
* @param string $file
|
||||
*/
|
||||
private function parseDefinition($id, $service, $file)
|
||||
{
|
||||
if ((string) $service['alias']) {
|
||||
$public = true;
|
||||
if (isset($service['public'])) {
|
||||
$public = $service->getAttributeAsPhp('public');
|
||||
}
|
||||
$this->container->setAlias($id, new Alias((string) $service['alias'], $public));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($service['parent'])) {
|
||||
$definition = new DefinitionDecorator((string) $service['parent']);
|
||||
} else {
|
||||
$definition = new Definition();
|
||||
}
|
||||
|
||||
foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'abstract') as $key) {
|
||||
if (isset($service[$key])) {
|
||||
$method = 'set'.str_replace('-', '', $key);
|
||||
$definition->$method((string) $service->getAttributeAsPhp($key));
|
||||
}
|
||||
}
|
||||
|
||||
if ($service->file) {
|
||||
$definition->setFile((string) $service->file);
|
||||
}
|
||||
|
||||
$definition->setArguments($service->getArgumentsAsPhp('argument'));
|
||||
$definition->setProperties($service->getArgumentsAsPhp('property'));
|
||||
|
||||
if (isset($service->configurator)) {
|
||||
if (isset($service->configurator['function'])) {
|
||||
$definition->setConfigurator((string) $service->configurator['function']);
|
||||
} else {
|
||||
if (isset($service->configurator['service'])) {
|
||||
$class = new Reference((string) $service->configurator['service'], ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
|
||||
} else {
|
||||
$class = (string) $service->configurator['class'];
|
||||
}
|
||||
|
||||
$definition->setConfigurator(array($class, (string) $service->configurator['method']));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($service->call as $call) {
|
||||
$definition->addMethodCall((string) $call['method'], $call->getArgumentsAsPhp('argument'));
|
||||
}
|
||||
|
||||
foreach ($service->tag as $tag) {
|
||||
$parameters = array();
|
||||
foreach ($tag->attributes() as $name => $value) {
|
||||
if ('name' === $name) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parameters[$name] = SimpleXMLElement::phpize($value);
|
||||
}
|
||||
|
||||
$definition->addTag((string) $tag['name'], $parameters);
|
||||
}
|
||||
|
||||
$this->container->setDefinition($id, $definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a XML file.
|
||||
*
|
||||
* @param string $file Path to a file
|
||||
*
|
||||
* @throws InvalidArgumentException When loading of XML file returns error
|
||||
*/
|
||||
private function parseFile($file)
|
||||
{
|
||||
$dom = new \DOMDocument();
|
||||
libxml_use_internal_errors(true);
|
||||
if (!$dom->load($file, defined('LIBXML_COMPACT') ? LIBXML_COMPACT : 0)) {
|
||||
throw new InvalidArgumentException(implode("\n", $this->getXmlErrors()));
|
||||
}
|
||||
$dom->validateOnParse = true;
|
||||
$dom->normalizeDocument();
|
||||
libxml_use_internal_errors(false);
|
||||
$this->validate($dom, $file);
|
||||
|
||||
return simplexml_import_dom($dom, 'Symfony\\Component\\DependencyInjection\\SimpleXMLElement');
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes anonymous services
|
||||
*
|
||||
* @param SimpleXMLElement $xml
|
||||
* @param string $file
|
||||
*
|
||||
* @return array An array of anonymous services
|
||||
*/
|
||||
private function processAnonymousServices(SimpleXMLElement $xml, $file)
|
||||
{
|
||||
$definitions = array();
|
||||
$count = 0;
|
||||
|
||||
// anonymous services as arguments
|
||||
if (false === $nodes = $xml->xpath('//container:argument[@type="service"][not(@id)]')) {
|
||||
return $xml;
|
||||
}
|
||||
foreach ($nodes as $node) {
|
||||
// give it a unique name
|
||||
$node['id'] = sprintf('%s_%d', md5($file), ++$count);
|
||||
|
||||
$definitions[(string) $node['id']] = array($node->service, $file, false);
|
||||
$node->service['id'] = (string) $node['id'];
|
||||
}
|
||||
|
||||
// anonymous services "in the wild"
|
||||
if (false === $nodes = $xml->xpath('//container:services/container:service[not(@id)]')) {
|
||||
return $xml;
|
||||
}
|
||||
foreach ($nodes as $node) {
|
||||
// give it a unique name
|
||||
$node['id'] = sprintf('%s_%d', md5($file), ++$count);
|
||||
|
||||
$definitions[(string) $node['id']] = array($node, $file, true);
|
||||
$node->service['id'] = (string) $node['id'];
|
||||
}
|
||||
|
||||
// resolve definitions
|
||||
krsort($definitions);
|
||||
foreach ($definitions as $id => $def) {
|
||||
// anonymous services are always private
|
||||
$def[0]['public'] = false;
|
||||
|
||||
$this->parseDefinition($id, $def[0], $def[1]);
|
||||
|
||||
$oNode = dom_import_simplexml($def[0]);
|
||||
if (true === $def[2]) {
|
||||
$nNode = new \DOMElement('_services');
|
||||
$oNode->parentNode->replaceChild($nNode, $oNode);
|
||||
$nNode->setAttribute('id', $id);
|
||||
} else {
|
||||
$oNode->parentNode->removeChild($oNode);
|
||||
}
|
||||
}
|
||||
|
||||
return $xml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an XML document.
|
||||
*
|
||||
* @param DOMDocument $dom
|
||||
* @param string $file
|
||||
*/
|
||||
private function validate(\DOMDocument $dom, $file)
|
||||
{
|
||||
$this->validateSchema($dom, $file);
|
||||
$this->validateExtensions($dom, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a documents XML schema.
|
||||
*
|
||||
* @param \DOMDocument $dom
|
||||
* @param string $file
|
||||
*
|
||||
* @throws RuntimeException When extension references a non-existent XSD file
|
||||
* @throws InvalidArgumentException When XML doesn't validate its XSD schema
|
||||
*/
|
||||
private function validateSchema(\DOMDocument $dom, $file)
|
||||
{
|
||||
$schemaLocations = array('http://symfony.com/schema/dic/services' => str_replace('\\', '/', __DIR__.'/schema/dic/services/services-1.0.xsd'));
|
||||
|
||||
if ($element = $dom->documentElement->getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')) {
|
||||
$items = preg_split('/\s+/', $element);
|
||||
for ($i = 0, $nb = count($items); $i < $nb; $i += 2) {
|
||||
if (!$this->container->hasExtension($items[$i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (($extension = $this->container->getExtension($items[$i])) && false !== $extension->getXsdValidationBasePath()) {
|
||||
$path = str_replace($extension->getNamespace(), str_replace('\\', '/', $extension->getXsdValidationBasePath()).'/', $items[$i + 1]);
|
||||
|
||||
if (!is_file($path)) {
|
||||
throw new RuntimeException(sprintf('Extension "%s" references a non-existent XSD file "%s"', get_class($extension), $path));
|
||||
}
|
||||
|
||||
$schemaLocations[$items[$i]] = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tmpfiles = array();
|
||||
$imports = '';
|
||||
foreach ($schemaLocations as $namespace => $location) {
|
||||
$parts = explode('/', $location);
|
||||
if (0 === stripos($location, 'phar://')) {
|
||||
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
|
||||
if ($tmpfile) {
|
||||
copy($location, $tmpfile);
|
||||
$tmpfiles[] = $tmpfile;
|
||||
$parts = explode('/', str_replace('\\', '/', $tmpfile));
|
||||
}
|
||||
}
|
||||
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
|
||||
$location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
|
||||
|
||||
$imports .= sprintf(' <xsd:import namespace="%s" schemaLocation="%s" />'."\n", $namespace, $location);
|
||||
}
|
||||
|
||||
$source = <<<EOF
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<xsd:schema xmlns="http://symfony.com/schema"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://symfony.com/schema"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
|
||||
$imports
|
||||
</xsd:schema>
|
||||
EOF
|
||||
;
|
||||
|
||||
$current = libxml_use_internal_errors(true);
|
||||
$valid = $dom->schemaValidateSource($source);
|
||||
foreach ($tmpfiles as $tmpfile) {
|
||||
@unlink($tmpfile);
|
||||
}
|
||||
if (!$valid) {
|
||||
throw new InvalidArgumentException(implode("\n", $this->getXmlErrors()));
|
||||
}
|
||||
libxml_use_internal_errors($current);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an extension.
|
||||
*
|
||||
* @param \DOMDocument $dom
|
||||
* @param string $file
|
||||
*
|
||||
* @throws InvalidArgumentException When no extension is found corresponding to a tag
|
||||
*/
|
||||
private function validateExtensions(\DOMDocument $dom, $file)
|
||||
{
|
||||
foreach ($dom->documentElement->childNodes as $node) {
|
||||
if (!$node instanceof \DOMElement || 'http://symfony.com/schema/dic/services' === $node->namespaceURI) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// can it be handled by an extension?
|
||||
if (!$this->container->hasExtension($node->namespaceURI)) {
|
||||
$extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getNamespace(); }, $this->container->getExtensions()));
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
|
||||
$node->tagName,
|
||||
$file,
|
||||
$node->namespaceURI,
|
||||
$extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of XML errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function getXmlErrors()
|
||||
{
|
||||
$errors = array();
|
||||
foreach (libxml_get_errors() as $error) {
|
||||
$errors[] = sprintf('[%s %s] %s (in %s - line %d, column %d)',
|
||||
LIBXML_ERR_WARNING == $error->level ? 'WARNING' : 'ERROR',
|
||||
$error->code,
|
||||
trim($error->message),
|
||||
$error->file ? $error->file : 'n/a',
|
||||
$error->line,
|
||||
$error->column
|
||||
);
|
||||
}
|
||||
|
||||
libxml_clear_errors();
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads from an extension.
|
||||
*
|
||||
* @param SimpleXMLElement $xml
|
||||
*/
|
||||
private function loadFromExtensions(SimpleXMLElement $xml)
|
||||
{
|
||||
foreach (dom_import_simplexml($xml)->childNodes as $node) {
|
||||
if (!$node instanceof \DOMElement || $node->namespaceURI === 'http://symfony.com/schema/dic/services') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$values = static::convertDomElementToArray($node);
|
||||
if (!is_array($values)) {
|
||||
$values = array();
|
||||
}
|
||||
|
||||
$this->container->loadFromExtension($node->namespaceURI, $values);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a \DomElement object to a PHP array.
|
||||
*
|
||||
* The following rules applies during the conversion:
|
||||
*
|
||||
* * Each tag is converted to a key value or an array
|
||||
* if there is more than one "value"
|
||||
*
|
||||
* * The content of a tag is set under a "value" key (<foo>bar</foo>)
|
||||
* if the tag also has some nested tags
|
||||
*
|
||||
* * The attributes are converted to keys (<foo foo="bar"/>)
|
||||
*
|
||||
* * The nested-tags are converted to keys (<foo><foo>bar</foo></foo>)
|
||||
*
|
||||
* @param \DomElement $element A \DomElement instance
|
||||
*
|
||||
* @return array A PHP array
|
||||
*/
|
||||
static public function convertDomElementToArray(\DomElement $element)
|
||||
{
|
||||
$empty = true;
|
||||
$config = array();
|
||||
foreach ($element->attributes as $name => $node) {
|
||||
$config[$name] = SimpleXMLElement::phpize($node->value);
|
||||
$empty = false;
|
||||
}
|
||||
|
||||
$nodeValue = false;
|
||||
foreach ($element->childNodes as $node) {
|
||||
if ($node instanceof \DOMText) {
|
||||
if (trim($node->nodeValue)) {
|
||||
$nodeValue = trim($node->nodeValue);
|
||||
$empty = false;
|
||||
}
|
||||
} elseif (!$node instanceof \DOMComment) {
|
||||
if ($node instanceof \DOMElement && '_services' === $node->nodeName) {
|
||||
$value = new Reference($node->getAttribute('id'));
|
||||
} else {
|
||||
$value = static::convertDomElementToArray($node);
|
||||
}
|
||||
|
||||
$key = $node->localName;
|
||||
if (isset($config[$key])) {
|
||||
if (!is_array($config[$key]) || !is_int(key($config[$key]))) {
|
||||
$config[$key] = array($config[$key]);
|
||||
}
|
||||
$config[$key][] = $value;
|
||||
} else {
|
||||
$config[$key] = $value;
|
||||
}
|
||||
|
||||
$empty = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (false !== $nodeValue) {
|
||||
$value = SimpleXMLElement::phpize($nodeValue);
|
||||
if (count($config)) {
|
||||
$config['value'] = $value;
|
||||
} else {
|
||||
$config = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return !$empty ? $config : null;
|
||||
}
|
||||
}
|
324
core/vendor/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
vendored
Normal file
324
core/vendor/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
vendored
Normal file
|
@ -0,0 +1,324 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader;
|
||||
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* YamlFileLoader loads YAML files service definitions.
|
||||
*
|
||||
* The YAML format does not support anonymous services (cf. the XML loader).
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class YamlFileLoader extends FileLoader
|
||||
{
|
||||
/**
|
||||
* Loads a Yaml file.
|
||||
*
|
||||
* @param mixed $file The resource
|
||||
* @param string $type The resource type
|
||||
*/
|
||||
public function load($file, $type = null)
|
||||
{
|
||||
$path = $this->locator->locate($file);
|
||||
|
||||
$content = $this->loadFile($path);
|
||||
|
||||
$this->container->addResource(new FileResource($path));
|
||||
|
||||
// empty file
|
||||
if (null === $content) {
|
||||
return;
|
||||
}
|
||||
|
||||
// imports
|
||||
$this->parseImports($content, $file);
|
||||
|
||||
// parameters
|
||||
if (isset($content['parameters'])) {
|
||||
foreach ($content['parameters'] as $key => $value) {
|
||||
$this->container->setParameter($key, $this->resolveServices($value));
|
||||
}
|
||||
}
|
||||
|
||||
// extensions
|
||||
$this->loadFromExtensions($content);
|
||||
|
||||
// services
|
||||
$this->parseDefinitions($content, $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class supports the given resource.
|
||||
*
|
||||
* @param mixed $resource A resource
|
||||
* @param string $type The resource type
|
||||
*
|
||||
* @return Boolean true if this class supports the given resource, false otherwise
|
||||
*/
|
||||
public function supports($resource, $type = null)
|
||||
{
|
||||
return is_string($resource) && 'yml' === pathinfo($resource, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses all imports
|
||||
*
|
||||
* @param array $content
|
||||
* @param string $file
|
||||
*/
|
||||
private function parseImports($content, $file)
|
||||
{
|
||||
if (!isset($content['imports'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($content['imports'] as $import) {
|
||||
$this->setCurrentDir(dirname($file));
|
||||
$this->import($import['resource'], null, isset($import['ignore_errors']) ? (Boolean) $import['ignore_errors'] : false, $file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses definitions
|
||||
*
|
||||
* @param array $content
|
||||
* @param string $file
|
||||
*/
|
||||
private function parseDefinitions($content, $file)
|
||||
{
|
||||
if (!isset($content['services'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($content['services'] as $id => $service) {
|
||||
$this->parseDefinition($id, $service, $file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a definition.
|
||||
*
|
||||
* @param string $id
|
||||
* @param array $service
|
||||
* @param string $file
|
||||
*/
|
||||
private function parseDefinition($id, $service, $file)
|
||||
{
|
||||
if (is_string($service) && 0 === strpos($service, '@')) {
|
||||
$this->container->setAlias($id, substr($service, 1));
|
||||
|
||||
return;
|
||||
} elseif (isset($service['alias'])) {
|
||||
$public = !array_key_exists('public', $service) || (Boolean) $service['public'];
|
||||
$this->container->setAlias($id, new Alias($service['alias'], $public));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($service['parent'])) {
|
||||
$definition = new DefinitionDecorator($service['parent']);
|
||||
} else {
|
||||
$definition = new Definition();
|
||||
}
|
||||
|
||||
if (isset($service['class'])) {
|
||||
$definition->setClass($service['class']);
|
||||
}
|
||||
|
||||
if (isset($service['scope'])) {
|
||||
$definition->setScope($service['scope']);
|
||||
}
|
||||
|
||||
if (isset($service['synthetic'])) {
|
||||
$definition->setSynthetic($service['synthetic']);
|
||||
}
|
||||
|
||||
if (isset($service['public'])) {
|
||||
$definition->setPublic($service['public']);
|
||||
}
|
||||
|
||||
if (isset($service['abstract'])) {
|
||||
$definition->setAbstract($service['abstract']);
|
||||
}
|
||||
|
||||
if (isset($service['factory_class'])) {
|
||||
$definition->setFactoryClass($service['factory_class']);
|
||||
}
|
||||
|
||||
if (isset($service['factory_method'])) {
|
||||
$definition->setFactoryMethod($service['factory_method']);
|
||||
}
|
||||
|
||||
if (isset($service['factory_service'])) {
|
||||
$definition->setFactoryService($service['factory_service']);
|
||||
}
|
||||
|
||||
if (isset($service['file'])) {
|
||||
$definition->setFile($service['file']);
|
||||
}
|
||||
|
||||
if (isset($service['arguments'])) {
|
||||
$definition->setArguments($this->resolveServices($service['arguments']));
|
||||
}
|
||||
|
||||
if (isset($service['properties'])) {
|
||||
$definition->setProperties($this->resolveServices($service['properties']));
|
||||
}
|
||||
|
||||
if (isset($service['configurator'])) {
|
||||
if (is_string($service['configurator'])) {
|
||||
$definition->setConfigurator($service['configurator']);
|
||||
} else {
|
||||
$definition->setConfigurator(array($this->resolveServices($service['configurator'][0]), $service['configurator'][1]));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($service['calls'])) {
|
||||
foreach ($service['calls'] as $call) {
|
||||
$definition->addMethodCall($call[0], $this->resolveServices($call[1]));
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($service['tags'])) {
|
||||
if (!is_array($service['tags'])) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s.', $id, $file));
|
||||
}
|
||||
|
||||
foreach ($service['tags'] as $tag) {
|
||||
if (!isset($tag['name'])) {
|
||||
throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
|
||||
}
|
||||
|
||||
$name = $tag['name'];
|
||||
unset($tag['name']);
|
||||
|
||||
$definition->addTag($name, $tag);
|
||||
}
|
||||
}
|
||||
|
||||
$this->container->setDefinition($id, $definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a YAML file.
|
||||
*
|
||||
* @param string $file
|
||||
*
|
||||
* @return array The file content
|
||||
*/
|
||||
private function loadFile($file)
|
||||
{
|
||||
return $this->validate(Yaml::parse($file), $file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a YAML file.
|
||||
*
|
||||
* @param mixed $content
|
||||
* @param string $file
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws InvalidArgumentException When service file is not valid
|
||||
*/
|
||||
private function validate($content, $file)
|
||||
{
|
||||
if (null === $content) {
|
||||
return $content;
|
||||
}
|
||||
|
||||
if (!is_array($content)) {
|
||||
throw new InvalidArgumentException(sprintf('The service file "%s" is not valid.', $file));
|
||||
}
|
||||
|
||||
foreach (array_keys($content) as $namespace) {
|
||||
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$this->container->hasExtension($namespace)) {
|
||||
$extensionNamespaces = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
|
||||
$namespace,
|
||||
$file,
|
||||
$namespace,
|
||||
$extensionNamespaces ? sprintf('"%s"', implode('", "', $extensionNamespaces)) : 'none'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves services.
|
||||
*
|
||||
* @param string $value
|
||||
*
|
||||
* @return Reference
|
||||
*/
|
||||
private function resolveServices($value)
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$value = array_map(array($this, 'resolveServices'), $value);
|
||||
} elseif (is_string($value) && 0 === strpos($value, '@')) {
|
||||
if (0 === strpos($value, '@?')) {
|
||||
$value = substr($value, 2);
|
||||
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
|
||||
} else {
|
||||
$value = substr($value, 1);
|
||||
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
|
||||
}
|
||||
|
||||
if ('=' === substr($value, -1)) {
|
||||
$value = substr($value, 0, -1);
|
||||
$strict = false;
|
||||
} else {
|
||||
$strict = true;
|
||||
}
|
||||
|
||||
$value = new Reference($value, $invalidBehavior, $strict);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads from Extensions
|
||||
*
|
||||
* @param array $content
|
||||
*/
|
||||
private function loadFromExtensions($content)
|
||||
{
|
||||
foreach ($content as $namespace => $values) {
|
||||
if (in_array($namespace, array('imports', 'parameters', 'services'))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_array($values)) {
|
||||
$values = array();
|
||||
}
|
||||
|
||||
$this->container->loadFromExtension($namespace, $values);
|
||||
}
|
||||
}
|
||||
}
|
180
core/vendor/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
vendored
Normal file
180
core/vendor/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<xsd:schema xmlns="http://symfony.com/schema/dic/services"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
targetNamespace="http://symfony.com/schema/dic/services"
|
||||
elementFormDefault="qualified">
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Symfony XML Services Schema, version 1.0
|
||||
Authors: Fabien Potencier
|
||||
|
||||
This defines a way to describe PHP objects (services) and their
|
||||
dependencies.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="container" type="container" />
|
||||
|
||||
<xsd:complexType name="container">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The root element of a service file.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:sequence>
|
||||
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="imports" type="imports" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="parameters" type="parameters" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="services" type="services" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:sequence>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="services">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Enclosing element for the definition of all services
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element name="service" type="service" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="imports">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Enclosing element for the import elements
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element name="import" type="import" />
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="import">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Import an external resource defining other services or parameters
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:attribute name="resource" type="xsd:string" use="required" />
|
||||
<xsd:attribute name="ignore-errors" type="boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="configurator">
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="service" type="xsd:string" />
|
||||
<xsd:attribute name="class" type="xsd:string" />
|
||||
<xsd:attribute name="method" type="xsd:string" />
|
||||
<xsd:attribute name="function" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="service">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="file" type="xsd:string" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="configurator" type="configurator" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="class" type="xsd:string" />
|
||||
<xsd:attribute name="scope" type="xsd:string" />
|
||||
<xsd:attribute name="public" type="boolean" />
|
||||
<xsd:attribute name="synthetic" type="boolean" />
|
||||
<xsd:attribute name="abstract" type="boolean" />
|
||||
<xsd:attribute name="factory-class" type="xsd:string" />
|
||||
<xsd:attribute name="factory-method" type="xsd:string" />
|
||||
<xsd:attribute name="factory-service" type="xsd:string" />
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="parent" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="tag">
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:anyAttribute namespace="##any" processContents="lax" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="parameters">
|
||||
<xsd:choice minOccurs="1" maxOccurs="unbounded">
|
||||
<xsd:element name="parameter" type="parameter" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="type" type="parameter_type" />
|
||||
<xsd:attribute name="key" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="parameter" mixed="true">
|
||||
<xsd:choice minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:element name="parameter" type="parameter" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="type" type="parameter_type" />
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="key" type="xsd:string" />
|
||||
<xsd:attribute name="on-invalid" type="invalid_sequence" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="property" mixed="true">
|
||||
<xsd:attribute name="type" type="argument_type" />
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="on-invalid" type="xsd:string" />
|
||||
<xsd:attribute name="strict" type="boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="argument" mixed="true">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="service" type="service" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="type" type="argument_type" />
|
||||
<xsd:attribute name="id" type="xsd:string" />
|
||||
<xsd:attribute name="key" type="xsd:string" />
|
||||
<xsd:attribute name="index" type="xsd:integer" />
|
||||
<xsd:attribute name="on-invalid" type="xsd:string" />
|
||||
<xsd:attribute name="strict" type="boolean" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="call" mixed="true">
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
|
||||
<xsd:element name="service" type="service" />
|
||||
</xsd:choice>
|
||||
<xsd:attribute name="method" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:simpleType name="parameter_type">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="collection" />
|
||||
<xsd:enumeration value="service" />
|
||||
<xsd:enumeration value="string" />
|
||||
<xsd:enumeration value="constant" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="argument_type">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="collection" />
|
||||
<xsd:enumeration value="service" />
|
||||
<xsd:enumeration value="string" />
|
||||
<xsd:enumeration value="constant" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="invalid_sequence">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="null" />
|
||||
<xsd:enumeration value="ignore" />
|
||||
<xsd:enumeration value="exception" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="boolean">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:pattern value="(%.+%|true|false)" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:schema>
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* Parameter represents a parameter reference.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Parameter
|
||||
{
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $id The parameter key
|
||||
*/
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* __toString.
|
||||
*
|
||||
* @return string The parameter key
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->id;
|
||||
}
|
||||
}
|
72
core/vendor/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php
vendored
Normal file
72
core/vendor/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\ParameterBag;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
|
||||
/**
|
||||
* Holds read-only parameters.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class FrozenParameterBag extends ParameterBag
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* For performance reasons, the constructor assumes that
|
||||
* all keys are already lowercased.
|
||||
*
|
||||
* This is always the case when used internally.
|
||||
*
|
||||
* @param array $parameters An array of parameters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct(array $parameters = array())
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
$this->resolved = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
throw new LogicException('Impossible to call clear() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function add(array $parameters)
|
||||
{
|
||||
throw new LogicException('Impossible to call add() on a frozen ParameterBag.');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||
}
|
||||
}
|
261
core/vendor/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php
vendored
Normal file
261
core/vendor/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php
vendored
Normal file
|
@ -0,0 +1,261 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\ParameterBag;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Holds parameters.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class ParameterBag implements ParameterBagInterface
|
||||
{
|
||||
protected $parameters;
|
||||
protected $resolved;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param array $parameters An array of parameters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct(array $parameters = array())
|
||||
{
|
||||
$this->parameters = array();
|
||||
$this->add($parameters);
|
||||
$this->resolved = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all parameters.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->parameters = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds parameters to the service container parameters.
|
||||
*
|
||||
* @param array $parameters An array of parameters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function add(array $parameters)
|
||||
{
|
||||
foreach ($parameters as $key => $value) {
|
||||
$this->parameters[strtolower($key)] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the service container parameters.
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a service container parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return mixed The parameter value
|
||||
*
|
||||
* @throws ParameterNotFoundException if the parameter is not defined
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function get($name)
|
||||
{
|
||||
$name = strtolower($name);
|
||||
|
||||
if (!array_key_exists($name, $this->parameters)) {
|
||||
throw new ParameterNotFoundException($name);
|
||||
}
|
||||
|
||||
return $this->parameters[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a service container parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
* @param mixed $value The parameter value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function set($name, $value)
|
||||
{
|
||||
$this->parameters[strtolower($name)] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a parameter name is defined.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return Boolean true if the parameter name is defined, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function has($name)
|
||||
{
|
||||
return array_key_exists(strtolower($name), $this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces parameter placeholders (%name%) by their values for all parameters.
|
||||
*/
|
||||
public function resolve()
|
||||
{
|
||||
if ($this->resolved) {
|
||||
return;
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
foreach ($this->parameters as $key => $value) {
|
||||
try {
|
||||
$value = $this->resolveValue($value);
|
||||
$parameters[$key] = $this->unescapeValue($value);
|
||||
} catch (ParameterNotFoundException $e) {
|
||||
$e->setSourceKey($key);
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$this->parameters = $parameters;
|
||||
$this->resolved = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces parameter placeholders (%name%) by their values.
|
||||
*
|
||||
* @param mixed $value A value
|
||||
* @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
|
||||
*
|
||||
* @return mixed The resolved value
|
||||
*
|
||||
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
|
||||
* @throws ParameterCircularReferenceException if a circular reference if detected
|
||||
* @throws RuntimeException when a given parameter has a type problem.
|
||||
*/
|
||||
public function resolveValue($value, array $resolving = array())
|
||||
{
|
||||
if (is_array($value)) {
|
||||
$args = array();
|
||||
foreach ($value as $k => $v) {
|
||||
$args[$this->resolveValue($k, $resolving)] = $this->resolveValue($v, $resolving);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
if (!is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $this->resolveString($value, $resolving);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves parameters inside a string
|
||||
*
|
||||
* @param string $value The string to resolve
|
||||
* @param array $resolving An array of keys that are being resolved (used internally to detect circular references)
|
||||
*
|
||||
* @return string The resolved string
|
||||
*
|
||||
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
|
||||
* @throws ParameterCircularReferenceException if a circular reference if detected
|
||||
* @throws RuntimeException when a given parameter has a type problem.
|
||||
*/
|
||||
public function resolveString($value, array $resolving = array())
|
||||
{
|
||||
// we do this to deal with non string values (Boolean, integer, ...)
|
||||
// as the preg_replace_callback throw an exception when trying
|
||||
// a non-string in a parameter value
|
||||
if (preg_match('/^%([^%\s]+)%$/', $value, $match)) {
|
||||
$key = strtolower($match[1]);
|
||||
|
||||
if (isset($resolving[$key])) {
|
||||
throw new ParameterCircularReferenceException(array_keys($resolving));
|
||||
}
|
||||
|
||||
$resolving[$key] = true;
|
||||
|
||||
return $this->resolved ? $this->get($key) : $this->resolveValue($this->get($key), $resolving);
|
||||
}
|
||||
|
||||
$self = $this;
|
||||
|
||||
return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($self, $resolving, $value) {
|
||||
// skip %%
|
||||
if (!isset($match[1])) {
|
||||
return '%%';
|
||||
}
|
||||
|
||||
$key = strtolower($match[1]);
|
||||
if (isset($resolving[$key])) {
|
||||
throw new ParameterCircularReferenceException(array_keys($resolving));
|
||||
}
|
||||
|
||||
$resolved = $self->get($key);
|
||||
|
||||
if (!is_string($resolved) && !is_numeric($resolved)) {
|
||||
throw new RuntimeException(sprintf('A string value must be composed of strings and/or numbers, but found parameter "%s" of type %s inside string value "%s".', $key, gettype($resolved), $value));
|
||||
}
|
||||
|
||||
$resolved = (string) $resolved;
|
||||
$resolving[$key] = true;
|
||||
|
||||
return $self->isResolved() ? $resolved : $self->resolveString($resolved, $resolving);
|
||||
}, $value);
|
||||
}
|
||||
|
||||
public function isResolved()
|
||||
{
|
||||
return $this->resolved;
|
||||
}
|
||||
|
||||
private function unescapeValue($value)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
return str_replace('%%', '%', $value);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$result = array();
|
||||
foreach ($value as $k => $v) {
|
||||
$result[$k] = $this->unescapeValue($v);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
97
core/vendor/Symfony/Component/DependencyInjection/ParameterBag/ParameterBagInterface.php
vendored
Normal file
97
core/vendor/Symfony/Component/DependencyInjection/ParameterBag/ParameterBagInterface.php
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\ParameterBag;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
|
||||
|
||||
/**
|
||||
* ParameterBagInterface.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface ParameterBagInterface
|
||||
{
|
||||
/**
|
||||
* Clears all parameters.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function clear();
|
||||
|
||||
/**
|
||||
* Adds parameters to the service container parameters.
|
||||
*
|
||||
* @param array $parameters An array of parameters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function add(array $parameters);
|
||||
|
||||
/**
|
||||
* Gets the service container parameters.
|
||||
*
|
||||
* @return array An array of parameters
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function all();
|
||||
|
||||
/**
|
||||
* Gets a service container parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return mixed The parameter value
|
||||
*
|
||||
* @throws ParameterNotFoundException if the parameter is not defined
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function get($name);
|
||||
|
||||
/**
|
||||
* Sets a service container parameter.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
* @param mixed $value The parameter value
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function set($name, $value);
|
||||
|
||||
/**
|
||||
* Returns true if a parameter name is defined.
|
||||
*
|
||||
* @param string $name The parameter name
|
||||
*
|
||||
* @return Boolean true if the parameter name is defined, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function has($name);
|
||||
|
||||
/**
|
||||
* Replaces parameter placeholders (%name%) by their values for all parameters.
|
||||
*/
|
||||
function resolve();
|
||||
|
||||
/**
|
||||
* Replaces parameter placeholders (%name%) by their values.
|
||||
*
|
||||
* @param mixed $value A value
|
||||
*
|
||||
* @throws ParameterNotFoundException if a placeholder references a parameter that does not exist
|
||||
*/
|
||||
function resolveValue($value);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
DependencyInjection Component
|
||||
=============================
|
||||
|
||||
DependencyInjection manages your services via a robust and flexible Dependency
|
||||
Injection Container.
|
||||
|
||||
Here is a simple example that shows how to register services and parameters:
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
$sc = new ContainerBuilder();
|
||||
$sc
|
||||
->register('foo', '%foo.class%')
|
||||
->addArgument(new Reference('bar'))
|
||||
;
|
||||
$sc->setParameter('foo.class', 'Foo');
|
||||
|
||||
$sc->get('foo');
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
Unit tests:
|
||||
|
||||
https://github.com/symfony/symfony/tree/master/tests/Symfony/Tests/Component/DependencyInjection
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* Reference represents a service reference.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Reference
|
||||
{
|
||||
private $id;
|
||||
private $invalidBehavior;
|
||||
private $strict;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param int $invalidBehavior The behavior when the service does not exist
|
||||
* @param Boolean $strict Sets how this reference is validated
|
||||
*
|
||||
* @see Container
|
||||
*/
|
||||
public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, $strict = true)
|
||||
{
|
||||
$this->id = strtolower($id);
|
||||
$this->invalidBehavior = $invalidBehavior;
|
||||
$this->strict = $strict;
|
||||
}
|
||||
|
||||
/**
|
||||
* __toString.
|
||||
*
|
||||
* @return string The service identifier
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return (string) $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the behavior to be used when the service does not exist.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getInvalidBehavior()
|
||||
{
|
||||
return $this->invalidBehavior;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true when this Reference is strict
|
||||
*
|
||||
* @return Boolean
|
||||
*/
|
||||
public function isStrict()
|
||||
{
|
||||
return $this->strict;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* Scope class.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class Scope implements ScopeInterface
|
||||
{
|
||||
private $name;
|
||||
private $parentName;
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function __construct($name, $parentName = ContainerInterface::SCOPE_CONTAINER)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->parentName = $parentName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
public function getParentName()
|
||||
{
|
||||
return $this->parentName;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony framework.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* This source file is subject to the MIT license that is bundled
|
||||
* with this source code in the file LICENSE.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* Scope Interface.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface ScopeInterface
|
||||
{
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
function getName();
|
||||
|
||||
/**
|
||||
* @api
|
||||
*/
|
||||
function getParentName();
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* SimpleXMLElement class.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class SimpleXMLElement extends \SimpleXMLElement
|
||||
{
|
||||
/**
|
||||
* Converts an attribute as a php type.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttributeAsPhp($name)
|
||||
{
|
||||
return self::phpize($this[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns arguments as valid php types.
|
||||
*
|
||||
* @param string $name
|
||||
* @param Boolean $lowercase
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getArgumentsAsPhp($name, $lowercase = true)
|
||||
{
|
||||
$arguments = array();
|
||||
foreach ($this->$name as $arg) {
|
||||
if (isset($arg['name'])) {
|
||||
$arg['key'] = (string) $arg['name'];
|
||||
}
|
||||
$key = isset($arg['key']) ? (string) $arg['key'] : (!$arguments ? 0 : max(array_keys($arguments)) + 1);
|
||||
|
||||
// parameter keys are case insensitive
|
||||
if ('parameter' == $name && $lowercase) {
|
||||
$key = strtolower($key);
|
||||
}
|
||||
|
||||
// this is used by DefinitionDecorator to overwrite a specific
|
||||
// argument of the parent definition
|
||||
if (isset($arg['index'])) {
|
||||
$key = 'index_'.$arg['index'];
|
||||
}
|
||||
|
||||
switch ($arg['type']) {
|
||||
case 'service':
|
||||
$invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
|
||||
if (isset($arg['on-invalid']) && 'ignore' == $arg['on-invalid']) {
|
||||
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
|
||||
} elseif (isset($arg['on-invalid']) && 'null' == $arg['on-invalid']) {
|
||||
$invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
|
||||
}
|
||||
|
||||
if (isset($arg['strict'])) {
|
||||
$strict = self::phpize($arg['strict']);
|
||||
} else {
|
||||
$strict = true;
|
||||
}
|
||||
|
||||
$arguments[$key] = new Reference((string) $arg['id'], $invalidBehavior, $strict);
|
||||
break;
|
||||
case 'collection':
|
||||
$arguments[$key] = $arg->getArgumentsAsPhp($name, false);
|
||||
break;
|
||||
case 'string':
|
||||
$arguments[$key] = (string) $arg;
|
||||
break;
|
||||
case 'constant':
|
||||
$arguments[$key] = constant((string) $arg);
|
||||
break;
|
||||
default:
|
||||
$arguments[$key] = self::phpize($arg);
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an xml value to a php type.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
static public function phpize($value)
|
||||
{
|
||||
$value = (string) $value;
|
||||
$lowercaseValue = strtolower($value);
|
||||
|
||||
switch (true) {
|
||||
case 'null' === $lowercaseValue:
|
||||
return null;
|
||||
case ctype_digit($value):
|
||||
$raw = $value;
|
||||
$cast = intval($value);
|
||||
|
||||
return '0' == $value[0] ? octdec($value) : (((string) $raw == (string) $cast) ? $cast : $raw);
|
||||
case 'true' === $lowercaseValue:
|
||||
return true;
|
||||
case 'false' === $lowercaseValue:
|
||||
return false;
|
||||
case is_numeric($value):
|
||||
return '0x' == $value[0].$value[1] ? hexdec($value) : floatval($value);
|
||||
case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $value):
|
||||
return floatval(str_replace(',', '', $value));
|
||||
default:
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
}
|
33
core/vendor/Symfony/Component/DependencyInjection/TaggedContainerInterface.php
vendored
Normal file
33
core/vendor/Symfony/Component/DependencyInjection/TaggedContainerInterface.php
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* TaggedContainerInterface is the interface implemented when a container knows how to deals with tags.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface TaggedContainerInterface extends ContainerInterface
|
||||
{
|
||||
/**
|
||||
* Returns service ids for a given tag.
|
||||
*
|
||||
* @param string $name The tag name
|
||||
*
|
||||
* @return array An array of tags
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function findTaggedServiceIds($name);
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
/**
|
||||
* Represents a variable.
|
||||
*
|
||||
* $var = new Variable('a');
|
||||
*
|
||||
* will be dumped as
|
||||
*
|
||||
* $a
|
||||
*
|
||||
* by the PHP dumper.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class Variable
|
||||
{
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
public function __construct($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the object to a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "symfony/dependency-injection",
|
||||
"type": "library",
|
||||
"description": "Symfony DependencyInjection Component",
|
||||
"keywords": [],
|
||||
"homepage": "http://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"recommend": {
|
||||
"symfony/config": "self.version"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/yaml": "self.version"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Symfony\\Component\\DependencyInjection": "" }
|
||||
},
|
||||
"target-dir": "Symfony/Component/DependencyInjection",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.1-dev"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue