updated core and modules

This commit is contained in:
Bachir Soussi Chiadmi
2017-09-09 16:27:51 +02:00
parent 027aa99b32
commit 41863f872c
7810 changed files with 318922 additions and 83631 deletions
+2 -2
View File
@@ -104,7 +104,7 @@ class Atom extends AbstractEntry implements EntryInterface
/**
* Get the entry creation date
*
* @return string
* @return \DateTime
*/
public function getDateCreated()
{
@@ -122,7 +122,7 @@ class Atom extends AbstractEntry implements EntryInterface
/**
* Get the entry modification date
*
* @return string
* @return \DateTime
*/
public function getDateModified()
{
@@ -38,14 +38,14 @@ interface EntryInterface
/**
* Get the entry creation date
*
* @return string
* @return \DateTime
*/
public function getDateCreated();
/**
* Get the entry modification date
*
* @return string
* @return \DateTime
*/
public function getDateModified();
+2 -2
View File
@@ -167,7 +167,7 @@ class Rss extends AbstractEntry implements EntryInterface
/**
* Get the entry's date of creation
*
* @return string
* @return \DateTime
*/
public function getDateCreated()
{
@@ -178,7 +178,7 @@ class Rss extends AbstractEntry implements EntryInterface
* Get the entry's date of modification
*
* @throws Exception\RuntimeException
* @return string
* @return \DateTime
*/
public function getDateModified()
{
@@ -0,0 +1,16 @@
<?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 Zend\Feed\Reader\Exception;
use Zend\Feed\Exception;
class InvalidHttpClientException extends Exception\InvalidArgumentException implements ExceptionInterface
{
}
@@ -10,6 +10,8 @@
namespace Zend\Feed\Reader;
use Zend\ServiceManager\AbstractPluginManager;
use Zend\ServiceManager\Exception\InvalidServiceException;
use Zend\ServiceManager\Factory\InvokableFactory;
/**
* Plugin manager implementation for feed reader extensions based on the
@@ -21,33 +23,103 @@ use Zend\ServiceManager\AbstractPluginManager;
class ExtensionPluginManager extends AbstractPluginManager
{
/**
* Default set of extension classes
* Aliases for default set of extension classes
*
* @var array
*/
protected $invokableClasses = [
'atomentry' => 'Zend\Feed\Reader\Extension\Atom\Entry',
'atomfeed' => 'Zend\Feed\Reader\Extension\Atom\Feed',
'contententry' => 'Zend\Feed\Reader\Extension\Content\Entry',
'creativecommonsentry' => 'Zend\Feed\Reader\Extension\CreativeCommons\Entry',
'creativecommonsfeed' => 'Zend\Feed\Reader\Extension\CreativeCommons\Feed',
'dublincoreentry' => 'Zend\Feed\Reader\Extension\DublinCore\Entry',
'dublincorefeed' => 'Zend\Feed\Reader\Extension\DublinCore\Feed',
'podcastentry' => 'Zend\Feed\Reader\Extension\Podcast\Entry',
'podcastfeed' => 'Zend\Feed\Reader\Extension\Podcast\Feed',
'slashentry' => 'Zend\Feed\Reader\Extension\Slash\Entry',
'syndicationfeed' => 'Zend\Feed\Reader\Extension\Syndication\Feed',
'threadentry' => 'Zend\Feed\Reader\Extension\Thread\Entry',
'wellformedwebentry' => 'Zend\Feed\Reader\Extension\WellFormedWeb\Entry',
protected $aliases = [
'atomentry' => Extension\Atom\Entry::class,
'atomEntry' => Extension\Atom\Entry::class,
'AtomEntry' => Extension\Atom\Entry::class,
'atomfeed' => Extension\Atom\Feed::class,
'atomFeed' => Extension\Atom\Feed::class,
'AtomFeed' => Extension\Atom\Feed::class,
'contententry' => Extension\Content\Entry::class,
'contentEntry' => Extension\Content\Entry::class,
'ContentEntry' => Extension\Content\Entry::class,
'creativecommonsentry' => Extension\CreativeCommons\Entry::class,
'creativeCommonsEntry' => Extension\CreativeCommons\Entry::class,
'CreativeCommonsEntry' => Extension\CreativeCommons\Entry::class,
'creativecommonsfeed' => Extension\CreativeCommons\Feed::class,
'creativeCommonsFeed' => Extension\CreativeCommons\Feed::class,
'CreativeCommonsFeed' => Extension\CreativeCommons\Feed::class,
'dublincoreentry' => Extension\DublinCore\Entry::class,
'dublinCoreEntry' => Extension\DublinCore\Entry::class,
'DublinCoreEntry' => Extension\DublinCore\Entry::class,
'dublincorefeed' => Extension\DublinCore\Feed::class,
'dublinCoreFeed' => Extension\DublinCore\Feed::class,
'DublinCoreFeed' => Extension\DublinCore\Feed::class,
'podcastentry' => Extension\Podcast\Entry::class,
'podcastEntry' => Extension\Podcast\Entry::class,
'PodcastEntry' => Extension\Podcast\Entry::class,
'podcastfeed' => Extension\Podcast\Feed::class,
'podcastFeed' => Extension\Podcast\Feed::class,
'PodcastFeed' => Extension\Podcast\Feed::class,
'slashentry' => Extension\Slash\Entry::class,
'slashEntry' => Extension\Slash\Entry::class,
'SlashEntry' => Extension\Slash\Entry::class,
'syndicationfeed' => Extension\Syndication\Feed::class,
'syndicationFeed' => Extension\Syndication\Feed::class,
'SyndicationFeed' => Extension\Syndication\Feed::class,
'threadentry' => Extension\Thread\Entry::class,
'threadEntry' => Extension\Thread\Entry::class,
'ThreadEntry' => Extension\Thread\Entry::class,
'wellformedwebentry' => Extension\WellFormedWeb\Entry::class,
'wellFormedWebEntry' => Extension\WellFormedWeb\Entry::class,
'WellFormedWebEntry' => Extension\WellFormedWeb\Entry::class,
];
/**
* Do not share instances
* Factories for default set of extension classes
*
* @var array
*/
protected $factories = [
Extension\Atom\Entry::class => InvokableFactory::class,
Extension\Atom\Feed::class => InvokableFactory::class,
Extension\Content\Entry::class => InvokableFactory::class,
Extension\CreativeCommons\Entry::class => InvokableFactory::class,
Extension\CreativeCommons\Feed::class => InvokableFactory::class,
Extension\DublinCore\Entry::class => InvokableFactory::class,
Extension\DublinCore\Feed::class => InvokableFactory::class,
Extension\Podcast\Entry::class => InvokableFactory::class,
Extension\Podcast\Feed::class => InvokableFactory::class,
Extension\Slash\Entry::class => InvokableFactory::class,
Extension\Syndication\Feed::class => InvokableFactory::class,
Extension\Thread\Entry::class => InvokableFactory::class,
Extension\WellFormedWeb\Entry::class => InvokableFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'zendfeedreaderextensionatomentry' => InvokableFactory::class,
'zendfeedreaderextensionatomfeed' => InvokableFactory::class,
'zendfeedreaderextensioncontententry' => InvokableFactory::class,
'zendfeedreaderextensioncreativecommonsentry' => InvokableFactory::class,
'zendfeedreaderextensioncreativecommonsfeed' => InvokableFactory::class,
'zendfeedreaderextensiondublincoreentry' => InvokableFactory::class,
'zendfeedreaderextensiondublincorefeed' => InvokableFactory::class,
'zendfeedreaderextensionpodcastentry' => InvokableFactory::class,
'zendfeedreaderextensionpodcastfeed' => InvokableFactory::class,
'zendfeedreaderextensionslashentry' => InvokableFactory::class,
'zendfeedreaderextensionsyndicationfeed' => InvokableFactory::class,
'zendfeedreaderextensionthreadentry' => InvokableFactory::class,
'zendfeedreaderextensionwellformedwebentry' => InvokableFactory::class,
];
/**
* Do not share instances (v2)
*
* @var bool
*/
protected $shareByDefault = false;
/**
* Do not share instances (v3)
*
* @var bool
*/
protected $sharedByDefault = false;
/**
* Validate the plugin
*
@@ -57,7 +129,7 @@ class ExtensionPluginManager extends AbstractPluginManager
* @return void
* @throws Exception\InvalidArgumentException if invalid
*/
public function validatePlugin($plugin)
public function validate($plugin)
{
if ($plugin instanceof Extension\AbstractEntry
|| $plugin instanceof Extension\AbstractFeed
@@ -66,7 +138,7 @@ class ExtensionPluginManager extends AbstractPluginManager
return;
}
throw new Exception\InvalidArgumentException(sprintf(
throw new InvalidServiceException(sprintf(
'Plugin of type %s is invalid; must implement %s\Extension\AbstractFeed '
. 'or %s\Extension\AbstractEntry',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
@@ -74,4 +146,26 @@ class ExtensionPluginManager extends AbstractPluginManager
__NAMESPACE__
));
}
/**
* Validate the plugin (v2)
*
* @param mixed $plugin
* @return void
* @throws Exception\InvalidArgumentException if invalid
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %s\Extension\AbstractFeed '
. 'or %s\Extension\AbstractEntry',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__,
__NAMESPACE__
));
}
}
}
@@ -0,0 +1,33 @@
<?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 Zend\Feed\Reader\Http;
interface HeaderAwareClientInterface extends ClientInterface
{
/**
* Allow specifying headers to use when fetching a feed.
*
* Headers MUST be in the format:
*
* <code>
* [
* 'header-name' => [
* 'header',
* 'values'
* ]
* ]
* </code>
*
* @param string $uri
* @param array $headers
* @return HeaderAwareResponseInterface
*/
public function get($uri, array $headers = []);
}
@@ -0,0 +1,28 @@
<?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 Zend\Feed\Reader\Http;
interface HeaderAwareResponseInterface extends ResponseInterface
{
/**
* Retrieve a header (as a single line) from the response.
*
* Header name lookups MUST be case insensitive.
*
* Since the only header values the feed reader consumes are singular
* in nature, this method is expected to return a string, and not
* an array of values.
*
* @param string $name Header name to retrieve.
* @param mixed $default Default value to use if header is not present.
* @return string
*/
public function getHeaderLine($name, $default = null);
}
@@ -0,0 +1,68 @@
<?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 Zend\Feed\Reader\Http;
use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface;
/**
* ResponseInterface wrapper for a PSR-7 response.
*/
class Psr7ResponseDecorator implements HeaderAwareResponseInterface
{
/**
* @var Psr7ResponseInterface
*/
private $decoratedResponse;
/**
* @param Psr7ResponseInterface $response
*/
public function __construct(Psr7ResponseInterface $response)
{
$this->decoratedResponse = $response;
}
/**
* Return the original PSR-7 response being decorated.
*
* @return Psr7ResponseInterface
*/
public function getDecoratedResponse()
{
return $this->decoratedResponse;
}
/**
* {@inheritDoc}
*/
public function getBody()
{
return (string) $this->decoratedResponse->getBody();
}
/**
* {@inheritDoc}
*/
public function getStatusCode()
{
return $this->decoratedResponse->getStatusCode();
}
/**
* {@inheritDoc}
*/
public function getHeaderLine($name, $default = null)
{
if (! $this->decoratedResponse->hasHeader($name)) {
return $default;
}
return $this->decoratedResponse->getHeaderLine($name);
}
}
@@ -0,0 +1,175 @@
<?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 Zend\Feed\Reader\Http;
use Zend\Feed\Reader\Exception;
class Response implements HeaderAwareResponseInterface
{
/**
* @var string
*/
private $body;
/**
* @var array
*/
private $headers;
/**
* @var int
*/
private $statusCode;
/**
* @param int $statusCode
* @param string|object $body
* @param array $headers
* @throws Exception\InvalidArgumentException
*/
public function __construct($statusCode, $body = '', array $headers = [])
{
$this->validateStatusCode($statusCode);
$this->validateBody($body);
$this->validateHeaders($headers);
$this->statusCode = (int) $statusCode;
$this->body = (string) $body;
$this->headers = $this->normalizeHeaders($headers);
}
/**
* {@inheritDoc}
*/
public function getStatusCode()
{
return $this->statusCode;
}
/**
* {@inheritDoc}
*/
public function getBody()
{
return $this->body;
}
/**
* {@inheritDoc}
*/
public function getHeaderLine($name, $default = null)
{
$normalizedName = strtolower($name);
return isset($this->headers[$normalizedName])
? $this->headers[$normalizedName]
: $default;
}
/**
* Validate that we have a status code argument that will work for our context.
*
* @param mixed $body
* @throws Exception\InvalidArgumentException for arguments not castable
* to integer HTTP status codes.
*/
private function validateStatusCode($statusCode)
{
if (! is_numeric($statusCode)) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a numeric status code; received %s',
__CLASS__,
(is_object($statusCode) ? get_class($statusCode) : gettype($statusCode))
));
}
if (100 > $statusCode || 599 < $statusCode) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an integer status code between 100 and 599 inclusive; received %s',
__CLASS__,
$statusCode
));
}
if (intval($statusCode) != $statusCode) {
throw new Exception\InvalidArgumentException(sprintf(
'%s expects an integer status code; received %s',
__CLASS__,
$statusCode
));
}
}
/**
* Validate that we have a body argument that will work for our context.
*
* @param mixed $body
* @throws Exception\InvalidArgumentException for arguments not castable
* to strings.
*/
private function validateBody($body)
{
if (is_string($body)) {
return;
}
if (is_object($body) && method_exists($body, '__toString')) {
return;
}
throw new Exception\InvalidArgumentException(sprintf(
'%s expects a string body, or an object that can cast to string; received %s',
__CLASS__,
(is_object($body) ? get_class($body) : gettype($body))
));
}
/**
* Validate header values.
*
* @param array $headers
* @throws Exception\InvalidArgumentException
*/
private function validateHeaders(array $headers)
{
foreach ($headers as $name => $value) {
if (! is_string($name) || is_numeric($name) || empty($name)) {
throw new Exception\InvalidArgumentException(sprintf(
'Header names provided to %s must be non-empty, non-numeric strings; received %s',
__CLASS__,
$name
));
}
if (! is_string($value) && ! is_numeric($value)) {
throw new Exception\InvalidArgumentException(sprintf(
'Individual header values provided to %s must be a string or numeric; received %s for header %s',
__CLASS__,
(is_object($value) ? get_class($value) : gettype($value)),
$name
));
}
}
}
/**
* Normalize header names to lowercase.
*
* @param array $headers
* @return array
*/
private function normalizeHeaders(array $headers)
{
$normalized = [];
foreach ($headers as $name => $value) {
$normalized[strtolower($name)] = $value;
}
return $normalized;
}
}
@@ -0,0 +1,118 @@
<?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 Zend\Feed\Reader\Http;
use Zend\Http\Client as ZendHttpClient;
use Zend\Http\Headers;
use Zend\Feed\Reader\Exception;
class ZendHttpClientDecorator implements HeaderAwareClientInterface
{
/**
* @var ZendHttpClient
*/
private $client;
/**
* @param ZendHttpClient $client
*/
public function __construct(ZendHttpClient $client)
{
$this->client = $client;
}
/**
* @return ZendHttpClient
*/
public function getDecoratedClient()
{
return $this->client;
}
/**
* {@inheritDoc}
*/
public function get($uri, array $headers = [])
{
$this->client->resetParameters();
$this->client->setMethod('GET');
$this->client->setHeaders(new Headers());
$this->client->setUri($uri);
if (! empty($headers)) {
$this->injectHeaders($headers);
}
$response = $this->client->send();
return new Response(
$response->getStatusCode(),
$response->getBody(),
$this->prepareResponseHeaders($response->getHeaders())
);
}
/**
* Inject header values into the client.
*
* @param array $headerValues
*/
private function injectHeaders(array $headerValues)
{
$headers = $this->client->getRequest()->getHeaders();
foreach ($headerValues as $name => $values) {
if (! is_string($name) || is_numeric($name) || empty($name)) {
throw new Exception\InvalidArgumentException(sprintf(
'Header names provided to %s::get must be non-empty, non-numeric strings; received %s',
__CLASS__,
$name
));
}
if (! is_array($values)) {
throw new Exception\InvalidArgumentException(sprintf(
'Header values provided to %s::get must be arrays of values; received %s',
__CLASS__,
(is_object($values) ? get_class($values) : gettype($values))
));
}
foreach ($values as $value) {
if (! is_string($value) && ! is_numeric($value)) {
throw new Exception\InvalidArgumentException(sprintf(
'Individual header values provided to %s::get must be strings or numbers; '
. 'received %s for header %s',
__CLASS__,
(is_object($value) ? get_class($value) : gettype($value)),
$name
));
}
$headers->addHeaderLine($name, $value);
}
}
}
/**
* Normalize headers to use with HeaderAwareResponseInterface.
*
* Ensures multi-value headers are represented as a single string, via
* comma concatenation.
*
* @param Headers $headers
* @return array
*/
private function prepareResponseHeaders(Headers $headers)
{
$normalized = [];
foreach ($headers->toArray() as $name => $value) {
$normalized[$name] = is_array($value) ? implode(', ', $value) : $value;
}
return $normalized;
}
}
+37 -28
View File
@@ -14,6 +14,7 @@ use DOMXPath;
use Zend\Cache\Storage\StorageInterface as CacheStorage;
use Zend\Http as ZendHttp;
use Zend\Stdlib\ErrorHandler;
use Zend\Feed\Reader\Exception\InvalidHttpClientException;
/**
*/
@@ -57,7 +58,7 @@ class Reader implements ReaderImportInterface
/**
* HTTP client object to use for retrieving feeds
*
* @var ZendHttp\Client
* @var Http\ClientInterface
*/
protected static $httpClient = null;
@@ -117,23 +118,30 @@ class Reader implements ReaderImportInterface
*
* Sets the HTTP client object to use for retrieving the feeds.
*
* @param ZendHttp\Client $httpClient
* @param ZendHttp\Client | Http\ClientInterface $httpClient
* @return void
*/
public static function setHttpClient(ZendHttp\Client $httpClient)
public static function setHttpClient($httpClient)
{
if ($httpClient instanceof ZendHttp\Client) {
$httpClient = new Http\ZendHttpClientDecorator($httpClient);
}
if (! $httpClient instanceof Http\ClientInterface) {
throw new InvalidHttpClientException();
}
static::$httpClient = $httpClient;
}
/**
* Gets the HTTP client object. If none is set, a new ZendHttp\Client will be used.
*
* @return ZendHttp\Client
* @return Http\ClientInterface
*/
public static function getHttpClient()
{
if (!static::$httpClient instanceof ZendHttp\Client) {
static::$httpClient = new ZendHttp\Client();
if (! static::$httpClient) {
static::$httpClient = new Http\ZendHttpClientDecorator(new ZendHttp\Client());
}
return static::$httpClient;
@@ -189,17 +197,16 @@ class Reader implements ReaderImportInterface
*/
public static function import($uri, $etag = null, $lastModified = null)
{
$cache = self::getCache();
$client = self::getHttpClient();
$client->resetParameters();
$headers = new ZendHttp\Headers();
$client->setHeaders($headers);
$client->setUri($uri);
$cache = self::getCache();
$client = self::getHttpClient();
$cacheId = 'Zend_Feed_Reader_' . md5($uri);
if (static::$httpConditionalGet && $cache) {
$data = $cache->getItem($cacheId);
if ($data) {
$headers = [];
$data = $cache->getItem($cacheId);
if ($data && $client instanceof Http\HeaderAwareClientInterface) {
// Only check for ETag and last modified values in the cache
// if we have a client capable of emitting headers in the first place.
if ($etag === null) {
$etag = $cache->getItem($cacheId . '_etag');
}
@@ -207,13 +214,13 @@ class Reader implements ReaderImportInterface
$lastModified = $cache->getItem($cacheId . '_lastmodified');
}
if ($etag) {
$headers->addHeaderLine('If-None-Match', $etag);
$headers['If-None-Match'] = [$etag];
}
if ($lastModified) {
$headers->addHeaderLine('If-Modified-Since', $lastModified);
$headers['If-Modified-Since'] = [$lastModified];
}
}
$response = $client->send();
$response = $client->get($uri, $headers);
if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 304) {
throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
}
@@ -222,11 +229,14 @@ class Reader implements ReaderImportInterface
} else {
$responseXml = $response->getBody();
$cache->setItem($cacheId, $responseXml);
if ($response->getHeaders()->get('ETag')) {
$cache->setItem($cacheId . '_etag', $response->getHeaders()->get('ETag')->getFieldValue());
}
if ($response->getHeaders()->get('Last-Modified')) {
$cache->setItem($cacheId . '_lastmodified', $response->getHeaders()->get('Last-Modified')->getFieldValue());
if ($response instanceof Http\HeaderAwareResponseInterface) {
if ($response->getHeaderLine('ETag', false)) {
$cache->setItem($cacheId . '_etag', $response->getHeaderLine('ETag'));
}
if ($response->getHeaderLine('Last-Modified', false)) {
$cache->setItem($cacheId . '_lastmodified', $response->getHeaderLine('Last-Modified'));
}
}
}
return static::importString($responseXml);
@@ -235,7 +245,7 @@ class Reader implements ReaderImportInterface
if ($data) {
return static::importString($data);
}
$response = $client->send();
$response = $client->get($uri);
if ((int) $response->getStatusCode() !== 200) {
throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
}
@@ -243,7 +253,7 @@ class Reader implements ReaderImportInterface
$cache->setItem($cacheId, $responseXml);
return static::importString($responseXml);
} else {
$response = $client->send();
$response = $client->get($uri);
if ((int) $response->getStatusCode() !== 200) {
throw new Exception\RuntimeException('Feed failed to load, got response code ' . $response->getStatusCode());
}
@@ -270,7 +280,7 @@ class Reader implements ReaderImportInterface
public static function importRemoteFeed($uri, Http\ClientInterface $client)
{
$response = $client->get($uri);
if (!$response instanceof Http\ResponseInterface) {
if (! $response instanceof Http\ResponseInterface) {
throw new Exception\RuntimeException(sprintf(
'Did not receive a %s\Http\ResponseInterface from the provided HTTP client; received "%s"',
__NAMESPACE__,
@@ -371,9 +381,8 @@ class Reader implements ReaderImportInterface
*/
public static function findFeedLinks($uri)
{
$client = static::getHttpClient();
$client->setUri($uri);
$response = $client->send();
$client = static::getHttpClient();
$response = $client->get($uri);
if ($response->getStatusCode() !== 200) {
throw new Exception\RuntimeException("Failed to access $uri, got response code " . $response->getStatusCode());
}
@@ -14,8 +14,6 @@ use Zend\Feed\Writer;
use Zend\Stdlib\StringUtils;
use Zend\Stdlib\StringWrapper\StringWrapperInterface;
/**
*/
class Feed
{
/**
@@ -12,7 +12,7 @@ namespace Zend\Feed\Writer;
/**
* Default implementation of ExtensionManagerInterface
*
* Decorator of ExtensionPluginManager.
* Decorator for an ExtensionManagerInstance.
*/
class ExtensionManager implements ExtensionManagerInterface
{
@@ -22,14 +22,14 @@ class ExtensionManager implements ExtensionManagerInterface
* Constructor
*
* Seeds the extension manager with a plugin manager; if none provided,
* creates an instance.
* creates and decorates an instance of StandaloneExtensionManager.
*
* @param null|ExtensionPluginManager $pluginManager
* @param null|ExtensionManagerInterface $pluginManager
*/
public function __construct(ExtensionPluginManager $pluginManager = null)
public function __construct(ExtensionManagerInterface $pluginManager = null)
{
if (null === $pluginManager) {
$pluginManager = new ExtensionPluginManager();
$pluginManager = new StandaloneExtensionManager();
}
$this->pluginManager = $pluginManager;
}
@@ -37,7 +37,7 @@ class ExtensionManager implements ExtensionManagerInterface
/**
* Method overloading
*
* Proxy to composed ExtensionPluginManager instance.
* Proxy to composed ExtensionManagerInterface instance.
*
* @param string $method
* @param array $args
@@ -10,6 +10,8 @@
namespace Zend\Feed\Writer;
use Zend\ServiceManager\AbstractPluginManager;
use Zend\ServiceManager\Exception\InvalidServiceException;
use Zend\ServiceManager\Factory\InvokableFactory;
/**
* Plugin manager implementation for feed writer extensions
@@ -19,41 +21,107 @@ use Zend\ServiceManager\AbstractPluginManager;
class ExtensionPluginManager extends AbstractPluginManager
{
/**
* Default set of extension classes
* Aliases for default set of extension classes
*
* @var array
*/
protected $invokableClasses = [
'atomrendererfeed' => 'Zend\Feed\Writer\Extension\Atom\Renderer\Feed',
'contentrendererentry' => 'Zend\Feed\Writer\Extension\Content\Renderer\Entry',
'dublincorerendererentry' => 'Zend\Feed\Writer\Extension\DublinCore\Renderer\Entry',
'dublincorerendererfeed' => 'Zend\Feed\Writer\Extension\DublinCore\Renderer\Feed',
'itunesentry' => 'Zend\Feed\Writer\Extension\ITunes\Entry',
'itunesfeed' => 'Zend\Feed\Writer\Extension\ITunes\Feed',
'itunesrendererentry' => 'Zend\Feed\Writer\Extension\ITunes\Renderer\Entry',
'itunesrendererfeed' => 'Zend\Feed\Writer\Extension\ITunes\Renderer\Feed',
'slashrendererentry' => 'Zend\Feed\Writer\Extension\Slash\Renderer\Entry',
'threadingrendererentry' => 'Zend\Feed\Writer\Extension\Threading\Renderer\Entry',
'wellformedwebrendererentry' => 'Zend\Feed\Writer\Extension\WellFormedWeb\Renderer\Entry',
protected $aliases = [
'atomrendererfeed' => Extension\Atom\Renderer\Feed::class,
'atomRendererFeed' => Extension\Atom\Renderer\Feed::class,
'AtomRendererFeed' => Extension\Atom\Renderer\Feed::class,
'contentrendererentry' => Extension\Content\Renderer\Entry::class,
'contentRendererEntry' => Extension\Content\Renderer\Entry::class,
'ContentRendererEntry' => Extension\Content\Renderer\Entry::class,
'dublincorerendererentry' => Extension\DublinCore\Renderer\Entry::class,
'dublinCoreRendererEntry' => Extension\DublinCore\Renderer\Entry::class,
'DublinCoreRendererEntry' => Extension\DublinCore\Renderer\Entry::class,
'dublincorerendererfeed' => Extension\DublinCore\Renderer\Feed::class,
'dublinCoreRendererFeed' => Extension\DublinCore\Renderer\Feed::class,
'DublinCoreRendererFeed' => Extension\DublinCore\Renderer\Feed::class,
'itunesentry' => Extension\ITunes\Entry::class,
'itunesEntry' => Extension\ITunes\Entry::class,
'iTunesEntry' => Extension\ITunes\Entry::class,
'ItunesEntry' => Extension\ITunes\Entry::class,
'itunesfeed' => Extension\ITunes\Feed::class,
'itunesFeed' => Extension\ITunes\Feed::class,
'iTunesFeed' => Extension\ITunes\Feed::class,
'ItunesFeed' => Extension\ITunes\Feed::class,
'itunesrendererentry' => Extension\ITunes\Renderer\Entry::class,
'itunesRendererEntry' => Extension\ITunes\Renderer\Entry::class,
'iTunesRendererEntry' => Extension\ITunes\Renderer\Entry::class,
'ItunesRendererEntry' => Extension\ITunes\Renderer\Entry::class,
'itunesrendererfeed' => Extension\ITunes\Renderer\Feed::class,
'itunesRendererFeed' => Extension\ITunes\Renderer\Feed::class,
'iTunesRendererFeed' => Extension\ITunes\Renderer\Feed::class,
'ItunesRendererFeed' => Extension\ITunes\Renderer\Feed::class,
'slashrendererentry' => Extension\Slash\Renderer\Entry::class,
'slashRendererEntry' => Extension\Slash\Renderer\Entry::class,
'SlashRendererEntry' => Extension\Slash\Renderer\Entry::class,
'threadingrendererentry' => Extension\Threading\Renderer\Entry::class,
'threadingRendererEntry' => Extension\Threading\Renderer\Entry::class,
'ThreadingRendererEntry' => Extension\Threading\Renderer\Entry::class,
'wellformedwebrendererentry' => Extension\WellFormedWeb\Renderer\Entry::class,
'wellFormedWebRendererEntry' => Extension\WellFormedWeb\Renderer\Entry::class,
'WellFormedWebRendererEntry' => Extension\WellFormedWeb\Renderer\Entry::class,
];
/**
* Do not share instances
* Factories for default set of extension classes
*
* @var array
*/
protected $factories = [
Extension\Atom\Renderer\Feed::class => InvokableFactory::class,
Extension\Content\Renderer\Entry::class => InvokableFactory::class,
Extension\DublinCore\Renderer\Entry::class => InvokableFactory::class,
Extension\DublinCore\Renderer\Feed::class => InvokableFactory::class,
Extension\ITunes\Entry::class => InvokableFactory::class,
Extension\ITunes\Feed::class => InvokableFactory::class,
Extension\ITunes\Renderer\Entry::class => InvokableFactory::class,
Extension\ITunes\Renderer\Feed::class => InvokableFactory::class,
Extension\Slash\Renderer\Entry::class => InvokableFactory::class,
Extension\Threading\Renderer\Entry::class => InvokableFactory::class,
Extension\WellFormedWeb\Renderer\Entry::class => InvokableFactory::class,
// Legacy (v2) due to alias resolution; canonical form of resolved
// alias is used to look up the factory, while the non-normalized
// resolved alias is used as the requested name passed to the factory.
'zendfeedwriterextensionatomrendererfeed' => InvokableFactory::class,
'zendfeedwriterextensioncontentrendererentry' => InvokableFactory::class,
'zendfeedwriterextensiondublincorerendererentry' => InvokableFactory::class,
'zendfeedwriterextensiondublincorerendererfeed' => InvokableFactory::class,
'zendfeedwriterextensionitunesentry' => InvokableFactory::class,
'zendfeedwriterextensionitunesfeed' => InvokableFactory::class,
'zendfeedwriterextensionitunesrendererentry' => InvokableFactory::class,
'zendfeedwriterextensionitunesrendererfeed' => InvokableFactory::class,
'zendfeedwriterextensionslashrendererentry' => InvokableFactory::class,
'zendfeedwriterextensionthreadingrendererentry' => InvokableFactory::class,
'zendfeedwriterextensionwellformedwebrendererentry' => InvokableFactory::class,
];
/**
* Do not share instances (v2)
*
* @var bool
*/
protected $shareByDefault = false;
/**
* Validate the plugin
* Do not share instances (v3)
*
* @var bool
*/
protected $sharedByDefault = false;
/**
* Validate the plugin (v3)
*
* Checks that the extension loaded is of a valid type.
*
* @param mixed $plugin
* @return void
* @throws Exception\InvalidArgumentException if invalid
* @throws InvalidServiceException if invalid
*/
public function validatePlugin($plugin)
public function validate($plugin)
{
if ($plugin instanceof Extension\AbstractRenderer) {
// we're okay
@@ -70,11 +138,32 @@ class ExtensionPluginManager extends AbstractPluginManager
return;
}
throw new Exception\InvalidArgumentException(sprintf(
throw new InvalidServiceException(sprintf(
'Plugin of type %s is invalid; must implement %s\Extension\RendererInterface '
. 'or the classname must end in "Feed" or "Entry"',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__
));
}
/**
* Validate plugin (v2)
*
* @param mixed $plugin
* @return void
* @throws Exception\InvalidArgumentException when invalid
*/
public function validatePlugin($plugin)
{
try {
$this->validate($plugin);
} catch (InvalidServiceException $e) {
throw new Exception\InvalidArgumentException(sprintf(
'Plugin of type %s is invalid; must implement %s\Extension\RendererInterface '
. 'or the classname must end in "Feed" or "Entry"',
(is_object($plugin) ? get_class($plugin) : gettype($plugin)),
__NAMESPACE__
));
}
}
}
@@ -0,0 +1,50 @@
<?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 Zend\Feed\Writer;
class StandaloneExtensionManager implements ExtensionManagerInterface
{
private $extensions = [
'Atom\Renderer\Feed' => Extension\Atom\Renderer\Feed::class,
'Content\Renderer\Entry' => Extension\Content\Renderer\Entry::class,
'DublinCore\Renderer\Entry' => Extension\DublinCore\Renderer\Entry::class,
'DublinCore\Renderer\Feed' => Extension\DublinCore\Renderer\Feed::class,
'ITunes\Entry' => Extension\ITunes\Entry::class,
'ITunes\Feed' => Extension\ITunes\Feed::class,
'ITunes\Renderer\Entry' => Extension\ITunes\Renderer\Entry::class,
'ITunes\Renderer\Feed' => Extension\ITunes\Renderer\Feed::class,
'Slash\Renderer\Entry' => Extension\Slash\Renderer\Entry::class,
'Threading\Renderer\Entry' => Extension\Threading\Renderer\Entry::class,
'WellFormedWeb\Renderer\Entry' => Extension\WellFormedWeb\Renderer\Entry::class,
];
/**
* Do we have the extension?
*
* @param string $extension
* @return bool
*/
public function has($extension)
{
return array_key_exists($extension, $this->extensions);
}
/**
* Retrieve the extension
*
* @param string $extension
* @return mixed
*/
public function get($extension)
{
$class = $this->extensions[$extension];
return new $class();
}
}
+9 -6
View File
@@ -105,13 +105,16 @@ class Writer
return;
}
}
if (!$manager->has($feedName)
&& !$manager->has($entryName)
&& !$manager->has($feedRendererName)
&& !$manager->has($entryRendererName)
if (! $manager->has($feedName)
&& ! $manager->has($entryName)
&& ! $manager->has($feedRendererName)
&& ! $manager->has($entryRendererName)
) {
throw new Exception\RuntimeException('Could not load extension: ' . $name
. 'using Plugin Loader. Check prefix paths are configured and extension exists.');
throw new Exception\RuntimeException(sprintf(
'Could not load extension "%s" using Plugin Loader. '
. 'Check prefix paths are configured and extension exists.',
$name
));
}
if ($manager->has($feedName)) {
static::$extensions['feed'][] = $feedName;