[Config] Handle Service/EventSubscriberInterface in ReflectionClassResource
This commit is contained in:
parent
0023f4e84d
commit
67e821b94f
@ -11,6 +11,9 @@
|
||||
|
||||
namespace Symfony\Component\Config\Resource;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
@ -114,7 +117,9 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali
|
||||
|
||||
private function generateSignature(\ReflectionClass $class)
|
||||
{
|
||||
yield $class->getDocComment().$class->getModifiers();
|
||||
yield $class->getDocComment();
|
||||
yield (int) $class->isFinal();
|
||||
yield (int) $class->isAbstract();
|
||||
|
||||
if ($class->isTrait()) {
|
||||
yield print_r(class_uses($class->name), true);
|
||||
@ -149,6 +154,16 @@ class ReflectionClassResource implements SelfCheckingResourceInterface, \Seriali
|
||||
yield print_r($defaults, true);
|
||||
}
|
||||
}
|
||||
|
||||
if ($class->isSubclassOf(EventSubscriberInterface::class)) {
|
||||
yield EventSubscriberInterface::class;
|
||||
yield print_r(\call_user_func(array($class->name, 'getSubscribedEvents')), true);
|
||||
}
|
||||
|
||||
if ($class->isSubclassOf(ServiceSubscriberInterface::class)) {
|
||||
yield ServiceSubscriberInterface::class;
|
||||
yield print_r(\call_user_func(array($class->name, 'getSubscribedServices')), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@ namespace Symfony\Component\Config\Tests\Resource;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\Config\Resource\ReflectionClassResource;
|
||||
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
class ReflectionClassResourceTest extends TestCase
|
||||
{
|
||||
@ -136,8 +138,52 @@ EOPHP;
|
||||
yield array(0, 14, '/** priv docblock */');
|
||||
yield array(0, 15, '');
|
||||
}
|
||||
|
||||
public function testEventSubscriber()
|
||||
{
|
||||
$res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class));
|
||||
$this->assertTrue($res->isFresh(0));
|
||||
|
||||
TestEventSubscriber::$subscribedEvents = array(123);
|
||||
$this->assertFalse($res->isFresh(0));
|
||||
|
||||
$res = new ReflectionClassResource(new \ReflectionClass(TestEventSubscriber::class));
|
||||
$this->assertTrue($res->isFresh(0));
|
||||
}
|
||||
|
||||
public function testServiceSubscriber()
|
||||
{
|
||||
$res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class));
|
||||
$this->assertTrue($res->isFresh(0));
|
||||
|
||||
TestServiceSubscriber::$subscribedServices = array(123);
|
||||
$this->assertFalse($res->isFresh(0));
|
||||
|
||||
$res = new ReflectionClassResource(new \ReflectionClass(TestServiceSubscriber::class));
|
||||
$this->assertTrue($res->isFresh(0));
|
||||
}
|
||||
}
|
||||
|
||||
interface DummyInterface
|
||||
{
|
||||
}
|
||||
|
||||
class TestEventSubscriber implements EventSubscriberInterface
|
||||
{
|
||||
public static $subscribedEvents = array();
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return self::$subscribedEvents;
|
||||
}
|
||||
}
|
||||
|
||||
class TestServiceSubscriber implements ServiceSubscriberInterface
|
||||
{
|
||||
public static $subscribedServices = array();
|
||||
|
||||
public static function getSubscribedServices()
|
||||
{
|
||||
return self::$subscribedServices;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,8 @@
|
||||
"require-dev": {
|
||||
"symfony/finder": "~3.3|~4.0",
|
||||
"symfony/yaml": "~3.0|~4.0",
|
||||
"symfony/dependency-injection": "~3.3|~4.0"
|
||||
"symfony/dependency-injection": "~3.3|~4.0",
|
||||
"symfony/event-dispatcher": "~3.3|~4.0"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/finder": "<3.3",
|
||||
|
@ -56,14 +56,14 @@ class RegisterServiceSubscribersPass extends AbstractRecursivePass
|
||||
}
|
||||
$class = $value->getClass();
|
||||
|
||||
if (!is_subclass_of($class, ServiceSubscriberInterface::class)) {
|
||||
if (!class_exists($class, false)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId));
|
||||
}
|
||||
|
||||
if (!$r = $this->container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId));
|
||||
}
|
||||
if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) {
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class));
|
||||
}
|
||||
$this->container->addObjectResource($class);
|
||||
$class = $r->name;
|
||||
|
||||
$subscriberMap = array();
|
||||
$declaringClass = (new \ReflectionMethod($class, 'getSubscribedServices'))->class;
|
||||
|
||||
|
@ -89,17 +89,15 @@ class RegisterListenersPass implements CompilerPassInterface
|
||||
$def = $container->getDefinition($id);
|
||||
|
||||
// We must assume that the class value has been correctly filled, even if the service is created by a factory
|
||||
$class = $container->getParameterBag()->resolveValue($def->getClass());
|
||||
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
|
||||
$class = $def->getClass();
|
||||
|
||||
if (!is_subclass_of($class, $interface)) {
|
||||
if (!class_exists($class, false)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
|
||||
if (!$r = $container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
}
|
||||
$container->addObjectResource($class);
|
||||
if (!$r->isSubclassOf(EventSubscriberInterface::class)) {
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EventSubscriberInterface::class));
|
||||
}
|
||||
$class = $r->name;
|
||||
|
||||
ExtractingEventDispatcher::$subscriber = $class;
|
||||
$extractingDispatcher->addSubscriber($extractingDispatcher);
|
||||
|
Reference in New Issue
Block a user