Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 882 lines (771 sloc) 24.564 kb
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
1 <?php
2
0a64b22 @blue-eyes normalized license messages in PHP files
blue-eyes authored
3 /*
4 * This file is part of the Symfony package.
5 *
61b0a27 @fabpot replaced symfony-project.org by symfony.com
fabpot authored
6 * (c) Fabien Potencier <fabien@symfony.com>
0a64b22 @blue-eyes normalized license messages in PHP files
blue-eyes authored
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
12 namespace Symfony\Component\DependencyInjection;
13
29efab1 @schmittjoh [DependencyInjection] performance improvement, better analysis tools
schmittjoh authored
14 use Symfony\Component\DependencyInjection\Compiler\Compiler;
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
15 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
b62db3b @fabpot [DependencyInjection] added the possibility to pass the type of compiler...
fabpot authored
16 use Symfony\Component\DependencyInjection\Compiler\PassConfig;
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
17 use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
18 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
19 use Symfony\Component\DependencyInjection\Exception\LogicException;
20 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
21 use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
26f2c42 @fabpot moved common configuration classes to a new Config component
fabpot authored
22 use Symfony\Component\Config\Resource\FileResource;
23 use Symfony\Component\Config\Resource\ResourceInterface;
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
24
25 /**
26 * ContainerBuilder is a DI container that provides an API to easily describe services.
27 *
61b0a27 @fabpot replaced symfony-project.org by symfony.com
fabpot authored
28 * @author Fabien Potencier <fabien@symfony.com>
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
29 *
30 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
31 */
32 class ContainerBuilder extends Container implements TaggedContainerInterface
33 {
ad50e47 @fabpot [DependencyInjection] moved most protected things to private
fabpot authored
34 private $extensions = array();
35 private $extensionsByNs = array();
36 private $definitions = array();
37 private $aliases = array();
38 private $resources = array();
39 private $extensionConfigs = array();
40 private $compiler;
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
41
42 /**
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
43 * Registers an extension.
44 *
45 * @param ExtensionInterface $extension An extension instance
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
46 *
47 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
48 */
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
49 public function registerExtension(ExtensionInterface $extension)
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
50 {
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
51 $this->extensions[$extension->getAlias()] = $extension;
6161496 @fabpot [DependencyInjection] made getXsdValidationBasePath() and getNamespace()...
fabpot authored
52
53 if (false !== $extension->getNamespace()) {
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
54 $this->extensionsByNs[$extension->getNamespace()] = $extension;
6161496 @fabpot [DependencyInjection] made getXsdValidationBasePath() and getNamespace()...
fabpot authored
55 }
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
56 }
57
58 /**
59 * Returns an extension by alias or namespace.
60 *
61 * @param string $name An alias or a namespace
62 *
63 * @return ExtensionInterface An extension instance
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
64 *
9f7eeb8 @stof Fixed the phpdoc in the DependencyInjection component
stof authored
65 * @throws \LogicException if the extension is not registered
66 *
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
67 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
68 */
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
69 public function getExtension($name)
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
70 {
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
71 if (isset($this->extensions[$name])) {
72 return $this->extensions[$name];
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
73 }
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
74
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
75 if (isset($this->extensionsByNs[$name])) {
76 return $this->extensionsByNs[$name];
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
77 }
78
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
79 throw new LogicException(sprintf('Container extension "%s" is not registered', $name));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
80 }
81
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
82 /**
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
83 * Returns all registered extensions.
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
84 *
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
85 * @return array An array of ExtensionInterface
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
86 *
87 * @api
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
88 */
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
89 public function getExtensions()
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
90 {
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
91 return $this->extensions;
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
92 }
93
94 /**
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
95 * Checks if we have an extension.
96 *
97 * @param string $name The name of the extension
b673fef @fabpot [DoctrineBridge] fixed some CS
fabpot authored
98 *
5094a5c @eriksencosta capitalized 'boolean'
eriksencosta authored
99 * @return Boolean If the extension exists
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
100 *
101 * @api
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
102 */
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
103 public function hasExtension($name)
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
104 {
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
105 return isset($this->extensions[$name]) || isset($this->extensionsByNs[$name]);
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
106 }
107
108 /**
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
109 * Returns an array of resources loaded to build this configuration.
110 *
111 * @return ResourceInterface[] An array of resources
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
112 *
113 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
114 */
115 public function getResources()
116 {
117 return array_unique($this->resources);
118 }
119
120 /**
121 * Adds a resource for this configuration.
122 *
123 * @param ResourceInterface $resource A resource instance
124 *
125 * @return ContainerBuilder The current instance
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
126 *
127 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
128 */
129 public function addResource(ResourceInterface $resource)
130 {
131 $this->resources[] = $resource;
132
133 return $this;
134 }
135
9356fac @schmittjoh added some missing accessors/mutators
schmittjoh authored
136 public function setResources(array $resources)
137 {
138 $this->resources = $resources;
139
140 return $this;
141 }
142
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
143 /**
144 * Adds the object class hierarchy as resources.
145 *
146 * @param object $object An object instance
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
147 *
148 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
149 */
150 public function addObjectResource($object)
151 {
152 $parent = new \ReflectionObject($object);
8a72b4f @vicb Container builder tweaks
vicb authored
153 do {
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
154 $this->addResource(new FileResource($parent->getFileName()));
8a72b4f @vicb Container builder tweaks
vicb authored
155 } while ($parent = $parent->getParentClass());
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
156 }
157
158 /**
159 * Loads the configuration for an extension.
160 *
161 * @param string $extension The extension alias or namespace
162 * @param array $values An array of values that customizes the extension
163 *
164 * @return ContainerBuilder The current instance
577e256 @jmikola [DependencyInjection] Make exceptions consistent when ContainerBuilder i...
jmikola authored
165 * @throws BadMethodCallException When this ContainerBuilder is frozen
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
166 *
9f7eeb8 @stof Fixed the phpdoc in the DependencyInjection component
stof authored
167 * @throws \LogicException if the container is frozen
168 *
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
169 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
170 */
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
171 public function loadFromExtension($extension, array $values = array())
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
172 {
577e256 @jmikola [DependencyInjection] Make exceptions consistent when ContainerBuilder i...
jmikola authored
173 if ($this->isFrozen()) {
174 throw new BadMethodCallException('Cannot load from an extension on a frozen container.');
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
175 }
176
c407c84 @fabpot [DependencyInjection] moved extension loading in the freezing process (o...
fabpot authored
177 $namespace = $this->getExtension($extension)->getAlias();
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
178
47207c3 @arnaud-lb delay resolving values of extensions config until all files are loaded
arnaud-lb authored
179 $this->extensionConfigs[$namespace][] = $values;
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
180
181 return $this;
182 }
183
184 /**
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
185 * Adds a compiler pass.
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
186 *
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
187 * @param CompilerPassInterface $pass A compiler pass
188 * @param string $type The type of compiler pass
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
189 *
190 * @api
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
191 */
b62db3b @fabpot [DependencyInjection] added the possibility to pass the type of compiler...
fabpot authored
192 public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
193 {
4f69a95 @kriswallsmith [DependencyInjection] made compiler lazy again since there are many temp...
kriswallsmith authored
194 if (null === $this->compiler) {
195 $this->compiler = new Compiler();
196 }
197
b62db3b @fabpot [DependencyInjection] added the possibility to pass the type of compiler...
fabpot authored
198 $this->compiler->addPass($pass, $type);
ed71c49 @fabpot [DependencyInjection] added compiler passes as resources
fabpot authored
199
200 $this->addObjectResource($pass);
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
201 }
202
203 /**
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
204 * Returns the compiler pass config which can then be modified.
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
205 *
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
206 * @return PassConfig The compiler pass config
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
207 *
208 * @api
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
209 */
d3e398c @schmittjoh tweaked DI container
schmittjoh authored
210 public function getCompilerPassConfig()
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
211 {
4f69a95 @kriswallsmith [DependencyInjection] made compiler lazy again since there are many temp...
kriswallsmith authored
212 if (null === $this->compiler) {
213 $this->compiler = new Compiler();
214 }
215
29efab1 @schmittjoh [DependencyInjection] performance improvement, better analysis tools
schmittjoh authored
216 return $this->compiler->getPassConfig();
217 }
218
219 /**
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
220 * Returns the compiler.
29efab1 @schmittjoh [DependencyInjection] performance improvement, better analysis tools
schmittjoh authored
221 *
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
222 * @return Compiler The compiler
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
223 *
224 * @api
29efab1 @schmittjoh [DependencyInjection] performance improvement, better analysis tools
schmittjoh authored
225 */
226 public function getCompiler()
227 {
4f69a95 @kriswallsmith [DependencyInjection] made compiler lazy again since there are many temp...
kriswallsmith authored
228 if (null === $this->compiler) {
229 $this->compiler = new Compiler();
230 }
231
29efab1 @schmittjoh [DependencyInjection] performance improvement, better analysis tools
schmittjoh authored
232 return $this->compiler;
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
233 }
234
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
235 /**
236 * Returns all Scopes.
237 *
238 * @return array An array of scopes
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
239 *
240 * @api
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
241 */
9a2bb12 @schmittjoh adds scope to the DI container
schmittjoh authored
242 public function getScopes()
243 {
244 return $this->scopes;
245 }
246
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
247 /**
18147c5 @pborreli [Various] Fixed typo
pborreli authored
248 * Returns all Scope children.
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
249 *
250 * @return array An array of scope children.
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
251 *
252 * @api
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
253 */
9a2bb12 @schmittjoh adds scope to the DI container
schmittjoh authored
254 public function getScopeChildren()
255 {
256 return $this->scopeChildren;
257 }
258
3b7f997 @schmittjoh slight compiler refactoring (RFC)
schmittjoh authored
259 /**
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
260 * Sets a service.
261 *
262 * @param string $id The service identifier
263 * @param object $service The service instance
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
264 * @param string $scope The scope
ea6646d @avalanche123 [DependencyInjection] Interface Injection implementation
avalanche123 authored
265 *
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
266 * @throws BadMethodCallException When this ContainerBuilder is frozen
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
267 *
268 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
269 */
9a2bb12 @schmittjoh adds scope to the DI container
schmittjoh authored
270 public function set($id, $service, $scope = self::SCOPE_CONTAINER)
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
271 {
ea6646d @avalanche123 [DependencyInjection] Interface Injection implementation
avalanche123 authored
272 if ($this->isFrozen()) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
273 throw new BadMethodCallException('Setting service on a frozen container is not allowed');
ea6646d @avalanche123 [DependencyInjection] Interface Injection implementation
avalanche123 authored
274 }
275
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
276 $id = strtolower($id);
277
8a72b4f @vicb Container builder tweaks
vicb authored
278 unset($this->definitions[$id], $this->aliases[$id]);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
279
9a2bb12 @schmittjoh adds scope to the DI container
schmittjoh authored
280 parent::set($id, $service, $scope);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
281 }
282
283 /**
5e2d688 @kriswallsmith [DependencyInjection] renamed ContainerBuilder::remove() as removeDefini...
kriswallsmith authored
284 * Removes a service definition.
9d705ed @fabpot [DependencyInjection] added methods to remove an alias and a definition ...
fabpot authored
285 *
286 * @param string $id The service identifier
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
287 *
288 * @api
9d705ed @fabpot [DependencyInjection] added methods to remove an alias and a definition ...
fabpot authored
289 */
5e2d688 @kriswallsmith [DependencyInjection] renamed ContainerBuilder::remove() as removeDefini...
kriswallsmith authored
290 public function removeDefinition($id)
9d705ed @fabpot [DependencyInjection] added methods to remove an alias and a definition ...
fabpot authored
291 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
292 unset($this->definitions[strtolower($id)]);
9d705ed @fabpot [DependencyInjection] added methods to remove an alias and a definition ...
fabpot authored
293 }
294
295 /**
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
296 * Returns true if the given service is defined.
297 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
298 * @param string $id The service identifier
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
299 *
300 * @return Boolean true if the service is defined, false otherwise
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
301 *
302 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
303 */
304 public function has($id)
305 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
306 $id = strtolower($id);
307
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
308 return isset($this->definitions[$id]) || isset($this->aliases[$id]) || parent::has($id);
309 }
310
311 /**
312 * Gets a service.
313 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
314 * @param string $id The service identifier
315 * @param integer $invalidBehavior The behavior when the service does not exist
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
316 *
317 * @return object The associated service
318 *
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
319 * @throws InvalidArgumentException if the service is not defined
320 * @throws LogicException if the service has a circular reference to itself
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
321 *
322 * @see Reference
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
323 *
324 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
325 */
326 public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
327 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
328 $id = strtolower($id);
329
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
330 try {
331 return parent::get($id, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
332 } catch (InvalidArgumentException $e) {
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
333 if (isset($this->loading[$id])) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
334 throw new LogicException(sprintf('The service "%s" has a circular reference to itself.', $id), 0, $e);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
335 }
336
337 if (!$this->hasDefinition($id) && isset($this->aliases[$id])) {
338 return $this->get($this->aliases[$id]);
339 }
340
341 try {
342 $definition = $this->getDefinition($id);
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
343 } catch (InvalidArgumentException $e) {
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
344 if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
345 return null;
346 }
347
348 throw $e;
349 }
350
351 $this->loading[$id] = true;
352
353 $service = $this->createService($definition, $id);
354
355 unset($this->loading[$id]);
356
357 return $service;
358 }
359 }
360
361 /**
362 * Merges a ContainerBuilder with the current ContainerBuilder configuration.
363 *
364 * Service definitions overrides the current defined ones.
365 *
366 * But for parameters, they are overridden by the current ones. It allows
367 * the parameters passed to the container constructor to have precedence
368 * over the loaded ones.
369 *
370 * $container = new ContainerBuilder(array('foo' => 'bar'));
371 * $loader = new LoaderXXX($container);
372 * $loader->load('resource_name');
373 * $container->register('foo', new stdClass());
374 *
375 * In the above example, even if the loaded resource defines a foo
376 * parameter, the value will still be 'bar' as defined in the ContainerBuilder
377 * constructor.
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
378 *
379 * @param ContainerBuilder $container The ContainerBuilder instance to merge.
577e256 @jmikola [DependencyInjection] Make exceptions consistent when ContainerBuilder i...
jmikola authored
380 *
f454528 @fabpot merged 2.0
fabpot authored
381 *
577e256 @jmikola [DependencyInjection] Make exceptions consistent when ContainerBuilder i...
jmikola authored
382 * @throws BadMethodCallException When this ContainerBuilder is frozen
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
383 *
384 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
385 */
386 public function merge(ContainerBuilder $container)
387 {
577e256 @jmikola [DependencyInjection] Make exceptions consistent when ContainerBuilder i...
jmikola authored
388 if ($this->isFrozen()) {
389 throw new BadMethodCallException('Cannot merge on a frozen container.');
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
390 }
391
392 $this->addDefinitions($container->getDefinitions());
393 $this->addAliases($container->getAliases());
ad50e47 @fabpot [DependencyInjection] moved most protected things to private
fabpot authored
394 $this->getParameterBag()->add($container->getParameterBag()->all());
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
395
396 foreach ($container->getResources() as $resource) {
397 $this->addResource($resource);
398 }
399
43ea87a @fabpot made DIC extensions members of the Container instead of static members
fabpot authored
400 foreach ($this->extensions as $name => $extension) {
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
401 if (!isset($this->extensionConfigs[$name])) {
402 $this->extensionConfigs[$name] = array();
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
403 }
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
404
405 $this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
406 }
407 }
408
409 /**
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
410 * Returns the configuration array for the given extension.
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
411 *
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
412 * @param string $name The name of the extension
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
413 *
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
414 * @return array An array of configuration
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
415 *
416 * @api
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
417 */
418 public function getExtensionConfig($name)
419 {
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
420 if (!isset($this->extensionConfigs[$name])) {
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
421 $this->extensionConfigs[$name] = array();
21c0068 @lsmith77 implicitly load all registered bundles, all loading is now handled by lo...
lsmith77 authored
422 }
423
424 return $this->extensionConfigs[$name];
425 }
426
427 /**
39fd519 @fabpot renamed Container::freeze() to Container::compile()
fabpot authored
428 * Compiles the container.
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
429 *
39fd519 @fabpot renamed Container::freeze() to Container::compile()
fabpot authored
430 * This method passes the container to compiler
431 * passes whose job is to manipulate and optimize
432 * the container.
433 *
434 * The main compiler passes roughly do four things:
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
435 *
436 * * The extension configurations are merged;
437 * * Parameter values are resolved;
39fd519 @fabpot renamed Container::freeze() to Container::compile()
fabpot authored
438 * * The parameter bag is frozen;
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
439 * * Extension loading is disabled.
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
440 *
441 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
442 */
39fd519 @fabpot renamed Container::freeze() to Container::compile()
fabpot authored
443 public function compile()
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
444 {
4f69a95 @kriswallsmith [DependencyInjection] made compiler lazy again since there are many temp...
kriswallsmith authored
445 if (null === $this->compiler) {
446 $this->compiler = new Compiler();
447 }
448
0e12c55 @kriswallsmith [DependencyInjection] extensions should only load if called during confi...
kriswallsmith authored
449 foreach ($this->compiler->getPassConfig()->getPasses() as $pass) {
450 $this->addObjectResource($pass);
aa20917 @schmittjoh lazy-load the compiler, and related objects
schmittjoh authored
451 }
452
29efab1 @schmittjoh [DependencyInjection] performance improvement, better analysis tools
schmittjoh authored
453 $this->compiler->compile($this);
ea6646d @avalanche123 [DependencyInjection] Interface Injection implementation
avalanche123 authored
454
185bae4 @fabpot refactored previous commit, fixed tests
fabpot authored
455 $this->extensionConfigs = array();
5b55f4b @fabpot added a way for any extension to add classes to the class cache
fabpot authored
456
39fd519 @fabpot renamed Container::freeze() to Container::compile()
fabpot authored
457 parent::compile();
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
458 }
459
460 /**
461 * Gets all service ids.
462 *
463 * @return array An array of all defined service ids
464 */
465 public function getServiceIds()
466 {
467 return array_unique(array_merge(array_keys($this->getDefinitions()), array_keys($this->aliases), parent::getServiceIds()));
468 }
469
470 /**
471 * Adds the service aliases.
472 *
473 * @param array $aliases An array of aliases
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
474 *
475 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
476 */
477 public function addAliases(array $aliases)
478 {
479 foreach ($aliases as $alias => $id) {
480 $this->setAlias($alias, $id);
481 }
482 }
483
484 /**
485 * Sets the service aliases.
486 *
d3ea690 @pborreli [Phpdoc] Cleaning/fixing
pborreli authored
487 * @param array $aliases An array of service definitions
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
488 *
489 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
490 */
491 public function setAliases(array $aliases)
492 {
493 $this->aliases = array();
494 $this->addAliases($aliases);
495 }
496
497 /**
498 * Sets an alias for an existing service.
499 *
9f7eeb8 @stof Fixed the phpdoc in the DependencyInjection component
stof authored
500 * @param string $alias The alias to create
501 * @param string|Alias $id The service to alias
502 *
503 * @throws \InvalidArgumentException if the id is not a string or an Alias
504 * @throws \InvalidArgumentException if the alias is for itself
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
505 *
506 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
507 */
508 public function setAlias($alias, $id)
509 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
510 $alias = strtolower($alias);
aa1255f @schmittjoh adds visibility to aliases
schmittjoh authored
511
512 if (is_string($id)) {
513 $id = new Alias($id);
7aad3a4 @fabpot fixed CS
fabpot authored
514 } elseif (!$id instanceof Alias) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
515 throw new InvalidArgumentException('$id must be a string, or an Alias object.');
aa1255f @schmittjoh adds visibility to aliases
schmittjoh authored
516 }
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
517
315f96d @Seldaek [DepdenencyInjection] Prevent self-referencing aliases
Seldaek authored
518 if ($alias === strtolower($id)) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
519 throw new InvalidArgumentException('An alias can not reference itself, got a circular reference on "'.$alias.'".');
315f96d @Seldaek [DepdenencyInjection] Prevent self-referencing aliases
Seldaek authored
520 }
521
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
522 unset($this->definitions[$alias]);
523
524 $this->aliases[$alias] = $id;
525 }
526
527 /**
9d705ed @fabpot [DependencyInjection] added methods to remove an alias and a definition ...
fabpot authored
528 * Removes an alias.
529 *
530 * @param string $alias The alias to remove
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
531 *
532 * @api
9d705ed @fabpot [DependencyInjection] added methods to remove an alias and a definition ...
fabpot authored
533 */
534 public function removeAlias($alias)
535 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
536 unset($this->aliases[strtolower($alias)]);
9d705ed @fabpot [DependencyInjection] added methods to remove an alias and a definition ...
fabpot authored
537 }
538
539 /**
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
540 * Returns true if an alias exists under the given identifier.
541 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
542 * @param string $id The service identifier
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
543 *
544 * @return Boolean true if the alias exists, false otherwise
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
545 *
546 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
547 */
548 public function hasAlias($id)
549 {
aa1255f @schmittjoh adds visibility to aliases
schmittjoh authored
550 return isset($this->aliases[strtolower($id)]);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
551 }
552
553 /**
554 * Gets all defined aliases.
555 *
9f7eeb8 @stof Fixed the phpdoc in the DependencyInjection component
stof authored
556 * @return Alias[] An array of aliases
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
557 *
558 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
559 */
560 public function getAliases()
561 {
562 return $this->aliases;
563 }
564
565 /**
566 * Gets an alias.
567 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
568 * @param string $id The service identifier
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
569 *
4c6d8ed @lsmith77 corrected phpdoc
lsmith77 authored
570 * @return Alias An Alias instance
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
571 *
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
572 * @throws InvalidArgumentException if the alias does not exist
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
573 *
574 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
575 */
576 public function getAlias($id)
577 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
578 $id = strtolower($id);
579
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
580 if (!$this->hasAlias($id)) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
581 throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
582 }
583
584 return $this->aliases[$id];
585 }
586
13d7b04 @jmikola [DependencyInjection] Add hasInterfaceInjectorForClass(), which is helpf...
jmikola authored
587 /**
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
588 * Registers a service definition.
589 *
590 * This methods allows for simple registration of service definition
591 * with a fluid interface.
592 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
593 * @param string $id The service identifier
594 * @param string $class The service class
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
595 *
596 * @return Definition A Definition instance
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
597 *
598 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
599 */
600 public function register($id, $class = null)
601 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
602 return $this->setDefinition(strtolower($id), new Definition($class));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
603 }
604
605 /**
606 * Adds the service definitions.
607 *
608 * @param Definition[] $definitions An array of service definitions
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
609 *
610 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
611 */
612 public function addDefinitions(array $definitions)
613 {
614 foreach ($definitions as $id => $definition) {
615 $this->setDefinition($id, $definition);
616 }
617 }
618
619 /**
620 * Sets the service definitions.
621 *
622 * @param array $definitions An array of service definitions
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
623 *
624 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
625 */
626 public function setDefinitions(array $definitions)
627 {
628 $this->definitions = array();
629 $this->addDefinitions($definitions);
630 }
631
632 /**
633 * Gets all service definitions.
634 *
9f7eeb8 @stof Fixed the phpdoc in the DependencyInjection component
stof authored
635 * @return Definition[] An array of Definition instances
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
636 *
637 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
638 */
639 public function getDefinitions()
640 {
641 return $this->definitions;
642 }
643
644 /**
645 * Sets a service definition.
646 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
647 * @param string $id The service identifier
648 * @param Definition $definition A Definition instance
ea6646d @avalanche123 [DependencyInjection] Interface Injection implementation
avalanche123 authored
649 *
9f7eeb8 @stof Fixed the phpdoc in the DependencyInjection component
stof authored
650 * @return Definition the service definition
651 *
59b5e7f @jmikola [DependencyInjection] Fix up @throws documentation
jmikola authored
652 * @throws BadMethodCallException When this ContainerBuilder is frozen
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
653 *
654 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
655 */
656 public function setDefinition($id, Definition $definition)
657 {
ea6646d @avalanche123 [DependencyInjection] Interface Injection implementation
avalanche123 authored
658 if ($this->isFrozen()) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
659 throw new BadMethodCallException('Adding definition to a frozen container is not allowed');
ea6646d @avalanche123 [DependencyInjection] Interface Injection implementation
avalanche123 authored
660 }
661
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
662 $id = strtolower($id);
663
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
664 unset($this->aliases[$id]);
665
666 return $this->definitions[$id] = $definition;
667 }
668
669 /**
670 * Returns true if a service definition exists under the given identifier.
671 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
672 * @param string $id The service identifier
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
673 *
674 * @return Boolean true if the service definition exists, false otherwise
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
675 *
676 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
677 */
678 public function hasDefinition($id)
679 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
680 return array_key_exists(strtolower($id), $this->definitions);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
681 }
682
683 /**
684 * Gets a service definition.
685 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
686 * @param string $id The service identifier
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
687 *
688 * @return Definition A Definition instance
689 *
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
690 * @throws InvalidArgumentException if the service definition does not exist
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
691 *
692 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
693 */
694 public function getDefinition($id)
695 {
6faf516 @fabpot [DependencyInjection] made service keys and aliases case insensitive (as...
fabpot authored
696 $id = strtolower($id);
697
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
698 if (!$this->hasDefinition($id)) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
699 throw new InvalidArgumentException(sprintf('The service definition "%s" does not exist.', $id));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
700 }
701
702 return $this->definitions[$id];
703 }
704
705 /**
706 * Gets a service definition by id or alias.
707 *
708 * The method "unaliases" recursively to return a Definition instance.
709 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
710 * @param string $id The service identifier or alias
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
711 *
712 * @return Definition A Definition instance
713 *
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
714 * @throws InvalidArgumentException if the service definition does not exist
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
715 *
716 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
717 */
718 public function findDefinition($id)
719 {
1501c58 @fabpot [DependencyInjection] made a small performance optimization
fabpot authored
720 while ($this->hasAlias($id)) {
721 $id = (string) $this->getAlias($id);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
722 }
723
724 return $this->getDefinition($id);
725 }
726
727 /**
728 * Creates a service for a service definition.
729 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
730 * @param Definition $definition A service definition instance
731 * @param string $id The service identifier
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
732 *
9f7eeb8 @stof Fixed the phpdoc in the DependencyInjection component
stof authored
733 * @return object The service described by the service definition
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
734 *
cb04ee0 @fabpot merged 2.0
fabpot authored
735 * @throws RuntimeException When the scope is inactive
736 * @throws RuntimeException When the factory definition is incomplete
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
737 * @throws InvalidArgumentException When configure callable is not callable
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
738 */
ad50e47 @fabpot [DependencyInjection] moved most protected things to private
fabpot authored
739 private function createService(Definition $definition, $id)
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
740 {
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
741 $parameterBag = $this->getParameterBag();
742
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
743 if (null !== $definition->getFile()) {
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
744 require_once $parameterBag->resolveValue($definition->getFile());
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
745 }
746
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
747 $arguments = $this->resolveServices(
748 $parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments()))
749 );
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
750
751 if (null !== $definition->getFactoryMethod()) {
f4f013a @jmikola [DependencyInjection] Create explicit factoryClass property for Definiti...
jmikola authored
752 if (null !== $definition->getFactoryClass()) {
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
753 $factory = $parameterBag->resolveValue($definition->getFactoryClass());
f4f013a @jmikola [DependencyInjection] Create explicit factoryClass property for Definiti...
jmikola authored
754 } elseif (null !== $definition->getFactoryService()) {
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
755 $factory = $this->get($parameterBag->resolveValue($definition->getFactoryService()));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
756 } else {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
757 throw new RuntimeException('Cannot create service from factory method without a factory service or factory class.');
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
758 }
759
760 $service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments);
761 } else {
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
762 $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
763
764 $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
765 }
766
9a2bb12 @schmittjoh adds scope to the DI container
schmittjoh authored
767 if (self::SCOPE_PROTOTYPE !== $scope = $definition->getScope()) {
768 if (self::SCOPE_CONTAINER !== $scope && !isset($this->scopedServices[$scope])) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
769 throw new RuntimeException('You tried to create a service of an inactive scope.');
9a2bb12 @schmittjoh adds scope to the DI container
schmittjoh authored
770 }
771
772 $this->services[$lowerId = strtolower($id)] = $service;
773
774 if (self::SCOPE_CONTAINER !== $scope) {
775 $this->scopedServices[$scope][$lowerId] = $service;
776 }
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
777 }
778
779 foreach ($definition->getMethodCalls() as $call) {
780 $services = self::getServiceConditionals($call[1]);
781
782 $ok = true;
783 foreach ($services as $s) {
784 if (!$this->has($s)) {
785 $ok = false;
786 break;
787 }
788 }
789
790 if ($ok) {
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
791 call_user_func_array(array($service, $call[0]), $this->resolveServices($parameterBag->resolveValue($call[1])));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
792 }
793 }
794
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
795 $properties = $this->resolveServices($parameterBag->resolveValue($definition->getProperties()));
fcaf26a @schmittjoh [DependencyInjection] fixes a bug when requesting a definition that uses...
schmittjoh authored
796 foreach ($properties as $name => $value) {
b341592 @fabpot [DependencyInjection] removed injection for protected and private proper...
fabpot authored
797 $service->$name = $value;
fcaf26a @schmittjoh [DependencyInjection] fixes a bug when requesting a definition that uses...
schmittjoh authored
798 }
799
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
800 if ($callable = $definition->getConfigurator()) {
801 if (is_array($callable) && is_object($callable[0]) && $callable[0] instanceof Reference) {
802 $callable[0] = $this->get((string) $callable[0]);
803 } elseif (is_array($callable)) {
0bf1b13 @avorobiev [DependencyInjection] Fixed unescaping of class arguments
avorobiev authored
804 $callable[0] = $parameterBag->resolveValue($callable[0]);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
805 }
806
807 if (!is_callable($callable)) {
0294a5d @jmikola [DependencyInjection] Use component-specific SPL exceptions
jmikola authored
808 throw new InvalidArgumentException(sprintf('The configure callable for class "%s" is not a callable.', get_class($service)));
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
809 }
810
811 call_user_func($callable, $service);
812 }
813
814 return $service;
815 }
816
817 /**
818 * Replaces service references by the real service instance.
819 *
416b8a6 @fabpot fixed phpdoc @param alignment
fabpot authored
820 * @param mixed $value A value
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
821 *
822 * @return mixed The same value with all service references replaced by the real service instances
823 */
824 public function resolveServices($value)
825 {
826 if (is_array($value)) {
827 foreach ($value as &$v) {
828 $v = $this->resolveServices($v);
829 }
413a201 @everzet [DependencyInjection] create inlined private service from it's definitio...
everzet authored
830 } elseif (is_object($value) && $value instanceof Reference) {
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
831 $value = $this->get((string) $value, $value->getInvalidBehavior());
413a201 @everzet [DependencyInjection] create inlined private service from it's definitio...
everzet authored
832 } elseif (is_object($value) && $value instanceof Definition) {
833 $value = $this->createService($value, null);
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
834 }
835
836 return $value;
837 }
838
839 /**
840 * Returns service ids for a given tag.
841 *
842 * @param string $name The tag name
843 *
844 * @return array An array of tags
acc28a9 @fabpot [DependencyInjection] tagged the public @api
fabpot authored
845 *
846 * @api
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
847 */
848 public function findTaggedServiceIds($name)
849 {
850 $tags = array();
851 foreach ($this->getDefinitions() as $id => $definition) {
852 if ($definition->getTag($name)) {
853 $tags[$id] = $definition->getTag($name);
854 }
855 }
856
857 return $tags;
858 }
859
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
860 /**
861 * Returns the Service Conditionals.
862 *
863 * @param mixed $value An array of conditionals to return.
b673fef @fabpot [DoctrineBridge] fixed some CS
fabpot authored
864 *
2a19f42 @merk [Dependency Injection] PHPDoc
merk authored
865 * @return array An array of Service conditionals
866 */
803f11b @fabpot fixed CS
fabpot authored
867 public static function getServiceConditionals($value)
946ab15 @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
868 {
869 $services = array();
870
871 if (is_array($value)) {
872 foreach ($value as $v) {
873 $services = array_unique(array_merge($services, self::getServiceConditionals($v)));
874 }
875 } elseif (is_object($value) && $value instanceof Reference && $value->getInvalidBehavior() === ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
876 $services[] = (string) $value;
877 }
878
879 return $services;
880 }
881 }
Something went wrong with that request. Please try again.