Skip to content

Commit

Permalink
[DependencyInjection] added annotations support in the service Defini…
Browse files Browse the repository at this point in the history
…tion
  • Loading branch information
fabpot committed Feb 9, 2010
1 parent 661a1cf commit 7a26b42
Show file tree
Hide file tree
Showing 18 changed files with 320 additions and 3 deletions.
@@ -0,0 +1,31 @@
<?php

namespace Symfony\Components\DependencyInjection;

/*
* This file is part of the symfony framework.
*
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

/**
* AnnotatedContainerInterface is the interface implemented when a container knows how to deals with annotations.
*
* @package symfony
* @subpackage dependency_injection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
interface AnnotatedContainerInterface
{
/**
* Returns service ids for a given annotation.
*
* @param string $name The annotation name
*
* @return array An array of annotations
*/
public function findAnnotatedServiceIds($name);
}
23 changes: 22 additions & 1 deletion src/Symfony/Components/DependencyInjection/Builder.php
Expand Up @@ -18,7 +18,7 @@
* @subpackage dependency_injection
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
*/
class Builder extends Container
class Builder extends Container implements AnnotatedContainerInterface
{
protected $definitions = array();
protected $aliases = array();
Expand Down Expand Up @@ -481,6 +481,27 @@ public function resolveServices($value)
return $value;
}

/**
* Returns service ids for a given annotation.
*
* @param string $name The annotation name
*
* @return array An array of annotations
*/
public function findAnnotatedServiceIds($name)
{
$annotations = array();
foreach ($this->getDefinitions() as $id => $definition)
{
if ($definition->getAnnotation($name))
{
$annotations[$id] = $definition->getAnnotation($name);
}
}

return $annotations;
}

static public function getServiceConditionals($value)
{
$services = array();
Expand Down
49 changes: 49 additions & 0 deletions src/Symfony/Components/DependencyInjection/Definition.php
Expand Up @@ -27,6 +27,7 @@ class Definition
protected $arguments;
protected $calls;
protected $configurator;
protected $annotations;

/**
* Constructor.
Expand All @@ -40,6 +41,7 @@ public function __construct($class, array $arguments = array())
$this->arguments = $arguments;
$this->calls = array();
$this->shared = true;
$this->annotations = array();
}

/**
Expand Down Expand Up @@ -171,6 +173,53 @@ public function getMethodCalls()
return $this->calls;
}

/**
* Returns all annotations.
*
* @return array An array of annotations
*/
public function getAnnotations()
{
return $this->annotations;
}

/**
* Gets an annotation by name.
*
* @param string $name The annotation name
*
* @return array $attributes An array of attributes
*/
public function getAnnotation($name)
{
if (!isset($this->annotations[$name]))
{
$this->annotations[$name] = array();
}

return $this->annotations[$name];
}

/**
* Adds an annotation for this definition.
*
* @param string $name The annotation name
* @param array $attributes An array of attributes
*
* @return Definition The current instance
*/
public function addAnnotation($name, array $attributes = array())
{
if (!isset($this->annotations[$name]))
{
$this->annotations[$name] = array();
}

$this->annotations[$name][] = $attributes;

return $this;
}

/**
* Sets a file to require before creating the service.
*
Expand Down
37 changes: 37 additions & 0 deletions src/Symfony/Components/DependencyInjection/Dumper/PhpDumper.php
Expand Up @@ -48,6 +48,7 @@ public function dump(array $options = array())
$this->startClass($options['class'], $options['base_class']).
$this->addConstructor().
$this->addServices().
$this->addAnnotations().
$this->addDefaultParametersMethod().
$this->endClass()
;
Expand Down Expand Up @@ -246,6 +247,42 @@ protected function addServices()
return $code;
}

protected function addAnnotations()
{
$annotations = array();
foreach ($this->container->getDefinitions() as $id => $definition)
{
foreach ($definition->getAnnotations() as $name => $ann)
{
if (!isset($annotations[$name]))
{
$annotations[$name] = array();
}

$annotations[$name][$id] = $ann;
}
}
$annotations = var_export($annotations, true);

return <<<EOF
/**
* Returns service ids for a given annotation.
*
* @param string \$name The annotation name
*
* @return array An array of annotations
*/
public function findAnnotatedServiceIds(\$name)
{
static \$annotations = $annotations;
return isset(\$annotations[\$name]) ? \$annotations[\$name] : array();
}
EOF;
}

protected function startClass($class, $baseClass)
{
$properties = array();
Expand Down
15 changes: 15 additions & 0 deletions src/Symfony/Components/DependencyInjection/Dumper/XmlDumper.php
Expand Up @@ -55,6 +55,21 @@ protected function addService($id, $definition)
!$definition->isShared() ? ' shared="false"' : ''
);

foreach ($definition->getAnnotations() as $name => $annotations)
{
foreach ($annotations as $attributes)
{
$att = array();
foreach ($attributes as $key => $value)
{
$att[] = sprintf('%s="%s"', $key, $value);
}
$att = $att ? ' '.implode(' ', $att) : '';

$code .= sprintf(" <annotation name=\"%s\"%s />\n", $name, $att);
}
}

if ($definition->getFile())
{
$code .= sprintf(" <file>%s</file>\n", $definition->getFile());
Expand Down
20 changes: 20 additions & 0 deletions src/Symfony/Components/DependencyInjection/Dumper/YamlDumper.php
Expand Up @@ -42,6 +42,26 @@ protected function addService($id, $definition)
$code = " $id:\n";
$code .= sprintf(" class: %s\n", $definition->getClass());

$annotationsCode = '';
foreach ($definition->getAnnotations() as $name => $annotations)
{
foreach ($annotations as $attributes)
{
$att = array();
foreach ($attributes as $key => $value)
{
$att[] = sprintf('%s: %s', YAML::dump($key), YAML::dump($value));
}
$att = $att ? ', '.implode(' ', $att) : '';

$annotationsCode .= sprintf(" - { name: %s%s }\n", YAML::dump($name), $att);
}
}
if ($annotationsCode)
{
$code .= " annotations:\n".$annotationsCode;
}

if ($definition->getFile())
{
$code .= sprintf(" file: %s\n", $definition->getFile());
Expand Down
Expand Up @@ -178,6 +178,22 @@ protected function parseDefinition(BuilderConfiguration $configuration, $id, $se
$definition->addMethodCall((string) $call['method'], $call->getArgumentsAsPhp('argument'));
}

foreach ($service->annotation as $annotation)
{
$parameters = array();
foreach ($annotation->attributes() as $name => $value)
{
if ('name' === $name)
{
continue;
}

$parameters[$name] = SimpleXMLElement::phpize($value);
}

$definition->addAnnotation((string) $annotation['name'], $parameters);
}

$configuration->setDefinition($id, $definition);
}

Expand Down
Expand Up @@ -177,6 +177,17 @@ protected function parseDefinition(BuilderConfiguration $configuration, $id, $se
}
}

if (isset($service['annotations']))
{
foreach ($service['annotations'] as $annotation)
{
$name = $annotation['name'];
unset($annotation['name']);

$definition->addAnnotation($name, $annotation);
}
}

$configuration->setDefinition($id, $definition);
}

Expand Down
Expand Up @@ -84,6 +84,7 @@
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="configurator" type="configurator" minOccurs="0" maxOccurs="1" />
<xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="annotation" type="annotation" minOccurs="0" maxOccurs="unbounded" />
</xsd:choice>
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="class" type="xsd:string" />
Expand All @@ -92,6 +93,11 @@
<xsd:attribute name="alias" type="xsd:string" />
</xsd:complexType>

<xsd:complexType name="annotation">
<xsd:attribute name="name" type="xsd:string" />
<xsd:anyAttribute namespace="##any" processContents="lax" />
</xsd:complexType>

<xsd:complexType name="parameters">
<xsd:sequence>
<xsd:element name="parameter" type="parameter" minOccurs="1" maxOccurs="unbounded" />
Expand Down
Expand Up @@ -10,6 +10,8 @@
$container = new Builder();
$container->
register('foo', 'FooClass')->
addAnnotation('foo', array('foo' => 'foo'))->
addAnnotation('foo', array('bar' => 'bar'))->
setConstructor('getInstance')->
setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, new Reference('service_container')))->
setFile(realpath(__DIR__.'/../includes/foo.php'))->
Expand Down
Expand Up @@ -13,4 +13,19 @@
class Container extends AbstractContainer
{
protected $shared = array();

/**
* Returns service ids for a given annotation.
*
* @param string $name The annotation name
*
* @return array An array of annotations
*/
public function findAnnotatedServiceIds($name)
{
static $annotations = array (
);

return isset($annotations[$name]) ? $annotations[$name] : array();
}
}
Expand Up @@ -13,4 +13,19 @@
class ProjectServiceContainer extends Container
{
protected $shared = array();

/**
* Returns service ids for a given annotation.
*
* @param string $name The annotation name
*
* @return array An array of annotations
*/
public function findAnnotatedServiceIds($name)
{
static $annotations = array (
);

return isset($annotations[$name]) ? $annotations[$name] : array();
}
}
Expand Up @@ -24,6 +24,21 @@ public function __construct()
$this->parameters = $this->getDefaultParameters();
}

/**
* Returns service ids for a given annotation.
*
* @param string $name The annotation name
*
* @return array An array of annotations
*/
public function findAnnotatedServiceIds($name)
{
static $annotations = array (
);

return isset($annotations[$name]) ? $annotations[$name] : array();
}

/**
* Gets the default parameters.
*
Expand Down

0 comments on commit 7a26b42

Please sign in to comment.