Chris@0: Chris@0: * Chris@0: * For the full copyright and license information, please view the LICENSE Chris@0: * file that was distributed with this source code. Chris@0: */ Chris@0: Chris@0: namespace Symfony\Component\DependencyInjection; Chris@0: Chris@0: use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; Chris@0: use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException; Chris@0: Chris@0: /** Chris@0: * Definition represents a service definition. Chris@0: * Chris@0: * @author Fabien Potencier Chris@0: */ Chris@0: class Definition Chris@0: { Chris@0: private $class; Chris@0: private $file; Chris@0: private $factory; Chris@0: private $shared = true; Chris@0: private $deprecated = false; Chris@0: private $deprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.'; Chris@0: private $properties = array(); Chris@0: private $calls = array(); Chris@0: private $configurator; Chris@0: private $tags = array(); Chris@0: private $public = true; Chris@0: private $synthetic = false; Chris@0: private $abstract = false; Chris@0: private $lazy = false; Chris@0: private $decoratedService; Chris@0: private $autowired = false; Chris@0: private $autowiringTypes = array(); Chris@0: Chris@0: protected $arguments; Chris@0: Chris@0: /** Chris@0: * @param string|null $class The service class Chris@0: * @param array $arguments An array of arguments to pass to the service constructor Chris@0: */ Chris@0: public function __construct($class = null, array $arguments = array()) Chris@0: { Chris@0: $this->class = $class; Chris@0: $this->arguments = $arguments; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets a factory. Chris@0: * Chris@0: * @param string|array $factory A PHP function or an array containing a class/Reference and a method to call Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setFactory($factory) Chris@0: { Chris@0: if (is_string($factory) && strpos($factory, '::') !== false) { Chris@0: $factory = explode('::', $factory, 2); Chris@0: } Chris@0: Chris@0: $this->factory = $factory; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the factory. Chris@0: * Chris@0: * @return string|array The PHP function or an array containing a class/Reference and a method to call Chris@0: */ Chris@0: public function getFactory() Chris@0: { Chris@0: return $this->factory; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the service that this service is decorating. Chris@0: * Chris@0: * @param null|string $id The decorated service id, use null to remove decoration Chris@0: * @param null|string $renamedId The new decorated service id Chris@0: * @param int $priority The priority of decoration Chris@0: * Chris@0: * @return $this Chris@0: * Chris@0: * @throws InvalidArgumentException In case the decorated service id and the new decorated service id are equals. Chris@0: */ Chris@0: public function setDecoratedService($id, $renamedId = null, $priority = 0) Chris@0: { Chris@0: if ($renamedId && $id == $renamedId) { Chris@0: throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id)); Chris@0: } Chris@0: Chris@0: if (null === $id) { Chris@0: $this->decoratedService = null; Chris@0: } else { Chris@0: $this->decoratedService = array($id, $renamedId, (int) $priority); Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the service that this service is decorating. Chris@0: * Chris@0: * @return null|array An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated Chris@0: */ Chris@0: public function getDecoratedService() Chris@0: { Chris@0: return $this->decoratedService; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the service class. Chris@0: * Chris@0: * @param string $class The service class Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setClass($class) Chris@0: { Chris@0: $this->class = $class; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the service class. Chris@0: * Chris@0: * @return string|null The service class Chris@0: */ Chris@0: public function getClass() Chris@0: { Chris@0: return $this->class; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the arguments to pass to the service constructor/factory method. Chris@0: * Chris@0: * @param array $arguments An array of arguments Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setArguments(array $arguments) Chris@0: { Chris@0: $this->arguments = $arguments; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: public function setProperties(array $properties) Chris@0: { Chris@0: $this->properties = $properties; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: public function getProperties() Chris@0: { Chris@0: return $this->properties; Chris@0: } Chris@0: Chris@0: public function setProperty($name, $value) Chris@0: { Chris@0: $this->properties[$name] = $value; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds an argument to pass to the service constructor/factory method. Chris@0: * Chris@0: * @param mixed $argument An argument Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function addArgument($argument) Chris@0: { Chris@0: $this->arguments[] = $argument; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets a specific argument. Chris@0: * Chris@0: * @param int $index Chris@0: * @param mixed $argument Chris@0: * Chris@0: * @return $this Chris@0: * Chris@0: * @throws OutOfBoundsException When the replaced argument does not exist Chris@0: */ Chris@0: public function replaceArgument($index, $argument) Chris@0: { Chris@0: if (0 === count($this->arguments)) { Chris@0: throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.'); Chris@0: } Chris@0: Chris@0: if ($index < 0 || $index > count($this->arguments) - 1) { Chris@0: throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1)); Chris@0: } Chris@0: Chris@0: $this->arguments[$index] = $argument; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the arguments to pass to the service constructor/factory method. Chris@0: * Chris@0: * @return array The array of arguments Chris@0: */ Chris@0: public function getArguments() Chris@0: { Chris@0: return $this->arguments; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets an argument to pass to the service constructor/factory method. Chris@0: * Chris@0: * @param int $index Chris@0: * Chris@0: * @return mixed The argument value Chris@0: * Chris@0: * @throws OutOfBoundsException When the argument does not exist Chris@0: */ Chris@0: public function getArgument($index) Chris@0: { Chris@0: if ($index < 0 || $index > count($this->arguments) - 1) { Chris@0: throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, count($this->arguments) - 1)); Chris@0: } Chris@0: Chris@0: return $this->arguments[$index]; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the methods to call after service initialization. Chris@0: * Chris@0: * @param array $calls An array of method calls Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setMethodCalls(array $calls = array()) Chris@0: { Chris@0: $this->calls = array(); Chris@0: foreach ($calls as $call) { Chris@0: $this->addMethodCall($call[0], $call[1]); Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a method to call after service initialization. Chris@0: * Chris@0: * @param string $method The method name to call Chris@0: * @param array $arguments An array of arguments to pass to the method call Chris@0: * Chris@0: * @return $this Chris@0: * Chris@0: * @throws InvalidArgumentException on empty $method param Chris@0: */ Chris@0: public function addMethodCall($method, array $arguments = array()) Chris@0: { Chris@0: if (empty($method)) { Chris@0: throw new InvalidArgumentException('Method name cannot be empty.'); Chris@0: } Chris@0: $this->calls[] = array($method, $arguments); Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Removes a method to call after service initialization. Chris@0: * Chris@0: * @param string $method The method name to remove Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function removeMethodCall($method) Chris@0: { Chris@0: foreach ($this->calls as $i => $call) { Chris@0: if ($call[0] === $method) { Chris@0: unset($this->calls[$i]); Chris@0: break; Chris@0: } Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Check if the current definition has a given method to call after service initialization. Chris@0: * Chris@0: * @param string $method The method name to search for Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function hasMethodCall($method) Chris@0: { Chris@0: foreach ($this->calls as $call) { Chris@0: if ($call[0] === $method) { Chris@0: return true; Chris@0: } Chris@0: } Chris@0: Chris@0: return false; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the methods to call after service initialization. Chris@0: * Chris@0: * @return array An array of method calls Chris@0: */ Chris@0: public function getMethodCalls() Chris@0: { Chris@0: return $this->calls; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets tags for this definition. Chris@0: * Chris@0: * @param array $tags Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setTags(array $tags) Chris@0: { Chris@0: $this->tags = $tags; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Returns all tags. Chris@0: * Chris@0: * @return array An array of tags Chris@0: */ Chris@0: public function getTags() Chris@0: { Chris@0: return $this->tags; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets a tag by name. Chris@0: * Chris@0: * @param string $name The tag name Chris@0: * Chris@0: * @return array An array of attributes Chris@0: */ Chris@0: public function getTag($name) Chris@0: { Chris@0: return isset($this->tags[$name]) ? $this->tags[$name] : array(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a tag for this definition. Chris@0: * Chris@0: * @param string $name The tag name Chris@0: * @param array $attributes An array of attributes Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function addTag($name, array $attributes = array()) Chris@0: { Chris@0: $this->tags[$name][] = $attributes; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this definition has a tag with the given name. Chris@0: * Chris@0: * @param string $name Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function hasTag($name) Chris@0: { Chris@0: return isset($this->tags[$name]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clears all tags for a given name. Chris@0: * Chris@0: * @param string $name The tag name Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function clearTag($name) Chris@0: { Chris@0: unset($this->tags[$name]); Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Clears the tags for this definition. Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function clearTags() Chris@0: { Chris@0: $this->tags = array(); Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets a file to require before creating the service. Chris@0: * Chris@0: * @param string $file A full pathname to include Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setFile($file) Chris@0: { Chris@0: $this->file = $file; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the file to require before creating the service. Chris@0: * Chris@0: * @return string|null The full pathname to include Chris@0: */ Chris@0: public function getFile() Chris@0: { Chris@0: return $this->file; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets if the service must be shared or not. Chris@0: * Chris@0: * @param bool $shared Whether the service must be shared or not Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setShared($shared) Chris@0: { Chris@0: $this->shared = (bool) $shared; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this service is shared. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isShared() Chris@0: { Chris@0: return $this->shared; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the visibility of this service. Chris@0: * Chris@0: * @param bool $boolean Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setPublic($boolean) Chris@0: { Chris@0: $this->public = (bool) $boolean; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this service is public facing. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isPublic() Chris@0: { Chris@0: return $this->public; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets the lazy flag of this service. Chris@0: * Chris@0: * @param bool $lazy Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setLazy($lazy) Chris@0: { Chris@0: $this->lazy = (bool) $lazy; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this service is lazy. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isLazy() Chris@0: { Chris@0: return $this->lazy; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets whether this definition is synthetic, that is not constructed by the Chris@0: * container, but dynamically injected. Chris@0: * Chris@0: * @param bool $boolean Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setSynthetic($boolean) Chris@0: { Chris@0: $this->synthetic = (bool) $boolean; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this definition is synthetic, that is not constructed by the Chris@0: * container, but dynamically injected. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isSynthetic() Chris@0: { Chris@0: return $this->synthetic; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this definition is abstract, that means it merely serves as a Chris@0: * template for other definitions. Chris@0: * Chris@0: * @param bool $boolean Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setAbstract($boolean) Chris@0: { Chris@0: $this->abstract = (bool) $boolean; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this definition is abstract, that means it merely serves as a Chris@0: * template for other definitions. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isAbstract() Chris@0: { Chris@0: return $this->abstract; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this definition is deprecated, that means it should not be called Chris@0: * anymore. Chris@0: * Chris@0: * @param bool $status Chris@0: * @param string $template Template message to use if the definition is deprecated Chris@0: * Chris@0: * @return $this Chris@0: * Chris@0: * @throws InvalidArgumentException When the message template is invalid. Chris@0: */ Chris@0: public function setDeprecated($status = true, $template = null) Chris@0: { Chris@0: if (null !== $template) { Chris@0: if (preg_match('#[\r\n]|\*/#', $template)) { Chris@0: throw new InvalidArgumentException('Invalid characters found in deprecation template.'); Chris@0: } Chris@0: Chris@0: if (false === strpos($template, '%service_id%')) { Chris@0: throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.'); Chris@0: } Chris@0: Chris@0: $this->deprecationTemplate = $template; Chris@0: } Chris@0: Chris@0: $this->deprecated = (bool) $status; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Whether this definition is deprecated, that means it should not be called Chris@0: * anymore. Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isDeprecated() Chris@0: { Chris@0: return $this->deprecated; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Message to use if this definition is deprecated. Chris@0: * Chris@0: * @param string $id Service id relying on this definition Chris@0: * Chris@0: * @return string Chris@0: */ Chris@0: public function getDeprecationMessage($id) Chris@0: { Chris@0: return str_replace('%service_id%', $id, $this->deprecationTemplate); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets a configurator to call after the service is fully initialized. Chris@0: * Chris@0: * @param string|array $configurator A PHP callable Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setConfigurator($configurator) Chris@0: { Chris@0: if (is_string($configurator) && strpos($configurator, '::') !== false) { Chris@0: $configurator = explode('::', $configurator, 2); Chris@0: } Chris@0: Chris@0: $this->configurator = $configurator; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the configurator to call after the service is fully initialized. Chris@0: * Chris@0: * @return callable|null The PHP callable to call Chris@0: */ Chris@0: public function getConfigurator() Chris@0: { Chris@0: return $this->configurator; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets types that will default to this definition. Chris@0: * Chris@0: * @param string[] $types Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setAutowiringTypes(array $types) Chris@0: { Chris@0: $this->autowiringTypes = array(); Chris@0: Chris@0: foreach ($types as $type) { Chris@0: $this->autowiringTypes[$type] = true; Chris@0: } Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Is the definition autowired? Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function isAutowired() Chris@0: { Chris@0: return $this->autowired; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Sets autowired. Chris@0: * Chris@0: * @param bool $autowired Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function setAutowired($autowired) Chris@0: { Chris@0: $this->autowired = $autowired; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets autowiring types that will default to this definition. Chris@0: * Chris@0: * @return string[] Chris@0: */ Chris@0: public function getAutowiringTypes() Chris@0: { Chris@0: return array_keys($this->autowiringTypes); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Adds a type that will default to this definition. Chris@0: * Chris@0: * @param string $type Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function addAutowiringType($type) Chris@0: { Chris@0: $this->autowiringTypes[$type] = true; Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Removes a type. Chris@0: * Chris@0: * @param string $type Chris@0: * Chris@0: * @return $this Chris@0: */ Chris@0: public function removeAutowiringType($type) Chris@0: { Chris@0: unset($this->autowiringTypes[$type]); Chris@0: Chris@0: return $this; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Will this definition default for the given type? Chris@0: * Chris@0: * @param string $type Chris@0: * Chris@0: * @return bool Chris@0: */ Chris@0: public function hasAutowiringType($type) Chris@0: { Chris@0: return isset($this->autowiringTypes[$type]); Chris@0: } Chris@0: }