Skip to content

Commit

Permalink
improve logic
Browse files Browse the repository at this point in the history
  • Loading branch information
wodka committed Feb 15, 2016
1 parent 2dc6bf4 commit 4533b8a
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 25 deletions.
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
{}
18 changes: 13 additions & 5 deletions Metadata/ClassMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class ClassMetadata extends BaseClassMetadata
public $properties = array();
public $initMethod;
public $environments = array();
public $services = [];
public $services = array();

/**
* on first call also populate legacy fields
Expand All @@ -45,16 +45,24 @@ 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->parent = @$service['parent'];
$this->public = @$service['public'];
$this->scope = @$service['scope'];
$this->abstract = @$service['abstract'];
// 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
*
Expand Down
28 changes: 19 additions & 9 deletions Metadata/Driver/AnnotationDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,27 @@ public function loadMetadataForClass(\ReflectionClass $class)
$service['public'] = $annot->public;
$service['scope'] = $annot->scope;
$service['abstract'] = $annot->abstract;
$metadata->addService($service);

// remove all empty values from service definition
$metadata->addService(array_filter($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 @@ -109,8 +115,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 @@ -125,8 +133,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
29 changes: 19 additions & 10 deletions Metadata/MetadataConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

namespace JMS\DiExtraBundle\Metadata;

use JMS\DiExtraBundle\Exception\InvalidParentException;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Definition;
Expand All @@ -36,27 +37,35 @@ public function convert(ClassHierarchyMetadata $metadata)
static $count = 0;
$definitions = array();

/** @var ClassMetadata $previous */
$previous = null;
/** @var ClassMetadata $classMetadata */
foreach ($metadata->classMetadata as $classMetadata) {
foreach ($classMetadata->getServices() as $service) {
if (null === $previous && null === @$service['parent']) {
if (null === $previous && empty($service['parent'])) {
$definition = new Definition();
} else {
if (empty($service['parent']) && sizeof($previous->getServices()) > 1) {
throw new InvalidParentException('there are multiple services on '.$classMetadata->name);
}

$definition = new DefinitionDecorator(
@$service['parent'] ?: $previous->id
);
}

$definition->setClass($classMetadata->name);
if (null !== @$service['scope']) {
$definition->setScope(@$service['scope']);
if (!empty($service['scope'])) {
if (!method_exists($definition, 'setScope')) {
throw new \RuntimeException('service scopes are not available on your Symfony version.');
}
$definition->setScope($service['scope']);
}
if (null !== @$service['public']) {
$definition->setPublic(@$service['public']);
if (!empty($service['public'])) {
$definition->setPublic($service['public']);
}
if (null !== @$service['abstract']) {
$definition->setAbstract(@$service['abstract']);
if (!empty($service['abstract'])) {
$definition->setAbstract($service['abstract']);
}
if (null !== $classMetadata->arguments) {
$definition->setArguments($classMetadata->arguments);
Expand All @@ -66,15 +75,15 @@ public function convert(ClassHierarchyMetadata $metadata)
$definition->setTags($classMetadata->tags);
$definition->setProperties($classMetadata->properties);

if (null === @$service['id']) {
$classMetadata->id = '_jms_di_extra.unnamed.service_' . $count++;
if (empty($service['id'])) {
$service['id'] = '_jms_di_extra.unnamed.service_' . $count++;
}

if ($classMetadata->initMethod) {
throw new \RuntimeException(sprintf('You can\'t use @AfterSetup on a service.'));
}

$definitions[$classMetadata->id] = $definition;
$definitions[$service['id']] = $definition;
}

$previous = $classMetadata;
Expand Down
2 changes: 1 addition & 1 deletion Tests/Metadata/Driver/AnnotationDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public function testMultiService()
'id' => 'first.service',
),
'second.service' => array(
'id' => 'first.service',
'id' => 'second.service',
)
), $metadata->getServices());
}
Expand Down

0 comments on commit 4533b8a

Please sign in to comment.