zendframework / zend-feed

Feed component from Zend Framework
BSD 3-Clause "New" or "Revised" License
166 stars 42 forks source link

Could not load extension: GooglePlayPodcast using Plugin Loader #80

Closed Synchro closed 6 years ago

Synchro commented 6 years ago

This is a little note for anyone running into this error. You will need to add the new GooglePlayPodcast extensions to your extension manager so that the extension can be found, like this:

namespace MyApp\RSS;

use Zend\Feed\Reader\Extension;
use Zend\Feed\Reader\ExtensionManagerInterface;

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',
        'GooglePlayPodcast\Entry' => 'Zend\Feed\Reader\Extension\GooglePlayPodcast\Entry', //New
        'GooglePlayPodcast\Feed' => 'Zend\Feed\Reader\Extension\GooglePlayPodcast\Feed', //New
        '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'
    ];
...

I have no idea why these need to be added explicitly since it seems it won't work without them. I saw that Drupal ran into the same thing.

weierophinney commented 6 years ago

Re-opening; the intention was to have these entries in place. We'll issue a bugfix release soon that ensures they are present.

Synchro commented 6 years ago

Thanks, glad it wasn't just me!

weierophinney commented 6 years ago

Hmmm... I thought this had to do with our own StandaloneExtensionManager, but it turns out it's different.

We do register it already (see https://github.com/zendframework/zend-feed/blob/875414e3413eab96253dcde79a94432ebf16f693/src/Reader/StandaloneExtensionManager.php#L24-L25 and https://github.com/zendframework/zend-feed/blob/875414e3413eab96253dcde79a94432ebf16f693/src/Reader/ExtensionPluginManager.php#L106-L107).

The problem is the fact that we register it as a core extension by default in Zend\Feed\Reader\Reader (see https://github.com/zendframework/zend-feed/blob/875414e3413eab96253dcde79a94432ebf16f693/src/Reader/Reader.php#L675). This means that if you are using a custom extension manager, and have not yet added these entries, you will get an error.

I'm going to see if I can add some code that will detect the presence of the required entries before attempting to register them. My personal take is that this should likely emit an E_USER_NOTICE that indicates the entries should be added to the extension manager.

Synchro commented 6 years ago

OK. I'd really like to do without an extension manager if possible. I have one extension that adds MRSS media support, and I gather I need to have a custom extension manager that loads all the standard extensions in order to load that extra one. Is that correct?

"All I want is" a class that will return a sensible RSS structure when given a URL and not explode when it encounters something unusual; I'm finding the mix of managers, extensions, and containers very confusing, especially since I'm not using ZF otherwise.

weierophinney commented 6 years ago

I have one extension that adds MRSS media support, and I gather I need to have a custom extension manager that loads all the standard extensions in order to load that extra one. Is that correct?

Correct.

We provide a "standalone" extension manager that has the various defaults we allow already, and this always has all core extensions represented. It also has a mechanism by which you can add extensions once you have an instance:

use Zend\Feed\Reader\Reader;
use Zend\Feed\Reader\StandaloneExtensionManager;

$extensions = new StandaloneExtensionManager();

// Register custom feed and entry classes with the manager:
$extensions->add('MRSS\Feed', \My\Feed\MRSS\Feed::class);
$extensions->add('MRSS\Entry', \My\Feed\MRSS\Entry::class);

// Tell Reader to use the custom extension manager:
Reader::setExtensionManager($extensions);

// Register the MRSS extension with the reader (which we can
// now do as the extension manager knows about the feed and entry
// types:
Reader::registerExtension('MRSS');

You cannot currently extend the class to auto-provide your extension, as the class uses private visibility; we can potentially open that in the future, but the add() (and it's opposite, remove()) function allows modification already.

I'm finding the mix of managers, extensions, and containers very confusing

What it comes down to is:

Hope the above helps you out!

I've also opened #81 to make the GooglePlayPodcast extension registration conditional; if no entry is present for it in the extension manager, Reader will not attempt to register the extension, but will emit an E_USER_NOTICE indicating you should add it to your extension manager implementation.

Synchro commented 6 years ago

Excellent, thanks.

weierophinney commented 6 years ago

2.10.2 has been released, which resolves this problem for existing users.