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