diff options
author | Bernhard Posselt <dev@bernhard-posselt.com> | 2014-12-17 09:01:54 +0100 |
---|---|---|
committer | Bernhard Posselt <dev@bernhard-posselt.com> | 2014-12-17 09:02:13 +0100 |
commit | 867cb7dbf960dc0cfbf7e59d656d1337bb59c526 (patch) | |
tree | 5bbdf1eef51cd3747f55ef2c524364f9cd3bf029 /vendor/fguillot | |
parent | a813b535eeb517e0ccd69a90d0058756014a1e01 (diff) |
update picofeed, fix #695
Diffstat (limited to 'vendor/fguillot')
32 files changed, 2326 insertions, 300 deletions
diff --git a/vendor/fguillot/picofeed/README.markdown b/vendor/fguillot/picofeed/README.markdown index 868d532e9..a1e1e39c5 100644 --- a/vendor/fguillot/picofeed/README.markdown +++ b/vendor/fguillot/picofeed/README.markdown @@ -59,6 +59,7 @@ Documentation - [Favicon fetcher](docs/favicon.markdown) - [OPML file importation](docs/opml-import.markdown) - [OPML file exportation](docs/opml-export.markdown) +- [Image proxy](docs/image-proxy.markdown) (avoid SSL mixed content warnings) - [Web scraping](docs/grabber.markdown) - [Exceptions](docs/exceptions.markdown) - [Debugging](docs/debugging.markdown) diff --git a/vendor/fguillot/picofeed/docs/config.markdown b/vendor/fguillot/picofeed/docs/config.markdown index 5e0dfea53..75546abd1 100644 --- a/vendor/fguillot/picofeed/docs/config.markdown +++ b/vendor/fguillot/picofeed/docs/config.markdown @@ -261,3 +261,26 @@ $config->setFilterSchemeWhitelist(['http://', 'ftp://']); ```php $config->setFilterWhitelistedTags(['a' => ['href'], 'img' => ['src', 'title']]); ``` + +### Define a image proxy url + +- Method name: `setFilterImageProxyUrl()` +- Default value: Empty +- Argument value: string + +```php +$config->setFilterImageProxyUrl('http://myproxy.example.org/?url=%s'); +``` + +### Define a image proxy callback + +- Method name: `setFilterImageProxyCallback()` +- Default value: null +- Argument value: Closure + +```php +$config->setFilterImageProxyCallback(function ($image_url) { + $key = hash_hmac('sha1', $image_url, 'secret'); + return 'https://mypublicproxy/'.$key.'/'.urlencode($image_url); +}); +```
\ No newline at end of file diff --git a/vendor/fguillot/picofeed/docs/favicon.markdown b/vendor/fguillot/picofeed/docs/favicon.markdown index 14e25955d..1ac3ee1fc 100644 --- a/vendor/fguillot/picofeed/docs/favicon.markdown +++ b/vendor/fguillot/picofeed/docs/favicon.markdown @@ -5,7 +5,7 @@ Find and download the favicon ----------------------------- ```php -use PicoFeed\Client\Favicon; +use PicoFeed\Reader\Favicon; $favicon = new Favicon; @@ -21,11 +21,42 @@ PicoFeed will try first to find the favicon from the meta tags and fallback to t When the HTML page is parsed, relative links and protocol relative links are converted to absolute url. +Get Favicon file type +--------------------- + +It's possible to fetch the image type, this information come from the Content-Type HTTP header: + +```php +$favicon = new Favicon; +$favicon->find('http://example.net/'); + +echo $favicon->getType(); + +// Will output the content type, by example "image/png" +``` + +Get the Favicon as Data URI +--------------------------- + +You can also get the whole image as Data URI. +It's useful if you want to store the icon in your database and avoid too many HTTP requests. + +```php +$favicon = new Favicon; +$favicon->find('http://example.net/'); + +echo $favicon->getDataUri(); + +// Output something like that: data:image/png;base64,iVBORw0KGgoAAAANSUh..... +``` + +See: http://en.wikipedia.org/wiki/Data_URI_scheme + Check if a favicon link exists ------------------------------ ```php -use PicoFeed\Client\Favicon; +use PicoFeed\Reader\Favicon; $favicon = new Favicon; @@ -40,7 +71,7 @@ Like other classes, the Favicon class support the Config object as constructor a ```php use PicoFeed\Config\Config; -use PicoFeed\Client\Favicon; +use PicoFeed\Reader\Favicon; $config = new Config; $config->setClientUserAgent('My RSS Reader'); diff --git a/vendor/fguillot/picofeed/docs/feed-parsing.markdown b/vendor/fguillot/picofeed/docs/feed-parsing.markdown index df881400e..82d3703e9 100644 --- a/vendor/fguillot/picofeed/docs/feed-parsing.markdown +++ b/vendor/fguillot/picofeed/docs/feed-parsing.markdown @@ -43,7 +43,8 @@ Output: ```bash Feed::id = tag:linuxfr.org,2005:/news Feed::title = LinuxFr.org : les dĂ©pĂȘches -Feed::url = http://linuxfr.org/news +Feed::feed_url = http://linuxfr.org/news.atom +Feed::site_url = http://linuxfr.org/news Feed::date = 1415138079 Feed::language = en-US Feed::description = @@ -58,6 +59,7 @@ Item::language = en-US Item::author = Syvolc Item::enclosure_url = Item::enclosure_type = +Item::isRTL() = false Item::content = 18307 bytes .... ``` @@ -181,7 +183,8 @@ Feed and item properties // Feed object $feed->getId(); // Unique feed id $feed->getTitle(); // Feed title -$feed->getUrl(); // Website url +$feed->getFeedUrl(); // Feed url +$feed->getSiteUrl(); // Website url $feed->getDate(); // Feed last updated date $feed->getLanguage(); // Feed language $feed->getDescription(); // Feed description @@ -198,16 +201,16 @@ $feed->items[0]->getAuthor(); // Item author $feed->items[0]->getEnclosureUrl(); // Enclosure url $feed->items[0]->getEnclosureType(); // Enclosure mime-type (audio/mp3, image/png...) $feed->items[0]->getContent(); // Item content (filtered or raw) +$feed->items[0]->isRTL(); // Return true if the item language is Right-To-Left ``` RTL language detection ---------------------- -There is an utility method to determine if a language code is Right-To-Left or not: +Use the method `Item::isRTL()` to test if an item is RTL or not: ```php -// Return true if RTL -Parser::isLanguageRTL($item->getLanguage()); +var_dump($item->isRTL()); // true or false ``` Known RTL languages are: diff --git a/vendor/fguillot/picofeed/docs/image-proxy.markdown b/vendor/fguillot/picofeed/docs/image-proxy.markdown new file mode 100644 index 000000000..74e10d0c6 --- /dev/null +++ b/vendor/fguillot/picofeed/docs/image-proxy.markdown @@ -0,0 +1,66 @@ +Image Proxy +=========== + +To prevent mixed content warnings on SSL pages served from your RSS reader you might want to use an assets proxy. + +Images url will be rewritten to be downloaded through the proxy. + +Example: + +```html +<img src="http://example.org/image.png"/> +``` + +Can be rewritten like that: + +```html +<img src="http://myproxy.example.org/?url=http%3A%2F%2Fexample.org%2Fimage.png"/> +``` + +Currently this feature is only compatible with images. + +There is several open source SSL image proxy available like [Camo](https://github.com/atmos/camo). +You can also write your own proxy. + +Usage +----- + +There two different ways to use this feature, define a proxy url or a callback. + +### Define a proxy url + +A proxy url must be defined with a placeholder `%s`. +The placeholder will be replaced by the image source urlencoded. + +```php +$config = new Config; +$config->setFilterImageProxyUrl('http://myproxy.example.org/?url=%s'); +``` + +Will rewrite the image source like that: + +```html +<img src="http://myproxy.example.org/?url=http%3A%2F%2Fexample.org%2Fimage.png"/> +``` + +### Define a callback + +Your callback will be called each time an image url need to be rewritten. +The first argument is the original image url and your function must returns the new image url. + +Here an example if your proxy need a shared secret key: + +```php +$config = new Config; + +$config->setFilterImageProxyCallback(function ($image_url) { + $key = hash_hmac('sha1', $image_url, 'secret'); + return 'https://mypublicproxy/'.$key.'/'.urlencode($image_url); +}); +``` + +Will generate an image url like that: + +```html +<img src="https://mypublicproxy/4924964043f3119b3cf2b07b1922d491bcc20092/http%3A%2F%2Ffoo%2Fimage.png"/> +``` diff --git a/vendor/fguillot/picofeed/example.php b/vendor/fguillot/picofeed/example.php deleted file mode 100644 index 6bf9b6e20..000000000 --- a/vendor/fguillot/picofeed/example.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -require 'vendor/autoload.php'; - -use PicoFeed\Reader\Reader; -use PicoFeed\PicoFeedException; - -try { - - // Fetch from your database the previous values of the Etag and LastModified headers - $etag = '...'; - $last_modified = '...'; - - $reader = new Reader; - - // Provide those values to the download method - $resource = $reader->download('http://linuxfr.org/news.atom', $last_modified, $etag); - - if ($resource->isModified()) { - - $parser = $reader->getParser( - $resource->getUrl(), - $resource->getContent(), - $resource->getEncoding() - ); - - $feed = $parser->execute(); - - // Save your feed in your database - // ... - - // Store the Etag and the LastModified headers in your database - $etag = $resource->getEtag(); - $last_modified = $resource->getLastModified(); - - // ... - } - else { - - echo 'Not modified, nothing to do!'; - } -} -catch (PicoFeedException $e) { - // Do something... -} diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php index e962ba4e8..c8c812c1a 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Client.php @@ -22,6 +22,14 @@ abstract class Client private $is_modified = true; /** + * HTTP Content-Type + * + * @access private + * @var string + */ + private $content_type = ''; + + /** * HTTP encoding * * @access private @@ -231,7 +239,8 @@ abstract class Client { if ($response['status'] == 200) { $this->content = $response['body']; - $this->encoding = $this->findCharset($response); + $this->content_type = $this->findContentType($response); + $this->encoding = $this->findCharset(); } } @@ -249,14 +258,26 @@ abstract class Client } /** - * Find charset from response headers + * Find content type from response headers * * @access public * @param array $response Client response + * @return string */ - public function findCharset(array $response) + public function findContentType(array $response) { - $result = explode('charset=', strtolower($this->getHeader($response, 'Content-Type'))); + return strtolower($this->getHeader($response, 'Content-Type')); + } + + /** + * Find charset from response headers + * + * @access public + * @return string + */ + public function findCharset() + { + $result = explode('charset=', $this->content_type); return isset($result[1]) ? $result[1] : ''; } @@ -390,6 +411,17 @@ abstract class Client } /** + * Get the content type value from HTTP headers + * + * @access public + * @return string + */ + public function getContentType() + { + return $this->content_type; + } + + /** * Get the encoding value from HTTP headers * * @access public diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Url.php b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Url.php index 90d7fb6f7..a74c23508 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Client/Url.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Client/Url.php @@ -80,6 +80,20 @@ class Url } /** + * Shortcut method to get a base url + * + * @static + * @access public + * @param string $url + * @return string + */ + public static function base($url) + { + $link = new Url($url); + return $link->getBaseUrl(); + } + + /** * Get the base URL * * @access public diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php b/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php index 298b9a2d7..9a5381f0f 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Config/Config.php @@ -30,6 +30,8 @@ namespace PicoFeed\Config; * @method \PicoFeed\Config\Config setFilterSchemeWhitelist(array $value) * @method \PicoFeed\Config\Config setFilterWhitelistedTags(array $value) * @method \PicoFeed\Config\Config setFilterBlacklistedTags(array $value) + * @method \PicoFeed\Config\Config setFilterImageProxyUrl($value) + * @method \PicoFeed\Config\Config setFilterImageProxyCallback($closure) * * @method integer getClientTimeout() * @method string getClientUserAgent() @@ -53,6 +55,8 @@ namespace PicoFeed\Config; * @method array getFilterSchemeWhitelist(array $default_value) * @method array getFilterWhitelistedTags(array $default_value) * @method array getFilterBlacklistedTags(array $default_value) + * @method string getFilterImageProxyUrl($default_value) + * @method string getFilterImageProxyCallback($default_value) */ class Config { diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php index 23b1103ad..66b3470f8 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Attribute.php @@ -13,6 +13,22 @@ use \PicoFeed\Client\Url; class Attribute { /** + * Image proxy url + * + * @access private + * @var string + */ + private $image_proxy_url = ''; + + /** + * Image proxy callback + * + * @access private + * @var \Closure|null + */ + private $image_proxy_callback = null; + + /** * Tags and attribute whitelist * * @access private @@ -204,10 +220,11 @@ class Attribute 'filterEmptyAttribute', 'filterAllowedAttribute', 'filterIntegerAttribute', - 'filterAbsoluteUrlAttribute', + 'rewriteAbsoluteUrl', 'filterIframeAttribute', 'filterBlacklistResourceAttribute', 'filterProtocolUrlAttribute', + 'rewriteImageProxyUrl', ); /** @@ -349,7 +366,7 @@ class Attribute * @param string $value Atttribute value * @return boolean */ - public function filterAbsoluteUrlAttribute($tag, $attribute, &$value) + public function rewriteAbsoluteUrl($tag, $attribute, &$value) { if ($this->isResource($attribute)) { $value = Url::resolve($value, $this->website); @@ -359,6 +376,30 @@ class Attribute } /** + * Rewrite image url to use with a proxy + * + * @access public + * @param string $tag Tag name + * @param string $attribute Atttribute name + * @param string $value Atttribute value + * @return boolean + */ + public function rewriteImageProxyUrl($tag, $attribute, &$value) + { + if ($tag === 'img' && $attribute === 'src') { + + if ($this->image_proxy_url) { + $value = sprintf($this->image_proxy_url, urlencode($value)); + } + else if (is_callable($this->image_proxy_callback)) { + $value = call_user_func($this->image_proxy_callback, $value); + } + } + + return true; + } + + /** * Return true if the scheme is authorized * * @access public @@ -484,7 +525,7 @@ class Attribute } /** - * Set whitelisted tags adn attributes for each tag + * Set whitelisted tags and attributes for each tag * * @access public * @param array $values List of tags: ['video' => ['src', 'cover'], 'img' => ['src']] @@ -586,4 +627,32 @@ class Attribute $this->iframe_whitelist = $values ?: $this->iframe_whitelist; return $this; } + + /** + * Set image proxy URL + * + * The original image url will be urlencoded + * + * @access public + * @param string $url Proxy URL + * @return \PicoFeed\Filter\Filter + */ + public function setImageProxyUrl($url) + { + $this->image_proxy_url = $url ?: $this->image_proxy_url; + return $this; + } + + /** + * Set image proxy callback + * + * @access public + * @param \Closure $callback + * @return \PicoFeed\Filter\Filter + */ + public function setImageProxyCallback($callback) + { + $this->image_proxy_callback = $callback ?: $this->image_proxy_callback; + return $this; + } } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php index 0490e2f49..82289444b 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Filter.php @@ -2,6 +2,8 @@ namespace PicoFeed\Filter; +use PicoFeed\Parser\XmlParser; + /** * Filter class * @@ -137,34 +139,4 @@ class Filter return $data; } - - /** - * Get the first XML tag - * - * @static - * @access public - * @param string $data Feed content - * @return string - */ - public static function getFirstTag($data) - { - // Strip HTML comments (max of 5,000 characters long to prevent crashing) - $data = preg_replace('/<!--(.{0,5000}?)-->/Uis', '', $data); - - /* Strip Doctype: - * Doctype needs to be within the first 100 characters. (Ideally the first!) - * If it's not found by then, we need to stop looking to prevent PREG - * from reaching max backtrack depth and crashing. - */ - $data = preg_replace('/^.{0,100}<!DOCTYPE([^>]*)>/Uis', '', $data); - - // Strip <?xml version.... - $data = self::stripXmlTag($data); - - // Find the first tag - $open_tag = strpos($data, '<'); - $close_tag = strpos($data, '>'); - - return substr($data, $open_tag, $close_tag); - } } diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php index d14d80907..f7816f1d2 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Filter/Html.php @@ -96,6 +96,8 @@ class Html $this->config = $config; if ($this->config !== null) { + $this->attribute->setImageProxyCallback($this->config->getFilterImageProxyCallback()); + $this->attribute->setImageProxyUrl($this->config->getFilterImageProxyUrl()); $this->attribute->setIframeWhitelist($this->config->getFilterIframeWhitelist(array())); $this->attribute->setIntegerAttributes($this->config->getFilterIntegerAttributes(array())); $this->attribute->setAttributeOverrides($this->config->getFilterAttributeOverrides(array())); diff --git a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php index 1217bc4b0..5bb930b22 100644 --- a/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php +++ b/vendor/fguillot/picofeed/lib/PicoFeed/Parser/Atom.php @@ -30,19 +30,31 @@ class Atom extends Parser * Find the feed url * * @access public - * @param SimpleXMLElement $xml Feed xml + * @param SimpleXMLElement $xml Feed xml * @param \PicoFeed\Parser\Feed $feed Feed object */ public function findFeedUrl(SimpleXMLElement $xml, Feed $feed) { - $feed->url = $this->getLink($xml); + $feed->feed_url = $this->getUrl($xml, 'self'); + } + + /** + * Find the site url + * + * @access public + * @param SimpleXMLElement $xml Feed xml + * @param \PicoFeed\Parser\Feed $feed Feed object + */ + public function findSiteUrl(SimpleXMLElement $xml, Feed $feed) + { + $feed->site_url = $this->getUrl($xml, 'alternate', true); } /** * Find the feed description * * @access public - * @param SimpleXMLElement $xml Feed xml + * @param SimpleXMLElement $xml Feed xml * @param \PicoFeed\Parser\Feed $feed Feed object */ public function findFeedDescription(SimpleXMLElement $xml, Feed $feed) @@ -54,7 +66,7 @@ class Atom extends Parser * Find the feed logo url * * @access public - * @param SimpleXMLElement $xml Feed xml + * @param SimpleXMLElement $xml Feed xml * @param \PicoFeed\Parser\Feed $feed Feed object */ public function findFeedLogo(SimpleXMLElement $xml, Feed $feed) |