diff --git a/core/core.services.yml b/core/core.services.yml index de408ad9f30e..df50344fc709 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -1418,11 +1418,13 @@ services: class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer calls: - [setContainer, ['@service_container']] + - [setStandalone, ['\Zend\Feed\Reader\StandaloneExtensionManager']] arguments: ['feed.reader.'] feed.bridge.writer: class: Drupal\Component\Bridge\ZfExtensionManagerSfContainer calls: - [setContainer, ['@service_container']] + - [setStandalone, ['\Zend\Feed\Writer\StandaloneExtensionManager']] arguments: ['feed.writer.'] # Zend Feed reader plugins. Plugin instances should not be shared. feed.reader.dublincoreentry: diff --git a/core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php b/core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php index c6579465eeef..59ae9f56464b 100644 --- a/core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php +++ b/core/lib/Drupal/Component/Bridge/ZfExtensionManagerSfContainer.php @@ -4,6 +4,7 @@ namespace Drupal\Component\Bridge; use Symfony\Component\DependencyInjection\ContainerAwareInterface; use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Zend\Feed\Reader\ExtensionManagerInterface as ReaderManagerInterface; use Zend\Feed\Writer\ExtensionManagerInterface as WriterManagerInterface; @@ -48,6 +49,11 @@ class ZfExtensionManagerSfContainer implements ReaderManagerInterface, WriterMan */ protected $canonicalNames; + /** + * @var \Zend\Feed\Reader\ExtensionManagerInterface|\Zend\Feed\Writer\ExtensionManagerInterface + */ + protected $standalone; + /** * Constructs a ZfExtensionManagerSfContainer object. * @@ -62,14 +68,25 @@ class ZfExtensionManagerSfContainer implements ReaderManagerInterface, WriterMan * {@inheritdoc} */ public function get($extension) { - return $this->container->get($this->prefix . $this->canonicalizeName($extension)); + try { + return $this->container->get($this->prefix . $this->canonicalizeName($extension)); + } + catch (ServiceNotFoundException $e) { + if ($this->standalone && $this->standalone->has($extension)) { + return $this->standalone->get($extension); + } + throw $e; + } } /** * {@inheritdoc} */ public function has($extension) { - return $this->container->has($this->prefix . $this->canonicalizeName($extension)); + if ($this->container->has($this->prefix . $this->canonicalizeName($extension))) { + return TRUE; + } + return $this->standalone && $this->standalone->has($extension); } /** @@ -102,4 +119,14 @@ class ZfExtensionManagerSfContainer implements ReaderManagerInterface, WriterMan $this->container = $container; } + /** + * @param $class + */ + public function setStandalone($class) { + if (!is_subclass_of($class, ReaderManagerInterface::class) && !is_subclass_of($class, WriterManagerInterface::class)) { + throw new \RuntimeException("$class must implement Zend\Feed\Reader\ExtensionManagerInterface or Zend\Feed\Writer\ExtensionManagerInterface"); + } + $this->standalone = new $class(); + } + } diff --git a/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php b/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php index 3aaf9d11297b..191b006e49d9 100644 --- a/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php +++ b/core/tests/Drupal/Tests/Component/Bridge/ZfExtensionManagerSfContainerTest.php @@ -5,6 +5,9 @@ namespace Drupal\Tests\Component\Bridge; use Drupal\Component\Bridge\ZfExtensionManagerSfContainer; use PHPUnit\Framework\TestCase; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Zend\Feed\Reader\Extension\Atom\Entry; +use Zend\Feed\Reader\StandaloneExtensionManager; /** * @coversDefaultClass \Drupal\Component\Bridge\ZfExtensionManagerSfContainer @@ -14,6 +17,7 @@ class ZfExtensionManagerSfContainerTest extends TestCase { /** * @covers ::setContainer + * @covers ::setStandalone * @covers ::get */ public function testGet() { @@ -24,10 +28,16 @@ class ZfExtensionManagerSfContainerTest extends TestCase { $bridge = new ZfExtensionManagerSfContainer(); $bridge->setContainer($container); $this->assertEquals($service, $bridge->get('foo')); + $bridge->setStandalone(StandaloneExtensionManager::class); + $this->assertInstanceOf(Entry::class, $bridge->get('Atom\Entry')); + // Ensure that the container is checked first. + $container->set('atomentry', $service); + $this->assertEquals($service, $bridge->get('Atom\Entry')); } /** * @covers ::setContainer + * @covers ::setStandalone * @covers ::has */ public function testHas() { @@ -39,6 +49,42 @@ class ZfExtensionManagerSfContainerTest extends TestCase { $bridge->setContainer($container); $this->assertTrue($bridge->has('foo')); $this->assertFalse($bridge->has('bar')); + $this->assertFalse($bridge->has('Atom\Entry')); + $bridge->setStandalone(StandaloneExtensionManager::class); + $this->assertTrue($bridge->has('Atom\Entry')); + } + + /** + * @covers ::setStandalone + */ + public function testSetStandaloneException() { + if (method_exists($this, 'expectException')) { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Drupal\Tests\Component\Bridge\ZfExtensionManagerSfContainerTest must implement Zend\Feed\Reader\ExtensionManagerInterface or Zend\Feed\Writer\ExtensionManagerInterface'); + } + else { + $this->setExpectedException(\RuntimeException::class, 'Drupal\Tests\Component\Bridge\ZfExtensionManagerSfContainerTest must implement Zend\Feed\Reader\ExtensionManagerInterface or Zend\Feed\Writer\ExtensionManagerInterface'); + } + $bridge = new ZfExtensionManagerSfContainer(); + $bridge->setStandalone(static::class); + } + + /** + * @covers ::get + */ + public function testGetContainerException() { + if (method_exists($this, 'expectException')) { + $this->expectException(ServiceNotFoundException::class); + $this->expectExceptionMessage('You have requested a non-existent service "test.foo".'); + } + else { + $this->setExpectedException(ServiceNotFoundException::class, 'You have requested a non-existent service "test.foo".'); + } + $container = new ContainerBuilder(); + $bridge = new ZfExtensionManagerSfContainer('test.'); + $bridge->setContainer($container); + $bridge->setStandalone(StandaloneExtensionManager::class); + $bridge->get('foo'); } /**