Skip to content

Commit

Permalink
add multiservice logic
Browse files Browse the repository at this point in the history
add deprecation warnings
add services support to AfterSetup
add tests
fix schmittjoh#232
  • Loading branch information
wodka committed Feb 16, 2016
1 parent d496296 commit 7655431
Show file tree
Hide file tree
Showing 14 changed files with 466 additions and 88 deletions.
2 changes: 2 additions & 0 deletions Annotation/AfterSetup.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@
*/
final class AfterSetup
{
/** @var array */
public $services;
}
3 changes: 3 additions & 0 deletions Annotation/InjectParams.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ final class InjectParams
{
/** @var array<JMS\DiExtraBundle\Annotation\Inject> */
public $params = array();

/** @var array */
public $services;
}
6 changes: 2 additions & 4 deletions DependencyInjection/Compiler/AnnotationConfigurationPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,12 @@ public function process(ContainerBuilder $container)
if (null === $metadata = $factory->getMetadataForClass($className)) {
continue;
}

if (null === $metadata->getOutsideClassMetadata()->id) {
continue;
}
if ( ! $metadata->getOutsideClassMetadata()->isLoadedInEnvironment($container->getParameter('kernel.environment'))) {
continue;
}

foreach ($converter->convert($metadata) as $id => $definition) {
foreach ($converter->convert($metadata, $container->getParameter('kernel.environment')) as $id => $definition) {
$container->setDefinition($id, $definition);
}
}
Expand Down
9 changes: 9 additions & 0 deletions Exception/InvalidParentException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace JMS\DiExtraBundle\Exception;

/**
* parent can be invalid if there is more than one service
*/
class InvalidParentException extends RuntimeException
{}
125 changes: 114 additions & 11 deletions Metadata/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,140 @@
use Metadata\ClassMetadata as BaseClassMetadata;

/**
* class metadata
* processed annotations for service creation
*/
class ClassMetadata extends BaseClassMetadata
{
/**
* @var string
* @deprecated use addService instead
*/
public $id;

/**
* @var string
* @deprecated use addService instead
*/
public $parent;

/**
* @var string
* @deprecated use addService instead, removed in SF 3.0
*/
public $scope;

/**
* @var bool
* @deprecated use addService instead
*/
public $public;

/**
* @var boolean
* @deprecated use addService instead
*/
public $abstract;

/**
* @var array
*/
public $tags = array();

/**
* constructor arguments
*
* @var array
*/
public $arguments;

/**
* @var array
*/
public $methodCalls = array();

/**
* @var array
*/
public $lookupMethods = array();

/**
* @var array
*/
public $properties = array();
/**
* @deprecated since version 1.7, to be removed in 2.0. Use $initMethods instead.
*/
public $initMethod;
public $initMethods = array();

/**
* @deprecated use addService instead
*
* @var string[]
*/
public $environments = array();
public $decorates;
public $decoration_inner_name;
public $deprecated;

/**
* @param string $env
* service definitions
*
* @var array[]
*/
private $services = array();

/**
* on first call also populate legacy fields
*
* @param string[] $service
*/
public function addService(array $service)
{
if (empty($this->id)) {
$this->id = $service['id'];
$this->parent = @$service['parent'];
$this->public = @$service['public'];
$this->scope = @$service['scope'];
$this->abstract = @$service['abstract'];
$this->environments = @$service['environments'];
// TODO update call for other tags (there are several pull requests)
}

$this->services[$service['id']] = $service;
}

/**
* @return bool
*/
public function hasServices()
{
return !empty($this->services);
}

/**
* get list of defined services, use fallback of original fields
*
* @return array[]
*/
public function getServices()
{
// TODO remove fallback for next major version
if (empty($this->services) || !isset($this->services[$this->id])) {
$this->services[] = array(
'id' => $this->id,
'parent' => $this->parent,
'public' => $this->public,
'scope' => $this->scope,
'abstract' => $this->abstract,
'environments' => $this->environments,
);
}

return $this->services;
}

/**
* @deprecated this is handled on service level
*
* @param string $env
* @return bool
*/
public function isLoadedInEnvironment($env)
Expand Down Expand Up @@ -78,9 +185,7 @@ public function serialize()
$this->initMethod,
parent::serialize(),
$this->environments,
$this->decorates,
$this->decoration_inner_name,
$this->deprecated,
$this->services,
));
}

Expand All @@ -106,9 +211,7 @@ public function unserialize($str)
$this->initMethod,
$parentStr,
$this->environments,
$this->decorates,
$this->decoration_inner_name,
$this->deprecated,
$this->services,
) = $data;

parent::unserialize($parentStr);
Expand Down
55 changes: 35 additions & 20 deletions Metadata/Driver/AnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,33 +72,41 @@ public function loadMetadataForClass(\ReflectionClass $class)

foreach ($this->reader->getClassAnnotations($class) as $annot) {
if ($annot instanceof Service) {
$service = array();
if (null === $annot->id) {
$metadata->id = $this->namingStrategy->classToServiceName($className);
$service['id'] = $this->namingStrategy->classToServiceName($className);
} else {
$metadata->id = $annot->id;
$service['id'] = $annot->id;
}

$metadata->parent = $annot->parent;
$metadata->public = $annot->public;
$metadata->scope = $annot->scope;
$metadata->abstract = $annot->abstract;
$metadata->decorates = $annot->decorates;
$metadata->decoration_inner_name = $annot->decoration_inner_name;
$metadata->deprecated = $annot->deprecated;
$service['parent'] = $annot->parent;
$service['public'] = $annot->public;
$service['scope'] = $annot->scope;
$service['abstract'] = $annot->abstract;
$service['environments'] = $annot->environments;
$service['decorates'] = $annot->decorates;
$service['decoration_inner_name'] = $annot->decoration_inner_name;
$service['deprecated'] = $annot->deprecated;

$metadata->addService($service);
} else if ($annot instanceof Tag) {
$metadata->tags[$annot->name][] = $annot->attributes;
} else if ($annot instanceof Validator) {
// automatically register as service if not done explicitly
if (null === $metadata->id) {
$metadata->id = $this->namingStrategy->classToServiceName($className);
if (!$metadata->hasServices()) {
$metadata->addService(array(
'id' => $this->namingStrategy->classToServiceName($className)
));
}

$metadata->tags['validator.constraint_validator'][] = array(
'alias' => $annot->alias,
);
} else if ($annot instanceof AbstractDoctrineListener) {
if (null === $metadata->id) {
$metadata->id = $this->namingStrategy->classToServiceName($className);
if (!$metadata->hasServices()) {
$metadata->addService(array(
'id' => $this->namingStrategy->classToServiceName($className)
));
}

foreach ($annot->events as $event) {
Expand All @@ -110,8 +118,10 @@ public function loadMetadataForClass(\ReflectionClass $class)
);
}
} else if ($annot instanceof FormType) {
if (null === $metadata->id) {
$metadata->id = $this->namingStrategy->classToServiceName($className);
if (!$metadata->hasServices()) {
$metadata->addService(array(
'id' => $this->namingStrategy->classToServiceName($className)
));
}

$alias = $annot->alias;
Expand All @@ -126,8 +136,10 @@ public function loadMetadataForClass(\ReflectionClass $class)
'alias' => $alias,
);
} else if ($annot instanceof MetadataProcessorInterface) {
if (null === $metadata->id) {
$metadata->id = $this->namingStrategy->classToServiceName($className);
if (!$metadata->hasServices()) {
$metadata->addService(array(
'id' => $this->namingStrategy->classToServiceName($className)
));
}

$annot->processMetadata($metadata);
Expand Down Expand Up @@ -187,7 +199,7 @@ public function loadMetadataForClass(\ReflectionClass $class)
if ('__construct' === $name) {
$metadata->arguments = $params;
} else {
$metadata->methodCalls[] = array($name, $params);
$metadata->methodCalls[] = array($name, $params, $annot->services);
}
} else if ($annot instanceof LookupMethod) {
$hasInjection = true;
Expand All @@ -208,8 +220,11 @@ public function loadMetadataForClass(\ReflectionClass $class)
throw new \RuntimeException(sprintf('The init method "%s::%s" must be public.', $method->class, $method->name));
}

$metadata->initMethod = $method->name;
$metadata->initMethods[] = $method->name;
$metadata->initMethods[] = [
$method->name,
array(), // parameters - to be in line with methodCalls
$annot->services
];
} else if ($annot instanceof MetadataProcessorInterface) {
if (null === $metadata->id) {
$metadata->id = $this->namingStrategy->classToServiceName($className);
Expand Down
Loading

0 comments on commit 7655431

Please sign in to comment.