annotate vendor/symfony/dependency-injection/ContainerBuilder.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\DependencyInjection;
Chris@0 13
Chris@0 14 use Symfony\Component\DependencyInjection\Compiler\Compiler;
Chris@0 15 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
Chris@0 16 use Symfony\Component\DependencyInjection\Compiler\PassConfig;
Chris@0 17 use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
Chris@0 18 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
Chris@0 19 use Symfony\Component\DependencyInjection\Exception\LogicException;
Chris@0 20 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
Chris@0 21 use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
Chris@0 22 use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
Chris@0 23 use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
Chris@0 24 use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
Chris@0 25 use Symfony\Component\Config\Resource\FileResource;
Chris@0 26 use Symfony\Component\Config\Resource\ResourceInterface;
Chris@0 27 use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\InstantiatorInterface;
Chris@0 28 use Symfony\Component\DependencyInjection\LazyProxy\Instantiator\RealServiceInstantiator;
Chris@0 29 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
Chris@0 30 use Symfony\Component\ExpressionLanguage\Expression;
Chris@0 31 use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
Chris@0 32
Chris@0 33 /**
Chris@0 34 * ContainerBuilder is a DI container that provides an API to easily describe services.
Chris@0 35 *
Chris@0 36 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 37 */
Chris@0 38 class ContainerBuilder extends Container implements TaggedContainerInterface
Chris@0 39 {
Chris@0 40 /**
Chris@0 41 * @var ExtensionInterface[]
Chris@0 42 */
Chris@0 43 private $extensions = array();
Chris@0 44
Chris@0 45 /**
Chris@0 46 * @var ExtensionInterface[]
Chris@0 47 */
Chris@0 48 private $extensionsByNs = array();
Chris@0 49
Chris@0 50 /**
Chris@0 51 * @var Definition[]
Chris@0 52 */
Chris@0 53 private $definitions = array();
Chris@0 54
Chris@0 55 /**
Chris@0 56 * @var Alias[]
Chris@0 57 */
Chris@0 58 private $aliasDefinitions = array();
Chris@0 59
Chris@0 60 /**
Chris@0 61 * @var ResourceInterface[]
Chris@0 62 */
Chris@0 63 private $resources = array();
Chris@0 64
Chris@0 65 private $extensionConfigs = array();
Chris@0 66
Chris@0 67 /**
Chris@0 68 * @var Compiler
Chris@0 69 */
Chris@0 70 private $compiler;
Chris@0 71
Chris@0 72 private $trackResources;
Chris@0 73
Chris@0 74 /**
Chris@0 75 * @var InstantiatorInterface|null
Chris@0 76 */
Chris@0 77 private $proxyInstantiator;
Chris@0 78
Chris@0 79 /**
Chris@0 80 * @var ExpressionLanguage|null
Chris@0 81 */
Chris@0 82 private $expressionLanguage;
Chris@0 83
Chris@0 84 /**
Chris@0 85 * @var ExpressionFunctionProviderInterface[]
Chris@0 86 */
Chris@0 87 private $expressionLanguageProviders = array();
Chris@0 88
Chris@0 89 public function __construct(ParameterBagInterface $parameterBag = null)
Chris@0 90 {
Chris@0 91 parent::__construct($parameterBag);
Chris@0 92
Chris@0 93 $this->trackResources = interface_exists('Symfony\Component\Config\Resource\ResourceInterface');
Chris@0 94 }
Chris@0 95
Chris@0 96 /**
Chris@0 97 * @var string[] with tag names used by findTaggedServiceIds
Chris@0 98 */
Chris@0 99 private $usedTags = array();
Chris@0 100
Chris@0 101 /**
Chris@0 102 * @var string[][] a map of env var names to their placeholders
Chris@0 103 */
Chris@0 104 private $envPlaceholders = array();
Chris@0 105
Chris@0 106 /**
Chris@0 107 * @var int[] a map of env vars to their resolution counter
Chris@0 108 */
Chris@0 109 private $envCounters = array();
Chris@0 110
Chris@0 111 /**
Chris@0 112 * Sets the track resources flag.
Chris@0 113 *
Chris@0 114 * If you are not using the loaders and therefore don't want
Chris@0 115 * to depend on the Config component, set this flag to false.
Chris@0 116 *
Chris@0 117 * @param bool $track true if you want to track resources, false otherwise
Chris@0 118 */
Chris@0 119 public function setResourceTracking($track)
Chris@0 120 {
Chris@0 121 $this->trackResources = (bool) $track;
Chris@0 122 }
Chris@0 123
Chris@0 124 /**
Chris@0 125 * Checks if resources are tracked.
Chris@0 126 *
Chris@0 127 * @return bool true if resources are tracked, false otherwise
Chris@0 128 */
Chris@0 129 public function isTrackingResources()
Chris@0 130 {
Chris@0 131 return $this->trackResources;
Chris@0 132 }
Chris@0 133
Chris@0 134 /**
Chris@0 135 * Sets the instantiator to be used when fetching proxies.
Chris@0 136 *
Chris@0 137 * @param InstantiatorInterface $proxyInstantiator
Chris@0 138 */
Chris@0 139 public function setProxyInstantiator(InstantiatorInterface $proxyInstantiator)
Chris@0 140 {
Chris@0 141 $this->proxyInstantiator = $proxyInstantiator;
Chris@0 142 }
Chris@0 143
Chris@0 144 /**
Chris@0 145 * Registers an extension.
Chris@0 146 *
Chris@0 147 * @param ExtensionInterface $extension An extension instance
Chris@0 148 */
Chris@0 149 public function registerExtension(ExtensionInterface $extension)
Chris@0 150 {
Chris@0 151 $this->extensions[$extension->getAlias()] = $extension;
Chris@0 152
Chris@0 153 if (false !== $extension->getNamespace()) {
Chris@0 154 $this->extensionsByNs[$extension->getNamespace()] = $extension;
Chris@0 155 }
Chris@0 156 }
Chris@0 157
Chris@0 158 /**
Chris@0 159 * Returns an extension by alias or namespace.
Chris@0 160 *
Chris@0 161 * @param string $name An alias or a namespace
Chris@0 162 *
Chris@0 163 * @return ExtensionInterface An extension instance
Chris@0 164 *
Chris@0 165 * @throws LogicException if the extension is not registered
Chris@0 166 */
Chris@0 167 public function getExtension($name)
Chris@0 168 {
Chris@0 169 if (isset($this->extensions[$name])) {
Chris@0 170 return $this->extensions[$name];
Chris@0 171 }
Chris@0 172
Chris@0 173 if (isset($this->extensionsByNs[$name])) {
Chris@0 174 return $this->extensionsByNs[$name];
Chris@0 175 }
Chris@0 176
Chris@0 177 throw new LogicException(sprintf('Container extension "%s" is not registered', $name));
Chris@0 178 }
Chris@0 179
Chris@0 180 /**
Chris@0 181 * Returns all registered extensions.
Chris@0 182 *
Chris@0 183 * @return ExtensionInterface[] An array of ExtensionInterface
Chris@0 184 */
Chris@0 185 public function getExtensions()
Chris@0 186 {
Chris@0 187 return $this->extensions;
Chris@0 188 }
Chris@0 189
Chris@0 190 /**
Chris@0 191 * Checks if we have an extension.
Chris@0 192 *
Chris@0 193 * @param string $name The name of the extension
Chris@0 194 *
Chris@0 195 * @return bool If the extension exists
Chris@0 196 */
Chris@0 197 public function hasExtension($name)
Chris@0 198 {
Chris@0 199 return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]);
Chris@0 200 }
Chris@0 201
Chris@0 202 /**
Chris@0 203 * Returns an array of resources loaded to build this configuration.
Chris@0 204 *
Chris@0 205 * @return ResourceInterface[] An array of resources
Chris@0 206 */
Chris@0 207 public function getResources()
Chris@0 208 {
Chris@0 209 return array_unique($this->resources);
Chris@0 210 }
Chris@0 211
Chris@0 212 /**
Chris@0 213 * Adds a resource for this configuration.
Chris@0 214 *
Chris@0 215 * @param ResourceInterface $resource A resource instance
Chris@0 216 *
Chris@0 217 * @return $this
Chris@0 218 */
Chris@0 219 public function addResource(ResourceInterface $resource)
Chris@0 220 {
Chris@0 221 if (!$this->trackResources) {
Chris@0 222 return $this;
Chris@0 223 }
Chris@0 224
Chris@0 225 $this->resources[] = $resource;
Chris@0 226
Chris@0 227 return $this;
Chris@0 228 }
Chris@0 229
Chris@0 230 /**
Chris@0 231 * Sets the resources for this configuration.
Chris@0 232 *
Chris@0 233 * @param ResourceInterface[] $resources An array of resources
Chris@0 234 *
Chris@0 235 * @return $this
Chris@0 236 */
Chris@0 237 public function setResources(array $resources)
Chris@0 238 {
Chris@0 239 if (!$this->trackResources) {
Chris@0 240 return $this;
Chris@0 241 }
Chris@0 242
Chris@0 243 $this->resources = $resources;
Chris@0 244
Chris@0 245 return $this;
Chris@0 246 }
Chris@0 247
Chris@0 248 /**
Chris@0 249 * Adds the object class hierarchy as resources.
Chris@0 250 *
Chris@0 251 * @param object $object An object instance
Chris@0 252 *
Chris@0 253 * @return $this
Chris@0 254 */
Chris@0 255 public function addObjectResource($object)
Chris@0 256 {
Chris@0 257 if ($this->trackResources) {
Chris@0 258 $this->addClassResource(new \ReflectionClass($object));
Chris@0 259 }
Chris@0 260
Chris@0 261 return $this;
Chris@0 262 }
Chris@0 263
Chris@0 264 /**
Chris@0 265 * Adds the given class hierarchy as resources.
Chris@0 266 *
Chris@0 267 * @param \ReflectionClass $class
Chris@0 268 *
Chris@0 269 * @return $this
Chris@0 270 */
Chris@0 271 public function addClassResource(\ReflectionClass $class)
Chris@0 272 {
Chris@0 273 if (!$this->trackResources) {
Chris@0 274 return $this;
Chris@0 275 }
Chris@0 276
Chris@0 277 do {
Chris@0 278 if (is_file($class->getFileName())) {
Chris@0 279 $this->addResource(new FileResource($class->getFileName()));
Chris@0 280 }
Chris@0 281 } while ($class = $class->getParentClass());
Chris@0 282
Chris@0 283 return $this;
Chris@0 284 }
Chris@0 285
Chris@0 286 /**
Chris@0 287 * Loads the configuration for an extension.
Chris@0 288 *
Chris@0 289 * @param string $extension The extension alias or namespace
Chris@0 290 * @param array $values An array of values that customizes the extension
Chris@0 291 *
Chris@0 292 * @return $this
Chris@0 293 *
Chris@0 294 * @throws BadMethodCallException When this ContainerBuilder is frozen
Chris@0 295 * @throws \LogicException if the container is frozen
Chris@0 296 */
Chris@0 297 public function loadFromExtension($extension, array $values = array())
Chris@0 298 {
Chris@0 299 if ($this->isFrozen()) {
Chris@0 300 throw new BadMethodCallException('Cannot load from an extension on a frozen container.');
Chris@0 301 }
Chris@0 302
Chris@0 303 $namespace = $this->getExtension($extension)->getAlias();
Chris@0 304
Chris@0 305 $this->extensionConfigs[$namespace][] = $values;
Chris@0 306
Chris@0 307 return $this;
Chris@0 308 }
Chris@0 309
Chris@0 310 /**
Chris@0 311 * Adds a compiler pass.
Chris@0 312 *
Chris@0 313 * @param CompilerPassInterface $pass A compiler pass
Chris@0 314 * @param string $type The type of compiler pass
Chris@0 315 * @param int $priority Used to sort the passes
Chris@0 316 *
Chris@0 317 * @return $this
Chris@0 318 */
Chris@0 319 public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, $priority = 0*/)
Chris@0 320 {
Chris@0 321 if (func_num_args() >= 3) {
Chris@0 322 $priority = func_get_arg(2);
Chris@0 323 } else {
Chris@0 324 if (__CLASS__ !== get_class($this)) {
Chris@0 325 $r = new \ReflectionMethod($this, __FUNCTION__);
Chris@0 326 if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
Chris@0 327 @trigger_error(sprintf('Method %s() will have a third `$priority = 0` argument in version 4.0. Not defining it is deprecated since 3.2.', __METHOD__), E_USER_DEPRECATED);
Chris@0 328 }
Chris@0 329 }
Chris@0 330
Chris@0 331 $priority = 0;
Chris@0 332 }
Chris@0 333
Chris@0 334 $this->getCompiler()->addPass($pass, $type, $priority);
Chris@0 335
Chris@0 336 $this->addObjectResource($pass);
Chris@0 337
Chris@0 338 return $this;
Chris@0 339 }
Chris@0 340
Chris@0 341 /**
Chris@0 342 * Returns the compiler pass config which can then be modified.
Chris@0 343 *
Chris@0 344 * @return PassConfig The compiler pass config
Chris@0 345 */
Chris@0 346 public function getCompilerPassConfig()
Chris@0 347 {
Chris@0 348 return $this->getCompiler()->getPassConfig();
Chris@0 349 }
Chris@0 350
Chris@0 351 /**
Chris@0 352 * Returns the compiler.
Chris@0 353 *
Chris@0 354 * @return Compiler The compiler
Chris@0 355 */
Chris@0 356 public function getCompiler()
Chris@0 357 {
Chris@0 358 if (null === $this->compiler) {
Chris@0 359 $this->compiler = new Compiler();
Chris@0 360 }
Chris@0 361
Chris@0 362 return $this->compiler;
Chris@0 363 }
Chris@0 364
Chris@0 365 /**
Chris@0 366 * Sets a service.
Chris@0 367 *
Chris@0 368 * @param string $id The service identifier
Chris@0 369 * @param object $service The service instance
Chris@0 370 *
Chris@0 371 * @throws BadMethodCallException When this ContainerBuilder is frozen
Chris@0 372 */
Chris@0 373 public function set($id, $service)
Chris@0 374 {
Chris@0 375 $id = strtolower($id);
Chris@0 376
Chris@0 377 if ($this->isFrozen() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) {
Chris@0 378 // setting a synthetic service on a frozen container is alright
Chris@0 379 throw new BadMethodCallException(sprintf('Setting service "%s" for an unknown or non-synthetic service definition on a frozen container is not allowed.', $id));
Chris@0 380 }
Chris@0 381
Chris@0 382 unset($this->definitions[$id], $this->aliasDefinitions[$id]);
Chris@0 383
Chris@0 384 parent::set($id, $service);
Chris@0 385 }
Chris@0 386
Chris@0 387 /**
Chris@0 388 * Removes a service definition.
Chris@0 389 *
Chris@0 390 * @param string $id The service identifier
Chris@0 391 */
Chris@0 392 public function removeDefinition($id)
Chris@0 393 {
Chris@0 394 unset($this->definitions[strtolower($id)]);
Chris@0 395 }
Chris@0 396
Chris@0 397 /**
Chris@0 398 * Returns true if the given service is defined.
Chris@0 399 *
Chris@0 400 * @param string $id The service identifier
Chris@0 401 *
Chris@0 402 * @return bool true if the service is defined, false otherwise
Chris@0 403 */
Chris@0 404 public function has($id)
Chris@0 405 {
Chris@0 406 $id = strtolower($id);
Chris@0 407
Chris@0 408 return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id);
Chris@0 409 }
Chris@0 410
Chris@0 411 /**
Chris@0 412 * Gets a service.
Chris@0 413 *
Chris@0 414 * @param string $id The service identifier
Chris@0 415 * @param int $invalidBehavior The behavior when the service does not exist
Chris@0 416 *
Chris@0 417 * @return object The associated service
Chris@0 418 *
Chris@0 419 * @throws InvalidArgumentException when no definitions are available
Chris@0 420 * @throws ServiceCircularReferenceException When a circular reference is detected
Chris@0 421 * @throws ServiceNotFoundException When the service is not defined
Chris@0 422 * @throws \Exception
Chris@0 423 *
Chris@0 424 * @see Reference
Chris@0 425 */
Chris@0 426 public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
Chris@0 427 {
Chris@0 428 $id = strtolower($id);
Chris@0 429
Chris@0 430 if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
Chris@0 431 return $service;
Chris@0 432 }
Chris@0 433
Chris@0 434 if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) {
Chris@0 435 return $this->get((string) $this->aliasDefinitions[$id], $invalidBehavior);
Chris@0 436 }
Chris@0 437
Chris@0 438 try {
Chris@0 439 $definition = $this->getDefinition($id);
Chris@0 440 } catch (ServiceNotFoundException $e) {
Chris@0 441 if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
Chris@0 442 return;
Chris@0 443 }
Chris@0 444
Chris@0 445 throw $e;
Chris@0 446 }
Chris@0 447
Chris@0 448 $this->loading[$id] = true;
Chris@0 449
Chris@0 450 try {
Chris@0 451 $service = $this->createService($definition, $id);
Chris@0 452 } finally {
Chris@0 453 unset($this->loading[$id]);
Chris@0 454 }
Chris@0 455
Chris@0 456 return $service;
Chris@0 457 }
Chris@0 458
Chris@0 459 /**
Chris@0 460 * Merges a ContainerBuilder with the current ContainerBuilder configuration.
Chris@0 461 *
Chris@0 462 * Service definitions overrides the current defined ones.
Chris@0 463 *
Chris@0 464 * But for parameters, they are overridden by the current ones. It allows
Chris@0 465 * the parameters passed to the container constructor to have precedence
Chris@0 466 * over the loaded ones.
Chris@0 467 *
Chris@0 468 * $container = new ContainerBuilder(array('foo' => 'bar'));
Chris@0 469 * $loader = new LoaderXXX($container);
Chris@0 470 * $loader->load('resource_name');
Chris@0 471 * $container->register('foo', new stdClass());
Chris@0 472 *
Chris@0 473 * In the above example, even if the loaded resource defines a foo
Chris@0 474 * parameter, the value will still be 'bar' as defined in the ContainerBuilder
Chris@0 475 * constructor.
Chris@0 476 *
Chris@0 477 * @param ContainerBuilder $container The ContainerBuilder instance to merge
Chris@0 478 *
Chris@0 479 * @throws BadMethodCallException When this ContainerBuilder is frozen
Chris@0 480 */
Chris@0 481 public function merge(ContainerBuilder $container)
Chris@0 482 {
Chris@0 483 if ($this->isFrozen()) {
Chris@0 484 throw new BadMethodCallException('Cannot merge on a frozen container.');
Chris@0 485 }
Chris@0 486
Chris@0 487 $this->addDefinitions($container->getDefinitions());
Chris@0 488 $this->addAliases($container->getAliases());
Chris@0 489 $this->getParameterBag()->add($container->getParameterBag()->all());
Chris@0 490
Chris@0 491 if ($this->trackResources) {
Chris@0 492 foreach ($container->getResources() as $resource) {
Chris@0 493 $this->addResource($resource);
Chris@0 494 }
Chris@0 495 }
Chris@0 496
Chris@0 497 foreach ($this->extensions as $name => $extension) {
Chris@0 498 if (!isset($this->extensionConfigs[$name])) {
Chris@0 499 $this->extensionConfigs[$name] = array();
Chris@0 500 }
Chris@0 501
Chris@0 502 $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name));
Chris@0 503 }
Chris@0 504
Chris@0 505 if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) {
Chris@0 506 $this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag());
Chris@0 507 }
Chris@0 508
Chris@0 509 foreach ($container->envCounters as $env => $count) {
Chris@0 510 if (!isset($this->envCounters[$env])) {
Chris@0 511 $this->envCounters[$env] = $count;
Chris@0 512 } else {
Chris@0 513 $this->envCounters[$env] += $count;
Chris@0 514 }
Chris@0 515 }
Chris@0 516 }
Chris@0 517
Chris@0 518 /**
Chris@0 519 * Returns the configuration array for the given extension.
Chris@0 520 *
Chris@0 521 * @param string $name The name of the extension
Chris@0 522 *
Chris@0 523 * @return array An array of configuration
Chris@0 524 */
Chris@0 525 public function getExtensionConfig($name)
Chris@0 526 {
Chris@0 527 if (!isset($this->extensionConfigs[$name])) {
Chris@0 528 $this->extensionConfigs[$name] = array();
Chris@0 529 }
Chris@0 530
Chris@0 531 return $this->extensionConfigs[$name];
Chris@0 532 }
Chris@0 533
Chris@0 534 /**
Chris@0 535 * Prepends a config array to the configs of the given extension.
Chris@0 536 *
Chris@0 537 * @param string $name The name of the extension
Chris@0 538 * @param array $config The config to set
Chris@0 539 */
Chris@0 540 public function prependExtensionConfig($name, array $config)
Chris@0 541 {
Chris@0 542 if (!isset($this->extensionConfigs[$name])) {
Chris@0 543 $this->extensionConfigs[$name] = array();
Chris@0 544 }
Chris@0 545
Chris@0 546 array_unshift($this->extensionConfigs[$name], $config);
Chris@0 547 }
Chris@0 548
Chris@0 549 /**
Chris@0 550 * Compiles the container.
Chris@0 551 *
Chris@0 552 * This method passes the container to compiler
Chris@0 553 * passes whose job is to manipulate and optimize
Chris@0 554 * the container.
Chris@0 555 *
Chris@0 556 * The main compiler passes roughly do four things:
Chris@0 557 *
Chris@0 558 * * The extension configurations are merged;
Chris@0 559 * * Parameter values are resolved;
Chris@0 560 * * The parameter bag is frozen;
Chris@0 561 * * Extension loading is disabled.
Chris@0 562 */
Chris@0 563 public function compile()
Chris@0 564 {
Chris@0 565 $compiler = $this->getCompiler();
Chris@0 566
Chris@0 567 if ($this->trackResources) {
Chris@0 568 foreach ($compiler->getPassConfig()->getPasses() as $pass) {
Chris@0 569 $this->addObjectResource($pass);
Chris@0 570 }
Chris@0 571 }
Chris@0 572
Chris@0 573 $compiler->compile($this);
Chris@0 574
Chris@0 575 foreach ($this->definitions as $id => $definition) {
Chris@0 576 if (!$definition->isPublic()) {
Chris@0 577 $this->privates[$id] = true;
Chris@0 578 }
Chris@0 579 if ($this->trackResources && $definition->isLazy() && ($class = $definition->getClass()) && class_exists($class)) {
Chris@0 580 $this->addClassResource(new \ReflectionClass($class));
Chris@0 581 }
Chris@0 582 }
Chris@0 583
Chris@0 584 $this->extensionConfigs = array();
Chris@0 585 $bag = $this->getParameterBag();
Chris@0 586
Chris@0 587 parent::compile();
Chris@0 588
Chris@0 589 $this->envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : array();
Chris@0 590 }
Chris@0 591
Chris@0 592 /**
Chris@0 593 * Gets all service ids.
Chris@0 594 *
Chris@0 595 * @return array An array of all defined service ids
Chris@0 596 */
Chris@0 597 public function getServiceIds()
Chris@0 598 {
Chris@0 599 return array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliasDefinitions), parent::getServiceIds()));
Chris@0 600 }
Chris@0 601
Chris@0 602 /**
Chris@0 603 * Adds the service aliases.
Chris@0 604 *
Chris@0 605 * @param array $aliases An array of aliases
Chris@0 606 */
Chris@0 607 public function addAliases(array $aliases)
Chris@0 608 {
Chris@0 609 foreach ($aliases as $alias => $id) {
Chris@0 610 $this->setAlias($alias, $id);
Chris@0 611 }
Chris@0 612 }
Chris@0 613
Chris@0 614 /**
Chris@0 615 * Sets the service aliases.
Chris@0 616 *
Chris@0 617 * @param array $aliases An array of aliases
Chris@0 618 */
Chris@0 619 public function setAliases(array $aliases)
Chris@0 620 {
Chris@0 621 $this->aliasDefinitions = array();
Chris@0 622 $this->addAliases($aliases);
Chris@0 623 }
Chris@0 624
Chris@0 625 /**
Chris@0 626 * Sets an alias for an existing service.
Chris@0 627 *
Chris@0 628 * @param string $alias The alias to create
Chris@0 629 * @param string|Alias $id The service to alias
Chris@0 630 *
Chris@0 631 * @throws InvalidArgumentException if the id is not a string or an Alias
Chris@0 632 * @throws InvalidArgumentException if the alias is for itself
Chris@0 633 */
Chris@0 634 public function setAlias($alias, $id)
Chris@0 635 {
Chris@0 636 $alias = strtolower($alias);
Chris@0 637
Chris@0 638 if (is_string($id)) {
Chris@0 639 $id = new Alias($id);
Chris@0 640 } elseif (!$id instanceof Alias) {
Chris@0 641 throw new InvalidArgumentException('$id must be a string, or an Alias object.');
Chris@0 642 }
Chris@0 643
Chris@0 644 if ($alias === (string) $id) {
Chris@0 645 throw new InvalidArgumentException(sprintf('An alias can not reference itself, got a circular reference on "%s".', $alias));
Chris@0 646 }
Chris@0 647
Chris@0 648 unset($this->definitions[$alias]);
Chris@0 649
Chris@0 650 $this->aliasDefinitions[$alias] = $id;
Chris@0 651 }
Chris@0 652
Chris@0 653 /**
Chris@0 654 * Removes an alias.
Chris@0 655 *
Chris@0 656 * @param string $alias The alias to remove
Chris@0 657 */
Chris@0 658 public function removeAlias($alias)
Chris@0 659 {
Chris@0 660 unset($this->aliasDefinitions[strtolower($alias)]);
Chris@0 661 }
Chris@0 662
Chris@0 663 /**
Chris@0 664 * Returns true if an alias exists under the given identifier.
Chris@0 665 *
Chris@0 666 * @param string $id The service identifier
Chris@0 667 *
Chris@0 668 * @return bool true if the alias exists, false otherwise
Chris@0 669 */
Chris@0 670 public function hasAlias($id)
Chris@0 671 {
Chris@0 672 return isset($this->aliasDefinitions[strtolower($id)]);
Chris@0 673 }
Chris@0 674
Chris@0 675 /**
Chris@0 676 * Gets all defined aliases.
Chris@0 677 *
Chris@0 678 * @return Alias[] An array of aliases
Chris@0 679 */
Chris@0 680 public function getAliases()
Chris@0 681 {
Chris@0 682 return $this->aliasDefinitions;
Chris@0 683 }
Chris@0 684
Chris@0 685 /**
Chris@0 686 * Gets an alias.
Chris@0 687 *
Chris@0 688 * @param string $id The service identifier
Chris@0 689 *
Chris@0 690 * @return Alias An Alias instance
Chris@0 691 *
Chris@0 692 * @throws InvalidArgumentException if the alias does not exist
Chris@0 693 */
Chris@0 694 public function getAlias($id)
Chris@0 695 {
Chris@0 696 $id = strtolower($id);
Chris@0 697
Chris@0 698 if (!isset($this->aliasDefinitions[$id])) {
Chris@0 699 throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
Chris@0 700 }
Chris@0 701
Chris@0 702 return $this->aliasDefinitions[$id];
Chris@0 703 }
Chris@0 704
Chris@0 705 /**
Chris@0 706 * Registers a service definition.
Chris@0 707 *
Chris@0 708 * This methods allows for simple registration of service definition
Chris@0 709 * with a fluid interface.
Chris@0 710 *
Chris@0 711 * @param string $id The service identifier
Chris@0 712 * @param string $class The service class
Chris@0 713 *
Chris@0 714 * @return Definition A Definition instance
Chris@0 715 */
Chris@0 716 public function register($id, $class = null)
Chris@0 717 {
Chris@0 718 return $this->setDefinition($id, new Definition($class));
Chris@0 719 }
Chris@0 720
Chris@0 721 /**
Chris@0 722 * Adds the service definitions.
Chris@0 723 *
Chris@0 724 * @param Definition[] $definitions An array of service definitions
Chris@0 725 */
Chris@0 726 public function addDefinitions(array $definitions)
Chris@0 727 {
Chris@0 728 foreach ($definitions as $id => $definition) {
Chris@0 729 $this->setDefinition($id, $definition);
Chris@0 730 }
Chris@0 731 }
Chris@0 732
Chris@0 733 /**
Chris@0 734 * Sets the service definitions.
Chris@0 735 *
Chris@0 736 * @param Definition[] $definitions An array of service definitions
Chris@0 737 */
Chris@0 738 public function setDefinitions(array $definitions)
Chris@0 739 {
Chris@0 740 $this->definitions = array();
Chris@0 741 $this->addDefinitions($definitions);
Chris@0 742 }
Chris@0 743
Chris@0 744 /**
Chris@0 745 * Gets all service definitions.
Chris@0 746 *
Chris@0 747 * @return Definition[] An array of Definition instances
Chris@0 748 */
Chris@0 749 public function getDefinitions()
Chris@0 750 {
Chris@0 751 return $this->definitions;
Chris@0 752 }
Chris@0 753
Chris@0 754 /**
Chris@0 755 * Sets a service definition.
Chris@0 756 *
Chris@0 757 * @param string $id The service identifier
Chris@0 758 * @param Definition $definition A Definition instance
Chris@0 759 *
Chris@0 760 * @return Definition the service definition
Chris@0 761 *
Chris@0 762 * @throws BadMethodCallException When this ContainerBuilder is frozen
Chris@0 763 */
Chris@0 764 public function setDefinition($id, Definition $definition)
Chris@0 765 {
Chris@0 766 if ($this->isFrozen()) {
Chris@0 767 throw new BadMethodCallException('Adding definition to a frozen container is not allowed');
Chris@0 768 }
Chris@0 769
Chris@0 770 $id = strtolower($id);
Chris@0 771
Chris@0 772 unset($this->aliasDefinitions[$id]);
Chris@0 773
Chris@0 774 return $this->definitions[$id] = $definition;
Chris@0 775 }
Chris@0 776
Chris@0 777 /**
Chris@0 778 * Returns true if a service definition exists under the given identifier.
Chris@0 779 *
Chris@0 780 * @param string $id The service identifier
Chris@0 781 *
Chris@0 782 * @return bool true if the service definition exists, false otherwise
Chris@0 783 */
Chris@0 784 public function hasDefinition($id)
Chris@0 785 {
Chris@0 786 return isset($this->definitions[strtolower($id)]);
Chris@0 787 }
Chris@0 788
Chris@0 789 /**
Chris@0 790 * Gets a service definition.
Chris@0 791 *
Chris@0 792 * @param string $id The service identifier
Chris@0 793 *
Chris@0 794 * @return Definition A Definition instance
Chris@0 795 *
Chris@0 796 * @throws ServiceNotFoundException if the service definition does not exist
Chris@0 797 */
Chris@0 798 public function getDefinition($id)
Chris@0 799 {
Chris@0 800 $id = strtolower($id);
Chris@0 801
Chris@0 802 if (!isset($this->definitions[$id])) {
Chris@0 803 throw new ServiceNotFoundException($id);
Chris@0 804 }
Chris@0 805
Chris@0 806 return $this->definitions[$id];
Chris@0 807 }
Chris@0 808
Chris@0 809 /**
Chris@0 810 * Gets a service definition by id or alias.
Chris@0 811 *
Chris@0 812 * The method "unaliases" recursively to return a Definition instance.
Chris@0 813 *
Chris@0 814 * @param string $id The service identifier or alias
Chris@0 815 *
Chris@0 816 * @return Definition A Definition instance
Chris@0 817 *
Chris@0 818 * @throws ServiceNotFoundException if the service definition does not exist
Chris@0 819 */
Chris@0 820 public function findDefinition($id)
Chris@0 821 {
Chris@0 822 $id = strtolower($id);
Chris@0 823
Chris@0 824 while (isset($this->aliasDefinitions[$id])) {
Chris@0 825 $id = (string) $this->aliasDefinitions[$id];
Chris@0 826 }
Chris@0 827
Chris@0 828 return $this->getDefinition($id);
Chris@0 829 }
Chris@0 830
Chris@0 831 /**
Chris@0 832 * Creates a service for a service definition.
Chris@0 833 *
Chris@0 834 * @param Definition $definition A service definition instance
Chris@0 835 * @param string $id The service identifier
Chris@0 836 * @param bool $tryProxy Whether to try proxying the service with a lazy proxy
Chris@0 837 *
Chris@0 838 * @return object The service described by the service definition
Chris@0 839 *
Chris@0 840 * @throws RuntimeException When the factory definition is incomplete
Chris@0 841 * @throws RuntimeException When the service is a synthetic service
Chris@0 842 * @throws InvalidArgumentException When configure callable is not callable
Chris@0 843 */
Chris@0 844 private function createService(Definition $definition, $id, $tryProxy = true)
Chris@0 845 {
Chris@0 846 if ($definition instanceof DefinitionDecorator) {
Chris@0 847 throw new RuntimeException(sprintf('Constructing service "%s" from a parent definition is not supported at build time.', $id));
Chris@0 848 }
Chris@0 849
Chris@0 850 if ($definition->isSynthetic()) {
Chris@0 851 throw new RuntimeException(sprintf('You have requested a synthetic service ("%s"). The DIC does not know how to construct this service.', $id));
Chris@0 852 }
Chris@0 853
Chris@0 854 if ($definition->isDeprecated()) {
Chris@0 855 @trigger_error($definition->getDeprecationMessage($id), E_USER_DEPRECATED);
Chris@0 856 }
Chris@0 857
Chris@0 858 if ($tryProxy && $definition->isLazy()) {
Chris@0 859 $proxy = $this
Chris@0 860 ->getProxyInstantiator()
Chris@0 861 ->instantiateProxy(
Chris@0 862 $this,
Chris@0 863 $definition,
Chris@0 864 $id, function () use ($definition, $id) {
Chris@0 865 return $this->createService($definition, $id, false);
Chris@0 866 }
Chris@0 867 );
Chris@0 868 $this->shareService($definition, $proxy, $id);
Chris@0 869
Chris@0 870 return $proxy;
Chris@0 871 }
Chris@0 872
Chris@0 873 $parameterBag = $this->getParameterBag();
Chris@0 874
Chris@0 875 if (null !== $definition->getFile()) {
Chris@0 876 require_once $parameterBag->resolveValue($definition->getFile());
Chris@0 877 }
Chris@0 878
Chris@0 879 $arguments = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments())));
Chris@0 880
Chris@0 881 if (null !== $factory = $definition->getFactory()) {
Chris@0 882 if (is_array($factory)) {
Chris@0 883 $factory = array($this->resolveServices($parameterBag->resolveValue($factory[0])), $factory[1]);
Chris@0 884 } elseif (!is_string($factory)) {
Chris@0 885 throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
Chris@0 886 }
Chris@0 887
Chris@0 888 $service = call_user_func_array($factory, $arguments);
Chris@0 889
Chris@0 890 if (!$definition->isDeprecated() && is_array($factory) && is_string($factory[0])) {
Chris@0 891 $r = new \ReflectionClass($factory[0]);
Chris@0 892
Chris@0 893 if (0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
Chris@0 894 @trigger_error(sprintf('The "%s" service relies on the deprecated "%s" factory class. It should either be deprecated or its factory upgraded.', $id, $r->name), E_USER_DEPRECATED);
Chris@0 895 }
Chris@0 896 }
Chris@0 897 } else {
Chris@0 898 $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));
Chris@0 899
Chris@0 900 $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
Chris@0 901
Chris@0 902 if (!$definition->isDeprecated() && 0 < strpos($r->getDocComment(), "\n * @deprecated ")) {
Chris@0 903 @trigger_error(sprintf('The "%s" service relies on the deprecated "%s" class. It should either be deprecated or its implementation upgraded.', $id, $r->name), E_USER_DEPRECATED);
Chris@0 904 }
Chris@0 905 }
Chris@0 906
Chris@0 907 if ($tryProxy || !$definition->isLazy()) {
Chris@0 908 // share only if proxying failed, or if not a proxy
Chris@0 909 $this->shareService($definition, $service, $id);
Chris@0 910 }
Chris@0 911
Chris@0 912 $properties = $this->resolveServices($parameterBag->unescapeValue($parameterBag->resolveValue($definition->getProperties())));
Chris@0 913 foreach ($properties as $name => $value) {
Chris@0 914 $service->$name = $value;
Chris@0 915 }
Chris@0 916
Chris@0 917 foreach ($definition->getMethodCalls() as $call) {
Chris@0 918 $this->callMethod($service, $call);
Chris@0 919 }
Chris@0 920
Chris@0 921 if ($callable = $definition->getConfigurator()) {
Chris@0 922 if (is_array($callable)) {
Chris@0 923 $callable[0] = $parameterBag->resolveValue($callable[0]);
Chris@0 924
Chris@0 925 if ($callable[0] instanceof Reference) {
Chris@0 926 $callable[0] = $this->get((string) $callable[0], $callable[0]->getInvalidBehavior());
Chris@0 927 } elseif ($callable[0] instanceof Definition) {
Chris@0 928 $callable[0] = $this->createService($callable[0], null);
Chris@0 929 }
Chris@0 930 }
Chris@0 931
Chris@0 932 if (!is_callable($callable)) {
Chris@0 933 throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service)));
Chris@0 934 }
Chris@0 935
Chris@0 936 call_user_func($callable, $service);
Chris@0 937 }
Chris@0 938
Chris@0 939 return $service;
Chris@0 940 }
Chris@0 941
Chris@0 942 /**
Chris@0 943 * Replaces service references by the real service instance and evaluates expressions.
Chris@0 944 *
Chris@0 945 * @param mixed $value A value
Chris@0 946 *
Chris@0 947 * @return mixed The same value with all service references replaced by
Chris@0 948 * the real service instances and all expressions evaluated
Chris@0 949 */
Chris@0 950 public function resolveServices($value)
Chris@0 951 {
Chris@0 952 if (is_array($value)) {
Chris@0 953 foreach ($value as $k => $v) {
Chris@0 954 $value[$k] = $this->resolveServices($v);
Chris@0 955 }
Chris@0 956 } elseif ($value instanceof Reference) {
Chris@0 957 $value = $this->get((string) $value, $value->getInvalidBehavior());
Chris@0 958 } elseif ($value instanceof Definition) {
Chris@0 959 $value = $this->createService($value, null);
Chris@0 960 } elseif ($value instanceof Expression) {
Chris@0 961 $value = $this->getExpressionLanguage()->evaluate($value, array('container' => $this));
Chris@0 962 }
Chris@0 963
Chris@0 964 return $value;
Chris@0 965 }
Chris@0 966
Chris@0 967 /**
Chris@0 968 * Returns service ids for a given tag.
Chris@0 969 *
Chris@0 970 * Example:
Chris@0 971 *
Chris@0 972 * $container->register('foo')->addTag('my.tag', array('hello' => 'world'));
Chris@0 973 *
Chris@0 974 * $serviceIds = $container->findTaggedServiceIds('my.tag');
Chris@0 975 * foreach ($serviceIds as $serviceId => $tags) {
Chris@0 976 * foreach ($tags as $tag) {
Chris@0 977 * echo $tag['hello'];
Chris@0 978 * }
Chris@0 979 * }
Chris@0 980 *
Chris@0 981 * @param string $name The tag name
Chris@0 982 *
Chris@0 983 * @return array An array of tags with the tagged service as key, holding a list of attribute arrays
Chris@0 984 */
Chris@0 985 public function findTaggedServiceIds($name)
Chris@0 986 {
Chris@0 987 $this->usedTags[] = $name;
Chris@0 988 $tags = array();
Chris@0 989 foreach ($this->getDefinitions() as $id => $definition) {
Chris@0 990 if ($definition->hasTag($name)) {
Chris@0 991 $tags[$id] = $definition->getTag($name);
Chris@0 992 }
Chris@0 993 }
Chris@0 994
Chris@0 995 return $tags;
Chris@0 996 }
Chris@0 997
Chris@0 998 /**
Chris@0 999 * Returns all tags the defined services use.
Chris@0 1000 *
Chris@0 1001 * @return array An array of tags
Chris@0 1002 */
Chris@0 1003 public function findTags()
Chris@0 1004 {
Chris@0 1005 $tags = array();
Chris@0 1006 foreach ($this->getDefinitions() as $id => $definition) {
Chris@0 1007 $tags = array_merge(array_keys($definition->getTags()), $tags);
Chris@0 1008 }
Chris@0 1009
Chris@0 1010 return array_unique($tags);
Chris@0 1011 }
Chris@0 1012
Chris@0 1013 /**
Chris@0 1014 * Returns all tags not queried by findTaggedServiceIds.
Chris@0 1015 *
Chris@0 1016 * @return string[] An array of tags
Chris@0 1017 */
Chris@0 1018 public function findUnusedTags()
Chris@0 1019 {
Chris@0 1020 return array_values(array_diff($this->findTags(), $this->usedTags));
Chris@0 1021 }
Chris@0 1022
Chris@0 1023 public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
Chris@0 1024 {
Chris@0 1025 $this->expressionLanguageProviders[] = $provider;
Chris@0 1026 }
Chris@0 1027
Chris@0 1028 /**
Chris@0 1029 * @return ExpressionFunctionProviderInterface[]
Chris@0 1030 */
Chris@0 1031 public function getExpressionLanguageProviders()
Chris@0 1032 {
Chris@0 1033 return $this->expressionLanguageProviders;
Chris@0 1034 }
Chris@0 1035
Chris@0 1036 /**
Chris@0 1037 * Resolves env parameter placeholders in a string or an array.
Chris@0 1038 *
Chris@0 1039 * @param mixed $value The value to resolve
Chris@0 1040 * @param string|null $format A sprintf() format to use as replacement for env placeholders or null to use the default parameter format
Chris@0 1041 * @param array &$usedEnvs Env vars found while resolving are added to this array
Chris@0 1042 *
Chris@0 1043 * @return string The string with env parameters resolved
Chris@0 1044 */
Chris@0 1045 public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null)
Chris@0 1046 {
Chris@0 1047 if (null === $format) {
Chris@0 1048 $format = '%%env(%s)%%';
Chris@0 1049 }
Chris@0 1050
Chris@0 1051 if (is_array($value)) {
Chris@0 1052 $result = array();
Chris@0 1053 foreach ($value as $k => $v) {
Chris@0 1054 $result[$this->resolveEnvPlaceholders($k, $format, $usedEnvs)] = $this->resolveEnvPlaceholders($v, $format, $usedEnvs);
Chris@0 1055 }
Chris@0 1056
Chris@0 1057 return $result;
Chris@0 1058 }
Chris@0 1059
Chris@0 1060 if (!is_string($value)) {
Chris@0 1061 return $value;
Chris@0 1062 }
Chris@0 1063
Chris@0 1064 $bag = $this->getParameterBag();
Chris@0 1065 $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders;
Chris@0 1066
Chris@0 1067 foreach ($envPlaceholders as $env => $placeholders) {
Chris@0 1068 foreach ($placeholders as $placeholder) {
Chris@0 1069 if (false !== stripos($value, $placeholder)) {
Chris@0 1070 $value = str_ireplace($placeholder, sprintf($format, $env), $value);
Chris@0 1071 $usedEnvs[$env] = $env;
Chris@0 1072 $this->envCounters[$env] = isset($this->envCounters[$env]) ? 1 + $this->envCounters[$env] : 1;
Chris@0 1073 }
Chris@0 1074 }
Chris@0 1075 }
Chris@0 1076
Chris@0 1077 return $value;
Chris@0 1078 }
Chris@0 1079
Chris@0 1080 /**
Chris@0 1081 * Get statistics about env usage.
Chris@0 1082 *
Chris@0 1083 * @return int[] The number of time each env vars has been resolved
Chris@0 1084 */
Chris@0 1085 public function getEnvCounters()
Chris@0 1086 {
Chris@0 1087 $bag = $this->getParameterBag();
Chris@0 1088 $envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders;
Chris@0 1089
Chris@0 1090 foreach ($envPlaceholders as $env => $placeholders) {
Chris@0 1091 if (!isset($this->envCounters[$env])) {
Chris@0 1092 $this->envCounters[$env] = 0;
Chris@0 1093 }
Chris@0 1094 }
Chris@0 1095
Chris@0 1096 return $this->envCounters;
Chris@0 1097 }
Chris@0 1098
Chris@0 1099 /**
Chris@0 1100 * Returns the Service Conditionals.
Chris@0 1101 *
Chris@0 1102 * @param mixed $value An array of conditionals to return
Chris@0 1103 *
Chris@0 1104 * @return array An array of Service conditionals
Chris@0 1105 */
Chris@0 1106 public static function getServiceConditionals($value)
Chris@0 1107 {
Chris@0 1108 $services = array();
Chris@0 1109
Chris@0 1110 if (is_array($value)) {
Chris@0 1111 foreach ($value as $v) {
Chris@0 1112 $services = array_unique(array_merge($services, self::getServiceConditionals($v)));
Chris@0 1113 }
Chris@0 1114 } elseif ($value instanceof Reference && $value->getInvalidBehavior() === ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
Chris@0 1115 $services[] = (string) $value;
Chris@0 1116 }
Chris@0 1117
Chris@0 1118 return $services;
Chris@0 1119 }
Chris@0 1120
Chris@0 1121 /**
Chris@0 1122 * Retrieves the currently set proxy instantiator or instantiates one.
Chris@0 1123 *
Chris@0 1124 * @return InstantiatorInterface
Chris@0 1125 */
Chris@0 1126 private function getProxyInstantiator()
Chris@0 1127 {
Chris@0 1128 if (!$this->proxyInstantiator) {
Chris@0 1129 $this->proxyInstantiator = new RealServiceInstantiator();
Chris@0 1130 }
Chris@0 1131
Chris@0 1132 return $this->proxyInstantiator;
Chris@0 1133 }
Chris@0 1134
Chris@0 1135 private function callMethod($service, $call)
Chris@0 1136 {
Chris@0 1137 $services = self::getServiceConditionals($call[1]);
Chris@0 1138
Chris@0 1139 foreach ($services as $s) {
Chris@0 1140 if (!$this->has($s)) {
Chris@0 1141 return;
Chris@0 1142 }
Chris@0 1143 }
Chris@0 1144
Chris@0 1145 call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->unescapeValue($this->getParameterBag()->resolveValue($call[1]))));
Chris@0 1146 }
Chris@0 1147
Chris@0 1148 /**
Chris@0 1149 * Shares a given service in the container.
Chris@0 1150 *
Chris@0 1151 * @param Definition $definition
Chris@0 1152 * @param mixed $service
Chris@0 1153 * @param string|null $id
Chris@0 1154 */
Chris@0 1155 private function shareService(Definition $definition, $service, $id)
Chris@0 1156 {
Chris@0 1157 if (null !== $id && $definition->isShared()) {
Chris@0 1158 $this->services[strtolower($id)] = $service;
Chris@0 1159 }
Chris@0 1160 }
Chris@0 1161
Chris@0 1162 private function getExpressionLanguage()
Chris@0 1163 {
Chris@0 1164 if (null === $this->expressionLanguage) {
Chris@0 1165 if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
Chris@0 1166 throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
Chris@0 1167 }
Chris@0 1168 $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
Chris@0 1169 }
Chris@0 1170
Chris@0 1171 return $this->expressionLanguage;
Chris@0 1172 }
Chris@0 1173 }