1<?php 2 3/** 4 * @see https://github.com/laminas/laminas-feed for the canonical source repository 5 * @copyright https://github.com/laminas/laminas-feed/blob/master/COPYRIGHT.md 6 * @license https://github.com/laminas/laminas-feed/blob/master/LICENSE.md New BSD License 7 */ 8 9namespace Laminas\Feed\Reader; 10 11use Laminas\ServiceManager\AbstractPluginManager; 12use Laminas\ServiceManager\Exception\InvalidServiceException; 13use Laminas\ServiceManager\Factory\InvokableFactory; 14 15/** 16 * Plugin manager implementation for feed reader extensions based on the 17 * AbstractPluginManager. 18 * 19 * Validation checks that we have an Extension\AbstractEntry or 20 * Extension\AbstractFeed. 21 */ 22class ExtensionPluginManager extends AbstractPluginManager implements ExtensionManagerInterface 23{ 24 /** 25 * Aliases for default set of extension classes 26 * 27 * @var array 28 */ 29 protected $aliases = [ 30 'atomentry' => Extension\Atom\Entry::class, 31 'atomEntry' => Extension\Atom\Entry::class, 32 'AtomEntry' => Extension\Atom\Entry::class, 33 'Atom\Entry' => Extension\Atom\Entry::class, 34 'atomfeed' => Extension\Atom\Feed::class, 35 'atomFeed' => Extension\Atom\Feed::class, 36 'AtomFeed' => Extension\Atom\Feed::class, 37 'Atom\Feed' => Extension\Atom\Feed::class, 38 'contententry' => Extension\Content\Entry::class, 39 'contentEntry' => Extension\Content\Entry::class, 40 'ContentEntry' => Extension\Content\Entry::class, 41 'Content\Entry' => Extension\Content\Entry::class, 42 'creativecommonsentry' => Extension\CreativeCommons\Entry::class, 43 'creativeCommonsEntry' => Extension\CreativeCommons\Entry::class, 44 'CreativeCommonsEntry' => Extension\CreativeCommons\Entry::class, 45 'CreativeCommons\Entry' => Extension\CreativeCommons\Entry::class, 46 'creativecommonsfeed' => Extension\CreativeCommons\Feed::class, 47 'creativeCommonsFeed' => Extension\CreativeCommons\Feed::class, 48 'CreativeCommonsFeed' => Extension\CreativeCommons\Feed::class, 49 'CreativeCommons\Feed' => Extension\CreativeCommons\Feed::class, 50 'dublincoreentry' => Extension\DublinCore\Entry::class, 51 'dublinCoreEntry' => Extension\DublinCore\Entry::class, 52 'DublinCoreEntry' => Extension\DublinCore\Entry::class, 53 'DublinCore\Entry' => Extension\DublinCore\Entry::class, 54 'dublincorefeed' => Extension\DublinCore\Feed::class, 55 'dublinCoreFeed' => Extension\DublinCore\Feed::class, 56 'DublinCoreFeed' => Extension\DublinCore\Feed::class, 57 'DublinCore\Feed' => Extension\DublinCore\Feed::class, 58 'googleplaypodcastentry' => Extension\GooglePlayPodcast\Entry::class, 59 'googlePlayPodcastEntry' => Extension\GooglePlayPodcast\Entry::class, 60 'GooglePlayPodcastEntry' => Extension\GooglePlayPodcast\Entry::class, 61 'GooglePlayPodcast\Entry' => Extension\GooglePlayPodcast\Entry::class, 62 'googleplaypodcastfeed' => Extension\GooglePlayPodcast\Feed::class, 63 'googlePlayPodcastFeed' => Extension\GooglePlayPodcast\Feed::class, 64 'GooglePlayPodcastFeed' => Extension\GooglePlayPodcast\Feed::class, 65 'GooglePlayPodcast\Feed' => Extension\GooglePlayPodcast\Feed::class, 66 'podcastentry' => Extension\Podcast\Entry::class, 67 'podcastEntry' => Extension\Podcast\Entry::class, 68 'PodcastEntry' => Extension\Podcast\Entry::class, 69 'Podcast\Entry' => Extension\Podcast\Entry::class, 70 'podcastfeed' => Extension\Podcast\Feed::class, 71 'podcastFeed' => Extension\Podcast\Feed::class, 72 'PodcastFeed' => Extension\Podcast\Feed::class, 73 'Podcast\Feed' => Extension\Podcast\Feed::class, 74 'slashentry' => Extension\Slash\Entry::class, 75 'slashEntry' => Extension\Slash\Entry::class, 76 'SlashEntry' => Extension\Slash\Entry::class, 77 'Slash\Entry' => Extension\Slash\Entry::class, 78 'syndicationfeed' => Extension\Syndication\Feed::class, 79 'syndicationFeed' => Extension\Syndication\Feed::class, 80 'SyndicationFeed' => Extension\Syndication\Feed::class, 81 'Syndication\Feed' => Extension\Syndication\Feed::class, 82 'threadentry' => Extension\Thread\Entry::class, 83 'threadEntry' => Extension\Thread\Entry::class, 84 'ThreadEntry' => Extension\Thread\Entry::class, 85 'Thread\Entry' => Extension\Thread\Entry::class, 86 'wellformedwebentry' => Extension\WellFormedWeb\Entry::class, 87 'wellFormedWebEntry' => Extension\WellFormedWeb\Entry::class, 88 'WellFormedWebEntry' => Extension\WellFormedWeb\Entry::class, 89 'WellFormedWeb\Entry' => Extension\WellFormedWeb\Entry::class, 90 91 // Legacy Zend Framework aliases 92 \Zend\Feed\Reader\Extension\Atom\Entry::class => Extension\Atom\Entry::class, 93 \Zend\Feed\Reader\Extension\Atom\Feed::class => Extension\Atom\Feed::class, 94 \Zend\Feed\Reader\Extension\Content\Entry::class => Extension\Content\Entry::class, 95 \Zend\Feed\Reader\Extension\CreativeCommons\Entry::class => Extension\CreativeCommons\Entry::class, 96 \Zend\Feed\Reader\Extension\CreativeCommons\Feed::class => Extension\CreativeCommons\Feed::class, 97 \Zend\Feed\Reader\Extension\DublinCore\Entry::class => Extension\DublinCore\Entry::class, 98 \Zend\Feed\Reader\Extension\DublinCore\Feed::class => Extension\DublinCore\Feed::class, 99 \Zend\Feed\Reader\Extension\GooglePlayPodcast\Entry::class => Extension\GooglePlayPodcast\Entry::class, 100 \Zend\Feed\Reader\Extension\GooglePlayPodcast\Feed::class => Extension\GooglePlayPodcast\Feed::class, 101 \Zend\Feed\Reader\Extension\Podcast\Entry::class => Extension\Podcast\Entry::class, 102 \Zend\Feed\Reader\Extension\Podcast\Feed::class => Extension\Podcast\Feed::class, 103 \Zend\Feed\Reader\Extension\Slash\Entry::class => Extension\Slash\Entry::class, 104 \Zend\Feed\Reader\Extension\Syndication\Feed::class => Extension\Syndication\Feed::class, 105 \Zend\Feed\Reader\Extension\Thread\Entry::class => Extension\Thread\Entry::class, 106 \Zend\Feed\Reader\Extension\WellFormedWeb\Entry::class => Extension\WellFormedWeb\Entry::class, 107 108 // v2 normalized FQCNs 109 'zendfeedreaderextensionatomentry' => Extension\Atom\Entry::class, 110 'zendfeedreaderextensionatomfeed' => Extension\Atom\Feed::class, 111 'zendfeedreaderextensioncontententry' => Extension\Content\Entry::class, 112 'zendfeedreaderextensioncreativecommonsentry' => Extension\CreativeCommons\Entry::class, 113 'zendfeedreaderextensioncreativecommonsfeed' => Extension\CreativeCommons\Feed::class, 114 'zendfeedreaderextensiondublincoreentry' => Extension\DublinCore\Entry::class, 115 'zendfeedreaderextensiondublincorefeed' => Extension\DublinCore\Feed::class, 116 'zendfeedreaderextensiongoogleplaypodcastentry' => Extension\GooglePlayPodcast\Entry::class, 117 'zendfeedreaderextensiongoogleplaypodcastfeed' => Extension\GooglePlayPodcast\Feed::class, 118 'zendfeedreaderextensionpodcastentry' => Extension\Podcast\Entry::class, 119 'zendfeedreaderextensionpodcastfeed' => Extension\Podcast\Feed::class, 120 'zendfeedreaderextensionslashentry' => Extension\Slash\Entry::class, 121 'zendfeedreaderextensionsyndicationfeed' => Extension\Syndication\Feed::class, 122 'zendfeedreaderextensionthreadentry' => Extension\Thread\Entry::class, 123 'zendfeedreaderextensionwellformedwebentry' => Extension\WellFormedWeb\Entry::class, 124 ]; 125 126 /** 127 * Factories for default set of extension classes 128 * 129 * @var array 130 */ 131 protected $factories = [ 132 Extension\Atom\Entry::class => InvokableFactory::class, 133 Extension\Atom\Feed::class => InvokableFactory::class, 134 Extension\Content\Entry::class => InvokableFactory::class, 135 Extension\CreativeCommons\Entry::class => InvokableFactory::class, 136 Extension\CreativeCommons\Feed::class => InvokableFactory::class, 137 Extension\DublinCore\Entry::class => InvokableFactory::class, 138 Extension\DublinCore\Feed::class => InvokableFactory::class, 139 Extension\GooglePlayPodcast\Entry::class => InvokableFactory::class, 140 Extension\GooglePlayPodcast\Feed::class => InvokableFactory::class, 141 Extension\Podcast\Entry::class => InvokableFactory::class, 142 Extension\Podcast\Feed::class => InvokableFactory::class, 143 Extension\Slash\Entry::class => InvokableFactory::class, 144 Extension\Syndication\Feed::class => InvokableFactory::class, 145 Extension\Thread\Entry::class => InvokableFactory::class, 146 Extension\WellFormedWeb\Entry::class => InvokableFactory::class, 147 // Legacy (v2) due to alias resolution; canonical form of resolved 148 // alias is used to look up the factory, while the non-normalized 149 // resolved alias is used as the requested name passed to the factory. 150 'laminasfeedreaderextensionatomentry' => InvokableFactory::class, 151 'laminasfeedreaderextensionatomfeed' => InvokableFactory::class, 152 'laminasfeedreaderextensioncontententry' => InvokableFactory::class, 153 'laminasfeedreaderextensioncreativecommonsentry' => InvokableFactory::class, 154 'laminasfeedreaderextensioncreativecommonsfeed' => InvokableFactory::class, 155 'laminasfeedreaderextensiondublincoreentry' => InvokableFactory::class, 156 'laminasfeedreaderextensiondublincorefeed' => InvokableFactory::class, 157 'laminasfeedreaderextensiongoogleplaypodcastentry' => InvokableFactory::class, 158 'laminasfeedreaderextensiongoogleplaypodcastfeed' => InvokableFactory::class, 159 'laminasfeedreaderextensionpodcastentry' => InvokableFactory::class, 160 'laminasfeedreaderextensionpodcastfeed' => InvokableFactory::class, 161 'laminasfeedreaderextensionslashentry' => InvokableFactory::class, 162 'laminasfeedreaderextensionsyndicationfeed' => InvokableFactory::class, 163 'laminasfeedreaderextensionthreadentry' => InvokableFactory::class, 164 'laminasfeedreaderextensionwellformedwebentry' => InvokableFactory::class, 165 ]; 166 167 /** 168 * Do not share instances (v2) 169 * 170 * @var bool 171 */ 172 protected $shareByDefault = false; 173 174 /** 175 * Do not share instances (v3) 176 * 177 * @var bool 178 */ 179 protected $sharedByDefault = false; 180 181 /** 182 * Validate the plugin 183 * 184 * Checks that the extension loaded is of a valid type. 185 * 186 * @param mixed $plugin 187 * @return void 188 * @throws Exception\InvalidArgumentException if invalid 189 */ 190 public function validate($plugin) 191 { 192 if ($plugin instanceof Extension\AbstractEntry 193 || $plugin instanceof Extension\AbstractFeed 194 ) { 195 // we're okay 196 return; 197 } 198 199 throw new InvalidServiceException(sprintf( 200 'Plugin of type %s is invalid; must implement %s\Extension\AbstractFeed ' 201 . 'or %s\Extension\AbstractEntry', 202 is_object($plugin) ? get_class($plugin) : gettype($plugin), 203 __NAMESPACE__, 204 __NAMESPACE__ 205 )); 206 } 207 208 /** 209 * Validate the plugin (v2) 210 * 211 * @param mixed $plugin 212 * @return void 213 * @throws Exception\InvalidArgumentException if invalid 214 */ 215 public function validatePlugin($plugin) 216 { 217 try { 218 $this->validate($plugin); 219 } catch (InvalidServiceException $e) { 220 throw new Exception\InvalidArgumentException(sprintf( 221 'Plugin of type %s is invalid; must implement %s\Extension\AbstractFeed ' 222 . 'or %s\Extension\AbstractEntry', 223 is_object($plugin) ? get_class($plugin) : gettype($plugin), 224 __NAMESPACE__, 225 __NAMESPACE__ 226 )); 227 } 228 } 229} 230