Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge pull request #55 from Synchro/master
Browse files Browse the repository at this point in the history
Make StandaloneExtensionManagers configurable
  • Loading branch information
weierophinney committed Dec 4, 2017
2 parents 0f90fea + 32982ff commit ab4e22e
Show file tree
Hide file tree
Showing 5 changed files with 245 additions and 17 deletions.
9 changes: 5 additions & 4 deletions docs/book/reader.md
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,9 @@ manager". Extension managers must implement `Zend\Feed\Reader\ExtensionManagerIn
Three implementations exist:

- `Zend\Feed\Reader\StandaloneExtensionManager` is a hard-coded implementation
seeded with all feed and entry implementations. You can extend it to add
extensions, though it's likely easier to copy and paste it, adding your
changes.
seeded with all feed and entry implementations. You can add simple extensions
from it using `add` and `remove` methods. `ExtensionPluginManager` is
recommended for more complex needs.
- `Zend\Feed\Reader\ExtensionPluginManager` is a `Zend\ServiceManager\AbstractPluginManager`
implementation, `Zend\Feed\Reader\ExtensionManager`; as such, you can extend
it to add more extensions, use a `Zend\ServiceManager\ConfigInterface` instance
Expand Down Expand Up @@ -727,7 +727,8 @@ your extension manager knows about it, and then register the extension with

The following example uses `Zend\Feed\Reader\ExtensionPluginManager` to manage
extensions, as it provides the ability to register new extensions without
requiring extension of the plugin manager itself. To use it, first intall
requiring extension of the plugin manager itself (note that this example works
with ServiceManager v2, but not v3). To use it, first install
zend-servicemanager:

```bash
Expand Down
62 changes: 49 additions & 13 deletions src/Reader/StandaloneExtensionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,24 @@

namespace Zend\Feed\Reader;

use Zend\Feed\Reader\Exception\InvalidArgumentException;

class StandaloneExtensionManager implements ExtensionManagerInterface
{
private $extensions = [
'Atom\Entry' => 'Zend\Feed\Reader\Extension\Atom\Entry',
'Atom\Feed' => 'Zend\Feed\Reader\Extension\Atom\Feed',
'Content\Entry' => 'Zend\Feed\Reader\Extension\Content\Entry',
'CreativeCommons\Entry' => 'Zend\Feed\Reader\Extension\CreativeCommons\Entry',
'CreativeCommons\Feed' => 'Zend\Feed\Reader\Extension\CreativeCommons\Feed',
'DublinCore\Entry' => 'Zend\Feed\Reader\Extension\DublinCore\Entry',
'DublinCore\Feed' => 'Zend\Feed\Reader\Extension\DublinCore\Feed',
'Podcast\Entry' => 'Zend\Feed\Reader\Extension\Podcast\Entry',
'Podcast\Feed' => 'Zend\Feed\Reader\Extension\Podcast\Feed',
'Slash\Entry' => 'Zend\Feed\Reader\Extension\Slash\Entry',
'Syndication\Feed' => 'Zend\Feed\Reader\Extension\Syndication\Feed',
'Thread\Entry' => 'Zend\Feed\Reader\Extension\Thread\Entry',
'WellFormedWeb\Entry' => 'Zend\Feed\Reader\Extension\WellFormedWeb\Entry',
'Atom\Entry' => Extension\Atom\Entry::class,
'Atom\Feed' => Extension\Atom\Feed::class,
'Content\Entry' => Extension\Content\Entry::class,
'CreativeCommons\Entry' => Extension\CreativeCommons\Entry::class,
'CreativeCommons\Feed' => Extension\CreativeCommons\Feed::class,
'DublinCore\Entry' => Extension\DublinCore\Entry::class,
'DublinCore\Feed' => Extension\DublinCore\Feed::class,
'Podcast\Entry' => Extension\Podcast\Entry::class,
'Podcast\Feed' => Extension\Podcast\Feed::class,
'Slash\Entry' => Extension\Slash\Entry::class,
'Syndication\Feed' => Extension\Syndication\Feed::class,
'Thread\Entry' => Extension\Thread\Entry::class,
'WellFormedWeb\Entry' => Extension\WellFormedWeb\Entry::class,
];

/**
Expand All @@ -49,4 +51,38 @@ public function get($extension)
$class = $this->extensions[$extension];
return new $class();
}

/**
* Add an extension.
*
* @param string $name
* @param string $class
*/
public function add($name, $class)
{
if (is_string($class) && (
is_a($class, Extension\AbstractEntry::class, true) ||
is_a($class, Extension\AbstractFeed::class, true))
) {
$this->extensions[$name] = $class;
return;
}

throw new InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %2$s\Extension\AbstractFeed '
. 'or %2$s\Extension\AbstractEntry',
$class,
__NAMESPACE__
));
}

/**
* Remove an extension.
*
* @param string $name
*/
public function remove($name)
{
unset($this->extensions[$name]);
}
}
38 changes: 38 additions & 0 deletions src/Writer/StandaloneExtensionManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

namespace Zend\Feed\Writer;

use Zend\Feed\Writer\Exception\InvalidArgumentException;

class StandaloneExtensionManager implements ExtensionManagerInterface
{
private $extensions = [
Expand Down Expand Up @@ -47,4 +49,40 @@ public function get($extension)
$class = $this->extensions[$extension];
return new $class();
}

/**
* Add an extension.
*
* @param string $name
* @param string $class
*/
public function add($name, $class)
{
if (is_string($class) && ((
is_a($class, Extension\AbstractRenderer::class, true) ||
'Feed' === substr($class, -4) ||
'Entry' === substr($class, -5)
))) {
$this->extensions[$name] = $class;

return;
}

throw new InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %s\Extension\RendererInterface '
. 'or the classname must end in "Feed" or "Entry"',
$class,
__NAMESPACE__
));
}

/**
* Remove an extension.
*
* @param string $name
*/
public function remove($name)
{
unset($this->extensions[$name]);
}
}
30 changes: 30 additions & 0 deletions test/Reader/StandaloneExtensionManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@

class StandaloneExtensionManagerTest extends TestCase
{
/**
* @var StandaloneExtensionManager
*/
private $extensions;

public function setUp()
{
$this->extensions = new StandaloneExtensionManager();
Expand Down Expand Up @@ -80,4 +85,29 @@ public function testEachPluginRetrievalReturnsNewInstance($pluginName, $pluginCl
$this->assertInstanceOf($pluginClass, $test);
$this->assertNotSame($extension, $test);
}

public function testAddAcceptsValidExtensionClasses()
{
$ext = $this->createMock(\Zend\Feed\Reader\Extension\AbstractEntry::class);
$this->extensions->add('Test/Entry', get_class($ext));
$this->assertTrue($this->extensions->has('Test/Entry'));
$ext = $this->createMock(\Zend\Feed\Reader\Extension\AbstractFeed::class);
$this->extensions->add('Test/Feed', get_class($ext));
$this->assertTrue($this->extensions->has('Test/Feed'));
}

public function testAddRejectsInvalidExtensions()
{
$this->expectException(\Zend\Feed\Reader\Exception\InvalidArgumentException::class);
$this->extensions->add('Test/Entry', 'blah');
}

public function testExtensionRemoval()
{
$ext = $this->createMock(\Zend\Feed\Reader\Extension\AbstractEntry::class);
$this->extensions->add('Test/Entry', get_class($ext));
$this->assertTrue($this->extensions->has('Test/Entry'));
$this->extensions->remove('Test/Entry');
$this->assertFalse($this->extensions->has('Test/Entry'));
}
}
123 changes: 123 additions & 0 deletions test/Writer/StandaloneExtensionManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
namespace ZendTest\Feed\Writer;

use PHPUnit\Framework\TestCase;
use Zend\Feed\Writer\StandaloneExtensionManager;
use Zend\Feed\Writer\ExtensionManagerInterface;

class StandaloneExtensionManagerTest extends TestCase
{
/**
* @var StandaloneExtensionManager
*/
private $extensions;

public function setUp()
{
$this->extensions = new StandaloneExtensionManager();
}

public function testIsAnExtensionManagerImplementation()
{
$this->assertInstanceOf(ExtensionManagerInterface::class, $this->extensions);
}

public function defaultPlugins()
{
return [
'Atom\Renderer\Feed' => [
'Atom\Renderer\Feed', \Zend\Feed\Writer\Extension\Atom\Renderer\Feed::class
],
'Content\Renderer\Entry' => [
'Content\Renderer\Entry', \Zend\Feed\Writer\Extension\Content\Renderer\Entry::class
],
'DublinCore\Renderer\Entry' => [
'DublinCore\Renderer\Entry', \Zend\Feed\Writer\Extension\DublinCore\Renderer\Entry::class
],
'DublinCore\Renderer\Feed' => [
'DublinCore\Renderer\Feed', \Zend\Feed\Writer\Extension\DublinCore\Renderer\Feed::class
],
'ITunes\Entry' => ['ITunes\Entry', \Zend\Feed\Writer\Extension\ITunes\Entry::class],
'ITunes\Feed' => ['ITunes\Feed', \Zend\Feed\Writer\Extension\ITunes\Feed::class],
'ITunes\Renderer\Entry' => [
'ITunes\Renderer\Entry', \Zend\Feed\Writer\Extension\ITunes\Renderer\Entry::class
],
'ITunes\Renderer\Feed' => [
'ITunes\Renderer\Feed', \Zend\Feed\Writer\Extension\ITunes\Renderer\Feed::class
],
'Slash\Renderer\Entry' => [
'Slash\Renderer\Entry', \Zend\Feed\Writer\Extension\Slash\Renderer\Entry::class
],
'Threading\Renderer\Entry' => [
'Threading\Renderer\Entry', \Zend\Feed\Writer\Extension\Threading\Renderer\Entry::class
],
'WellFormedWeb\Renderer\Entry' => [
'WellFormedWeb\Renderer\Entry', \Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry::class
],
];
}

/**
* @dataProvider defaultPlugins
*/
public function testHasAllDefaultPlugins($pluginName, $pluginClass)
{
$this->assertTrue($this->extensions->has($pluginName));
}

/**
* @dataProvider defaultPlugins
*/
public function testCanRetrieveDefaultPluginInstances($pluginName, $pluginClass)
{
$extension = $this->extensions->get($pluginName);
$this->assertInstanceOf($pluginClass, $extension);
}

/**
* @dataProvider defaultPlugins
*/
public function testEachPluginRetrievalReturnsNewInstance($pluginName, $pluginClass)
{
$extension = $this->extensions->get($pluginName);
$this->assertInstanceOf($pluginClass, $extension);

$test = $this->extensions->get($pluginName);
$this->assertInstanceOf($pluginClass, $test);
$this->assertNotSame($extension, $test);
}

public function testAddAcceptsValidExtensionClasses()
{
$this->extensions->add('Test/Feed', 'MyTestExtension_Feed');
$this->assertTrue($this->extensions->has('Test/Feed'));

$this->extensions->add('Test/Entry', 'MyTestExtension_Entry');
$this->assertTrue($this->extensions->has('Test/Entry'));

$ext = $this->createMock(\Zend\Feed\Writer\Extension\AbstractRenderer::class);
$this->extensions->add('Test/Thing', get_class($ext));
$this->assertTrue($this->extensions->has('Test/Thing'));
}

public function testAddRejectsInvalidExtensions()
{
$this->expectException(\Zend\Feed\Writer\Exception\InvalidArgumentException::class);
$this->extensions->add('Test/Feed', 'blah');
}

public function testExtensionRemoval()
{
$this->extensions->add('Test/Entry', 'MyTestExtension_Entry');
$this->assertTrue($this->extensions->has('Test/Entry'));
$this->extensions->remove('Test/Entry');
$this->assertFalse($this->extensions->has('Test/Entry'));
}
}

0 comments on commit ab4e22e

Please sign in to comment.