aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--caches/FileCache.php153
-rw-r--r--formats/AtomFormat.php113
-rw-r--r--formats/HtmlFormat.php85
-rw-r--r--formats/JsonFormat.php23
-rw-r--r--formats/MrssFormat.php106
-rw-r--r--formats/PlaintextFormat.php24
-rw-r--r--lib/Bridge.php194
-rw-r--r--lib/BridgeAbstract.php881
-rw-r--r--lib/BridgeInterface.php8
-rw-r--r--lib/Cache.php134
-rw-r--r--lib/CacheAbstract.php12
-rw-r--r--lib/CacheInterface.php8
-rw-r--r--lib/Exceptions.php97
-rw-r--r--lib/FeedExpander.php345
-rw-r--r--lib/Format.php103
-rw-r--r--lib/FormatAbstract.php208
-rw-r--r--lib/FormatInterface.php6
-rw-r--r--lib/HTMLUtils.php228
-rw-r--r--lib/RssBridge.php43
19 files changed, 1443 insertions, 1328 deletions
diff --git a/caches/FileCache.php b/caches/FileCache.php
index b6e04c37..a8ab88d7 100644
--- a/caches/FileCache.php
+++ b/caches/FileCache.php
@@ -2,93 +2,88 @@
/**
* Cache with file system
*/
-class FileCache extends CacheAbstract{
- protected $cacheDirCreated; // boolean to avoid always chck dir cache existance
+class FileCache extends CacheAbstract {
+ protected $cacheDirCreated; // boolean to avoid always chck dir cache existance
- public function loadData(){
- $this->isPrepareCache();
+ public function loadData(){
+ $this->isPrepareCache();
+ $datas = unserialize(file_get_contents($this->getCacheFile()));
+ return $datas;
+ }
- $datas = unserialize(file_get_contents($this->getCacheFile()));
+ public function saveData($datas){
+ $this->isPrepareCache();
- return $datas;
- }
+ //Re-encode datas to UTF-8
+ //$datas = Cache::utf8_encode_deep($datas);
+ $writeStream = file_put_contents($this->getCacheFile(), serialize($datas));
- public function saveData($datas){
- $this->isPrepareCache();
+ if(!$writeStream) {
+ throw new \Exception("Cannot write the cache... Do you have the right permissions ?");
+ }
- //Re-encode datas to UTF-8
- //$datas = Cache::utf8_encode_deep($datas);
-
- $writeStream = file_put_contents($this->getCacheFile(), serialize($datas));
+ return $this;
+ }
- if(!$writeStream) {
+ public function getTime(){
+ $this->isPrepareCache();
- throw new \Exception("Cannot write the cache... Do you have the right permissions ?");
+ $cacheFile = $this->getCacheFile();
+ if(file_exists($cacheFile)){
+ return filemtime($cacheFile);
+ }
+
+ return false;
+ }
+
+ /**
+ * Cache is prepared ?
+ * Note : Cache name is based on request information, then cache must be prepare before use
+ * @return \Exception|true
+ */
+ protected function isPrepareCache(){
+ if(is_null($this->param)){
+ throw new \Exception('Please feed "prepare" method before try to load');
+ }
+
+ return true;
+ }
+
+ /**
+ * Return cache path (and create if not exist)
+ * @return string Cache path
+ */
+ protected function getCachePath(){
+ $cacheDir = __DIR__ . '/../cache/'; // FIXME : configuration ?
+
+ // FIXME : implement recursive dir creation
+ if(is_null($this->cacheDirCreated) && !is_dir($cacheDir)){
+ $this->cacheDirCreated = true;
+ mkdir($cacheDir,0705);
+ chmod($cacheDir,0705);
}
- return $this;
- }
-
- public function getTime(){
- $this->isPrepareCache();
-
- $cacheFile = $this->getCacheFile();
- if( file_exists($cacheFile) ){
- return filemtime($cacheFile);
- }
-
- return false;
- }
-
- /**
- * Cache is prepared ?
- * Note : Cache name is based on request information, then cache must be prepare before use
- * @return \Exception|true
- */
- protected function isPrepareCache(){
- if( is_null($this->param) ){
- throw new \Exception('Please feed "prepare" method before try to load');
- }
-
- return true;
- }
-
- /**
- * Return cache path (and create if not exist)
- * @return string Cache path
- */
- protected function getCachePath(){
- $cacheDir = __DIR__ . '/../cache/'; // FIXME : configuration ?
-
- // FIXME : implement recursive dir creation
- if( is_null($this->cacheDirCreated) && !is_dir($cacheDir) ){
- $this->cacheDirCreated = true;
-
- mkdir($cacheDir,0705);
- chmod($cacheDir,0705);
- }
-
- return $cacheDir;
- }
-
- /**
- * Get the file name use for cache store
- * @return string Path to the file cache
- */
- protected function getCacheFile(){
- return $this->getCachePath() . $this->getCacheName();
- }
-
- /**
- * Determines file name for store the cache
- * return string
- */
- protected function getCacheName(){
- $this->isPrepareCache();
-
- $stringToEncode = $_SERVER['REQUEST_URI'] . http_build_query($this->param);
- $stringToEncode = preg_replace('/(\?|&)format=[^&]*/i', '$1', $stringToEncode);
- return hash('sha1', $stringToEncode) . '.cache';
- }
+ return $cacheDir;
+ }
+
+ /**
+ * Get the file name use for cache store
+ * @return string Path to the file cache
+ */
+ protected function getCacheFile(){
+ return $this->getCachePath() . $this->getCacheName();
+ }
+
+ /**
+ * Determines file name for store the cache
+ * return string
+ */
+ protected function getCacheName(){
+ $this->isPrepareCache();
+
+ $stringToEncode = $_SERVER['REQUEST_URI'] . http_build_query($this->param);
+ $stringToEncode = preg_replace('/(\?|&)format=[^&]*/i', '$1', $stringToEncode);
+ return hash('sha1', $stringToEncode) . '.cache';
+ }
}
diff --git a/formats/AtomFormat.php b/formats/AtomFormat.php
index 238dc884..fd2016bc 100644
--- a/formats/AtomFormat.php
+++ b/formats/AtomFormat.php
@@ -1,79 +1,80 @@
<?php
/**
* Atom
-* Documentation Source http://en.wikipedia.org/wiki/Atom_%28standard%29 and http://tools.ietf.org/html/rfc4287
+* Documentation Source http://en.wikipedia.org/wiki/Atom_%28standard%29 and
+* http://tools.ietf.org/html/rfc4287
*/
class AtomFormat extends FormatAbstract{
- public function stringify(){
- $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '';
- $httpHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
- $httpInfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
+ public function stringify(){
+ $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '';
+ $httpHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
+ $httpInfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
- $serverRequestUri = $this->xml_encode($_SERVER['REQUEST_URI']);
+ $serverRequestUri = $this->xml_encode($_SERVER['REQUEST_URI']);
- $extraInfos = $this->getExtraInfos();
- $title = $this->xml_encode($extraInfos['name']);
- $uri = !empty($extraInfos['uri']) ? $extraInfos['uri'] : 'https://github.com/sebsauvage/rss-bridge';
- $icon = $this->xml_encode('http://icons.better-idea.org/icon?url='. $uri .'&size=64');
- $uri = $this->xml_encode($uri);
+ $extraInfos = $this->getExtraInfos();
+ $title = $this->xml_encode($extraInfos['name']);
+ $uri = !empty($extraInfos['uri']) ? $extraInfos['uri'] : 'https://github.com/sebsauvage/rss-bridge';
+ $icon = $this->xml_encode('http://icons.better-idea.org/icon?url='. $uri .'&size=64');
+ $uri = $this->xml_encode($uri);
- $entries = '';
- foreach($this->getItems() as $item){
- $entryAuthor = isset($item['author']) ? $this->xml_encode($item['author']) : '';
- $entryTitle = isset($item['title']) ? $this->xml_encode($item['title']) : '';
- $entryUri = isset($item['uri']) ? $this->xml_encode($item['uri']) : '';
- $entryTimestamp = isset($item['timestamp']) ? $this->xml_encode(date(DATE_ATOM, $item['timestamp'])) : '';
- $entryContent = isset($item['content']) ? $this->xml_encode($this->sanitizeHtml($item['content'])) : '';
- $entries .= <<<EOD
+ $entries = '';
+ foreach($this->getItems() as $item){
+ $entryAuthor = isset($item['author']) ? $this->xml_encode($item['author']) : '';
+ $entryTitle = isset($item['title']) ? $this->xml_encode($item['title']) : '';
+ $entryUri = isset($item['uri']) ? $this->xml_encode($item['uri']) : '';
+ $entryTimestamp = isset($item['timestamp']) ? $this->xml_encode(date(DATE_ATOM, $item['timestamp'])) : '';
+ $entryContent = isset($item['content']) ? $this->xml_encode($this->sanitizeHtml($item['content'])) : '';
+ $entries .= <<<EOD
- <entry>
- <author>
- <name>{$entryAuthor}</name>
- </author>
- <title type="html"><![CDATA[{$entryTitle}]]></title>
- <link rel="alternate" type="text/html" href="{$entryUri}" />
- <id>{$entryUri}</id>
- <updated>{$entryTimestamp}</updated>
- <content type="html">{$entryContent}</content>
- </entry>
+ <entry>
+ <author>
+ <name>{$entryAuthor}</name>
+ </author>
+ <title type="html"><![CDATA[{$entryTitle}]]></title>
+ <link rel="alternate" type="text/html" href="{$entryUri}" />
+ <id>{$entryUri}</id>
+ <updated>{$entryTimestamp}</updated>
+ <content type="html">{$entryContent}</content>
+ </entry>
EOD;
- }
+ }
- $feedTimestamp = date(DATE_ATOM, time());
+ $feedTimestamp = date(DATE_ATOM, time());
- /* Data are prepared, now let's begin the "MAGIE !!!" */
- $toReturn = '<?xml version="1.0" encoding="UTF-8"?>';
- $toReturn .= <<<EOD
+ /* Data are prepared, now let's begin the "MAGIE !!!" */
+ $toReturn = '<?xml version="1.0" encoding="UTF-8"?>';
+ $toReturn .= <<<EOD
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en-US">
- <title type="text">{$title}</title>
- <id>http{$https}://{$httpHost}{$httpInfo}/</id>
- <icon>{$icon}</icon>
- <logo>{$icon}</logo>
- <updated>{$feedTimestamp}</updated>
- <link rel="alternate" type="text/html" href="{$uri}" />
- <link rel="self" href="http{$https}://{$httpHost}{$serverRequestUri}" />
+ <title type="text">{$title}</title>
+ <id>http{$https}://{$httpHost}{$httpInfo}/</id>
+ <icon>{$icon}</icon>
+ <logo>{$icon}</logo>
+ <updated>{$feedTimestamp}</updated>
+ <link rel="alternate" type="text/html" href="{$uri}" />
+ <link rel="self" href="http{$https}://{$httpHost}{$serverRequestUri}" />
{$entries}
</feed>
EOD;
-
- // Remove invalid non-UTF8 characters
- ini_set('mbstring.substitute_character', 'none');
- $toReturn= mb_convert_encoding($toReturn, 'UTF-8', 'UTF-8');
- return $toReturn;
- }
- public function display(){
- $this
- ->setContentType('application/atom+xml; charset=UTF-8')
- ->callContentType();
+ // Remove invalid non-UTF8 characters
+ ini_set('mbstring.substitute_character', 'none');
+ $toReturn = mb_convert_encoding($toReturn, 'UTF-8', 'UTF-8');
+ return $toReturn;
+ }
- return parent::display();
- }
+ public function display(){
+ $this
+ ->setContentType('application/atom+xml; charset=UTF-8')
+ ->callContentType();
- private function xml_encode($text) {
- return htmlspecialchars($text, ENT_XML1);
- }
+ return parent::display();
+ }
+
+ private function xml_encode($text){
+ return htmlspecialchars($text, ENT_XML1);
+ }
}
diff --git a/formats/HtmlFormat.php b/formats/HtmlFormat.php
index d7c927b0..1001acfc 100644
--- a/formats/HtmlFormat.php
+++ b/formats/HtmlFormat.php
@@ -1,63 +1,62 @@
<?php
-class HtmlFormat extends FormatAbstract{
-
- public function stringify(){
- $extraInfos = $this->getExtraInfos();
- $title = htmlspecialchars($extraInfos['name']);
- $uri = htmlspecialchars($extraInfos['uri']);
- $atomquery = str_replace('format=Html', 'format=Atom', htmlentities($_SERVER['QUERY_STRING']));
- $mrssquery = str_replace('format=Html', 'format=Mrss', htmlentities($_SERVER['QUERY_STRING']));
-
- $entries = '';
- foreach($this->getItems() as $item){
- $entryAuthor = isset($item['author']) ? '<br /><p class="author">by: ' . $item['author'] . '</p>' : '';
- $entryTitle = isset($item['title']) ? $this->sanitizeHtml(strip_tags($item['title'])) : '';
- $entryUri = isset($item['uri']) ? $item['uri'] : $uri;
- $entryTimestamp = isset($item['timestamp']) ? '<time datetime="' . date(DATE_ATOM, $item['timestamp']) . '">' . date(DATE_ATOM, $item['timestamp']) . '</time>' : '';
- $entryContent = isset($item['content']) ? '<div class="content">' . $this->sanitizeHtml($item['content']). '</div>' : '';
- $entries .= <<<EOD
+class HtmlFormat extends FormatAbstract {
+
+ public function stringify(){
+ $extraInfos = $this->getExtraInfos();
+ $title = htmlspecialchars($extraInfos['name']);
+ $uri = htmlspecialchars($extraInfos['uri']);
+ $atomquery = str_replace('format=Html', 'format=Atom', htmlentities($_SERVER['QUERY_STRING']));
+ $mrssquery = str_replace('format=Html', 'format=Mrss', htmlentities($_SERVER['QUERY_STRING']));
+
+ $entries = '';
+ foreach($this->getItems() as $item){
+ $entryAuthor = isset($item['author']) ? '<br /><p class="author">by: ' . $item['author'] . '</p>' : '';
+ $entryTitle = isset($item['title']) ? $this->sanitizeHtml(strip_tags($item['title'])) : '';
+ $entryUri = isset($item['uri']) ? $item['uri'] : $uri;
+ $entryTimestamp = isset($item['timestamp']) ? '<time datetime="' . date(DATE_ATOM, $item['timestamp']) . '">' . date(DATE_ATOM, $item['timestamp']) . '</time>' : '';
+ $entryContent = isset($item['content']) ? '<div class="content">' . $this->sanitizeHtml($item['content']). '</div>' : '';
+ $entries .= <<<EOD
<section class="feeditem">
- <h2><a class="itemtitle" href="{$entryUri}">{$entryTitle}</a></h2>
- {$entryTimestamp}
- {$entryAuthor}
- {$entryContent}
+ <h2><a class="itemtitle" href="{$entryUri}">{$entryTitle}</a></h2>
+ {$entryTimestamp}
+ {$entryAuthor}
+ {$entryContent}
</section>
EOD;
- }
+ }
-
- /* Data are prepared, now let's begin the "MAGIE !!!" */
- $toReturn = <<<EOD
+ /* Data are prepared, now let's begin the "MAGIE !!!" */
+ $toReturn = <<<EOD
<!DOCTYPE html>
<html>
<head>
- <meta charset="UTF-8">
- <title>{$title}</title>
- <link href="css/HtmlFormat.css" rel="stylesheet">
- <meta name="robots" content="noindex, follow">
+ <meta charset="UTF-8">
+ <title>{$title}</title>
+ <link href="css/HtmlFormat.css" rel="stylesheet">
+ <meta name="robots" content="noindex, follow">
</head>
<body>
- <h1 class="pagetitle"><a href="{$uri}" target="_blank">{$title}</a></h1>
- <div class="buttons">
- <a href="./#bridge-{$_GET['bridge']}"><button class="backbutton">← back to rss-bridge</button></a>
- <a href="./?{$atomquery}"><button class="rss-feed">RSS feed (ATOM)</button></a>
- <a href="./?{$mrssquery}"><button class="rss-feed">RSS feed (MRSS)</button></a>
- </div>
+ <h1 class="pagetitle"><a href="{$uri}" target="_blank">{$title}</a></h1>
+ <div class="buttons">
+ <a href="./#bridge-{$_GET['bridge']}"><button class="backbutton">← back to rss-bridge</button></a>
+ <a href="./?{$atomquery}"><button class="rss-feed">RSS feed (ATOM)</button></a>
+ <a href="./?{$mrssquery}"><button class="rss-feed">RSS feed (MRSS)</button></a>
+ </div>
{$entries}
</body>
</html>
EOD;
- return $toReturn;
- }
+ return $toReturn;
+ }
- public function display() {
- $this
- ->setContentType('text/html; charset=' . $this->getCharset())
- ->callContentType();
+ public function display() {
+ $this
+ ->setContentType('text/html; charset=' . $this->getCharset())
+ ->callContentType();
- return parent::display();
- }
+ return parent::display();
+ }
}
diff --git a/formats/JsonFormat.php b/formats/JsonFormat.php
index e173f230..ac6e450a 100644
--- a/formats/JsonFormat.php
+++ b/formats/JsonFormat.php
@@ -3,19 +3,18 @@
* Json
* Builds a JSON string from $this->items and return it to browser.
*/
-class JsonFormat extends FormatAbstract{
+class JsonFormat extends FormatAbstract {
- public function stringify(){
- $items = $this->getItems();
+ public function stringify(){
+ $items = $this->getItems();
+ return json_encode($items, JSON_PRETTY_PRINT);
+ }
- return json_encode($items, JSON_PRETTY_PRINT);
- }
+ public function display(){
+ $this
+ ->setContentType('application/json')
+ ->callContentType();
- public function display(){
- $this
- ->setContentType('application/json')
- ->callContentType();
-
- return parent::display();
- }
+ return parent::display();
+ }
}
diff --git a/formats/MrssFormat.php b/formats/MrssFormat.php
index ddbd5d35..fddbf0ac 100644
--- a/formats/MrssFormat.php
+++ b/formats/MrssFormat.php
@@ -3,72 +3,72 @@
* Mrss
* Documentation Source http://www.rssboard.org/media-rss
*/
-class MrssFormat extends FormatAbstract{
+class MrssFormat extends FormatAbstract {
- public function stringify(){
- $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '';
- $httpHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
- $httpInfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
+ public function stringify(){
+ $https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '';
+ $httpHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
+ $httpInfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
- $serverRequestUri = $this->xml_encode($_SERVER['REQUEST_URI']);
+ $serverRequestUri = $this->xml_encode($_SERVER['REQUEST_URI']);
- $extraInfos = $this->getExtraInfos();
- $title = $this->xml_encode($extraInfos['name']);
- $uri = $this->xml_encode(!empty($extraInfos['uri']) ? $extraInfos['uri'] : 'https://github.com/sebsauvage/rss-bridge');
- $icon = $this->xml_encode('http://icons.better-idea.org/icon?url='. $uri .'&size=64');
+ $extraInfos = $this->getExtraInfos();
+ $title = $this->xml_encode($extraInfos['name']);
+ $uri = $this->xml_encode(!empty($extraInfos['uri']) ? $extraInfos['uri'] : 'https://github.com/sebsauvage/rss-bridge');
+ $icon = $this->xml_encode('http://icons.better-idea.org/icon?url='. $uri .'&size=64');
- $items = '';
- foreach($this->getItems() as $item){
- $itemAuthor = isset($item['author']) ? $this->xml_encode($item['author']) : '';
- $itemTitle = strip_tags(isset($item['title']) ? $this->xml_encode($item['title']) : '');
- $itemUri = isset($item['uri']) ? $this->xml_encode($item['uri']) : '';
- $itemTimestamp = isset($item['timestamp']) ? $this->xml_encode(date(DATE_RFC2822, $item['timestamp'])) : '';
- $itemContent = isset($item['content']) ? $this->xml_encode($this->sanitizeHtml($item['content'])) : '';
- $items .= <<<EOD
+ $items = '';
+ foreach($this->getItems() as $item){
+ $itemAuthor = isset($item['author']) ? $this->xml_encode($item['author']) : '';
+ $itemTitle = strip_tags(isset($item['title']) ? $this->xml_encode($item['title']) : '');
+ $itemUri = isset($item['uri']) ? $this->xml_encode($item['uri']) : '';
+ $itemTimestamp = isset($item['timestamp']) ? $this->xml_encode(date(DATE_RFC2822, $item['timestamp'])) : '';
+ $itemContent = isset($item['content']) ? $this->xml_encode($this->sanitizeHtml($item['content'])) : '';
+ $items .= <<<EOD
- <item>
- <title>{$itemTitle}</title>
- <link>{$itemUri}</link>
- <guid isPermaLink="true">{$itemUri}</guid>
- <pubDate>{$itemTimestamp}</pubDate>
- <description>{$itemContent}</description>
- <author>{$itemAuthor}</author>
- </item>
+ <item>
+ <title>{$itemTitle}</title>
+ <link>{$itemUri}</link>
+ <guid isPermaLink="true">{$itemUri}</guid>
+ <pubDate>{$itemTimestamp}</pubDate>
+ <description>{$itemContent}</description>
+ <author>{$itemAuthor}</author>
+ </item>
EOD;
- }
+ }
- /* Data are prepared, now let's begin the "MAGIE !!!" */
- $toReturn = '<?xml version="1.0" encoding="UTF-8"?>';
- $toReturn .= <<<EOD
+ /* Data are prepared, now let's begin the "MAGIE !!!" */
+ $toReturn = '<?xml version="1.0" encoding="UTF-8"?>';
+ $toReturn .= <<<EOD
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{$title}</title>
- <link>http{$https}://{$httpHost}{$httpInfo}/</link>
- <description>{$title}</description>
- <image url="{$icon}" title="{$title}" link="{$uri}"/>
- <atom:link rel="alternate" type="text/html" href="{$uri}" />
- <atom:link rel="self" href="http{$https}://{$httpHost}{$serverRequestUri}" />
- {$items}
- </channel>
+ <channel>
+ <title>{$title}</title>
+ <link>http{$https}://{$httpHost}{$httpInfo}/</link>
+ <description>{$title}</description>
+ <image url="{$icon}" title="{$title}" link="{$uri}"/>
+ <atom:link rel="alternate" type="text/html" href="{$uri}" />
+ <atom:link rel="self" href="http{$https}://{$httpHost}{$serverRequestUri}" />
+ {$items}
+ </channel>
</rss>
EOD;
- // Remove invalid non-UTF8 characters
- ini_set('mbstring.substitute_character', 'none');
- $toReturn= mb_convert_encoding($toReturn, 'UTF-8', 'UTF-8');
- return $toReturn;
- }
+ // Remove invalid non-UTF8 characters
+ ini_set('mbstring.substitute_character', 'none');
+ $toReturn = mb_convert_encoding($toReturn, 'UTF-8', 'UTF-8');
+ return $toReturn;
+ }
- public function display(){
- $this
- ->setContentType('application/rss+xml; charset=UTF-8')
- ->callContentType();
+ public function display(){
+ $this
+ ->setContentType('application/rss+xml; charset=UTF-8')
+ ->callContentType();
- return parent::display();
- }
+ return parent::display();
+ }
- private function xml_encode($text) {
- return htmlspecialchars($text, ENT_XML1);
- }
+ private function xml_encode($text){
+ return htmlspecialchars($text, ENT_XML1);
+ }
}
diff --git a/formats/PlaintextFormat.php b/formats/PlaintextFormat.php
index e2cf0b94..593e938d 100644
--- a/formats/PlaintextFormat.php
+++ b/formats/PlaintextFormat.php
@@ -3,18 +3,18 @@
* Plaintext
* Returns $this->items as raw php data.
*/
-class PlaintextFormat extends FormatAbstract{
+class PlaintextFormat extends FormatAbstract {
- public function stringify(){
- $items = $this->getItems();
- return print_r($items, true);
- }
+ public function stringify(){
+ $items = $this->getItems();
+ return print_r($items, true);
+ }
- public function display(){
- $this
- ->setContentType('text/plain;charset=' . $this->getCharset())
- ->callContentType();
+ public function display(){
+ $this
+ ->setContentType('text/plain;charset=' . $this->getCharset())
+ ->callContentType();
- return parent::display();
- }
-} \ No newline at end of file
+ return parent::display();
+ }
+}
diff --git a/lib/Bridge.php b/lib/Bridge.php
index bacb77a0..a9645810 100644
--- a/lib/Bridge.php
+++ b/lib/Bridge.php
@@ -2,103 +2,105 @@
require_once(__DIR__ . '/BridgeInterface.php');
class Bridge {
- static protected $dirBridge;
-
- public function __construct(){
- throw new \LogicException('Please use ' . __CLASS__ . '::create for new object.');
- }
-
- /**
- * Checks if a bridge is an instantiable bridge.
- * @param string $nameBridge name of the bridge that you want to use
- * @return true if it is an instantiable bridge, false otherwise.
- */
- static public function isInstantiable($nameBridge){
- $re = new ReflectionClass($nameBridge);
- return $re->IsInstantiable();
- }
-
- /**
- * Create a new bridge object
- * @param string $nameBridge Defined bridge name you want use
- * @return Bridge object dedicated
- */
- static public function create($nameBridge){
- if(!preg_match('@^[A-Z][a-zA-Z0-9-]*$@', $nameBridge)){
- $message = <<<EOD
+ static protected $dirBridge;
+
+ public function __construct(){
+ throw new \LogicException('Please use ' . __CLASS__ . '::create for new object.');
+ }
+
+ /**
+ * Checks if a bridge is an instantiable bridge.
+ * @param string $nameBridge name of the bridge that you want to use
+ * @return true if it is an instantiable bridge, false otherwise.
+ */
+ static public function isInstantiable($nameBridge){
+ $re = new ReflectionClass($nameBridge);
+ return $re->IsInstantiable();
+ }
+
+ /**
+ * Create a new bridge object
+ * @param string $nameBridge Defined bridge name you want use
+ * @return Bridge object dedicated
+ */
+ static public function create($nameBridge){
+ if(!preg_match('@^[A-Z][a-zA-Z0-9-]*$@', $nameBridge)){
+ $message = <<<EOD
'nameBridge' must start with one uppercase character followed or not by
alphanumeric or dash characters!
EOD;
- throw new \InvalidArgumentException($message);
- }
-
- $nameBridge = $nameBridge . 'Bridge';
- $pathBridge = self::getDir() . $nameBridge . '.php';
-
- if(!file_exists($pathBridge)){
- throw new \Exception('The bridge you looking for does not exist. It should be at path ' . $pathBridge);
- }
-
- require_once $pathBridge;
-
- if(Bridge::isInstantiable($nameBridge)){
- return new $nameBridge();
- } else {
- return false;
- }
- }
-
- static public function setDir($dirBridge){
- if(!is_string($dirBridge)){
- throw new \InvalidArgumentException('Dir bridge must be a string.');
- }
-
- if(!file_exists($dirBridge)){
- throw new \Exception('Dir bridge does not exist.');
- }
-
- self::$dirBridge = $dirBridge;
- }
-
- static public function getDir(){
- $dirBridge = self::$dirBridge;
-
- if(is_null($dirBridge)){
- throw new \LogicException(__CLASS__ . ' class need to know bridge path !');
- }
-
- return $dirBridge;
- }
-
- /**
- * Lists the available bridges.
- * @return array List of the bridges
- */
- static public function listBridges(){
- $pathDirBridge = self::getDir();
- $listBridge = array();
- $dirFiles = scandir($pathDirBridge);
-
- if($dirFiles !== false){
- foreach($dirFiles as $fileName){
- if(preg_match('@^([^.]+)Bridge\.php$@U', $fileName, $out)){
- $listBridge[] = $out[1];
- }
- }
- }
-
- return $listBridge;
- }
-
- static public function isWhitelisted($whitelist, $name){
- if(in_array($name, $whitelist)
- or in_array($name . '.php', $whitelist)
- or in_array($name . 'Bridge', $whitelist) // DEPRECATED
- or in_array($name . 'Bridge.php', $whitelist) // DEPRECATED
- or count($whitelist) === 1 and trim($whitelist[0]) === '*'){
- return true;
- } else {
- return false;
- }
- }
+ throw new \InvalidArgumentException($message);
+ }
+
+ $nameBridge = $nameBridge . 'Bridge';
+ $pathBridge = self::getDir() . $nameBridge . '.php';
+
+ if(!file_exists($pathBridge)){
+ throw new \Exception('The bridge you looking for does not exist.'
+ . ' It should be at path '
+ . $pathBridge);
+ }
+
+ require_once $pathBridge;
+
+ if(Bridge::isInstantiable($nameBridge)){
+ return new $nameBridge();
+ } else {
+ return false;
+ }
+ }
+
+ static public function setDir($dirBridge){
+ if(!is_string($dirBridge)){
+ throw new \InvalidArgumentException('Dir bridge must be a string.');
+ }
+
+ if(!file_exists($dirBridge)){
+ throw new \Exception('Dir bridge does not exist.');
+ }
+
+ self::$dirBridge = $dirBridge;
+ }
+
+ static public function getDir(){
+ $dirBridge = self::$dirBridge;
+
+ if(is_null($dirBridge)){
+ throw new \LogicException(__CLASS__ . ' class need to know bridge path !');
+ }
+
+ return $dirBridge;
+ }
+
+ /**
+ * Lists the available bridges.
+ * @return array List of the bridges
+ */
+ static public function listBridges(){
+ $pathDirBridge = self::getDir();
+ $listBridge = array();
+ $dirFiles = scandir($pathDirBridge);
+
+ if($dirFiles !== false){
+ foreach($dirFiles as $fileName){
+ if(preg_match('@^([^.]+)Bridge\.php$@U', $fileName, $out)){
+ $listBridge[] = $out[1];
+ }
+ }
+ }
+
+ return $listBridge;
+ }
+
+ static public function isWhitelisted($whitelist, $name){
+ if(in_array($name, $whitelist)
+ || in_array($name . '.php', $whitelist)
+ || in_array($name . 'Bridge', $whitelist) // DEPRECATED
+ || in_array($name . 'Bridge.php', $whitelist) // DEPRECATED
+ || count($whitelist) === 1 and trim($whitelist[0]) === '*'){
+ return true;
+ } else {
+ return false;
+ }
+ }
}
diff --git a/lib/BridgeAbstract.php b/lib/BridgeAbstract.php
index abcda79d..d17c6bd2 100644
--- a/lib/BridgeAbstract.php
+++ b/lib/BridgeAbstract.php
@@ -2,444 +2,445 @@
require_once(__DIR__ . '/BridgeInterface.php');
abstract class BridgeAbstract implements BridgeInterface {
- const NAME = 'Unnamed bridge';
- const URI = '';
- const DESCRIPTION = 'No description provided';
- const MAINTAINER = 'No maintainer';
- const PARAMETERS = array();
-
- public $useProxy = true;
-
- protected $cache;
- protected $items = array();
- protected $inputs = array();
- protected $queriedContext = '';
-
- protected function returnError($message, $code){
- throw new \HttpException($message, $code);
- }
-
- protected function returnClientError($message){
- $this->returnError($message, 400);
- }
-
- protected function returnServerError($message){
- $this->returnError($message, 500);
- }
-
- /**
- * Return items stored in the bridge
- * @return mixed
- */
- public function getItems(){
- return $this->items;
- }
-
- protected function validateTextValue($value, $pattern = null){
- if(!is_null($pattern)){
- $filteredValue = filter_var($value, FILTER_VALIDATE_REGEXP,
- array('options' => array(
- 'regexp' => '/^' . $pattern . '$/'
- ))
- );
- } else {
- $filteredValue = filter_var($value);
- }
-
- if($filteredValue === false)
- return null;
-
- return $filteredValue;
- }
-
- protected function validateNumberValue($value){
- $filteredValue = filter_var($value, FILTER_VALIDATE_INT);
-
- if($filteredValue === false && !empty($value))
- return null;
-
- return $filteredValue;
- }
-
- protected function validateCheckboxValue($value){
- $filteredValue = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
-
- if(is_null($filteredValue))
- return null;
-
- return $filteredValue;
- }
-
- protected function validateListValue($value, $expectedValues){
- $filteredValue = filter_var($value);
-
- if($filteredValue === false)
- return null;
-
- if(!in_array($filteredValue, $expectedValues)){ // Check sub-values?
- foreach($expectedValues as $subName => $subValue){
- if(is_array($subValue) && in_array($filteredValue, $subValue))
- return $filteredValue;
- }
- return null;
- }
-
- return $filteredValue;
- }
-
- protected function validateData(&$data){
- if(!is_array($data))
- return false;
-
- foreach($data as $name=>$value){
- $registered = false;
- foreach(static::PARAMETERS as $context=>$set){
- if(array_key_exists($name,$set)){
- $registered = true;
- if(!isset($set[$name]['type'])){
- $set[$name]['type']='text';
- }
-
- switch($set[$name]['type']){
- case 'number':
- $data[$name] = $this->validateNumberValue($value);
- break;
- case 'checkbox':
- $data[$name] = $this->validateCheckboxValue($value);
- break;
- case 'list':
- $data[$name] = $this->validateListValue($value, $set[$name]['values']);
- break;
- default:
- case 'text':
- if(isset($set[$name]['pattern'])){
- $data[$name] = $this->validateTextValue($value, $set[$name]['pattern']);
- } else {
- $data[$name] = $this->validateTextValue($value);
- }
- break;
- }
-
- if(is_null($data[$name])){
- echo 'Parameter \'' . $name . '\' is invalid!' . PHP_EOL;
- return false;
- }
- }
- }
-
- if(!$registered)
- return false;
- }
-
- return true;
- }
-
- protected function setInputs(array $inputs, $queriedContext){
- // Import and assign all inputs to their context
- foreach($inputs as $name => $value){
- foreach(static::PARAMETERS as $context => $set){
- if(array_key_exists($name, static::PARAMETERS[$context])){
- $this->inputs[$context][$name]['value'] = $value;
- }
- }
- }
-
- // Apply default values to missing data
- $contexts = array($queriedContext);
- if(array_key_exists('global', static::PARAMETERS)){
- $contexts[] = 'global';
- }
-
- foreach($contexts as $context){
- foreach(static::PARAMETERS[$context] as $name => $properties){
- if(isset($this->inputs[$context][$name]['value'])){
- continue;
- }
-
- $type = isset($properties['type']) ? $properties['type'] : 'text';
-
- switch($type){
- case 'checkbox':
- if(!isset($properties['defaultValue'])){
- $this->inputs[$context][$name]['value'] = false;
- } else {
- $this->inputs[$context][$name]['value'] = $properties['defaultValue'];
- }
- break;
- case 'list':
- if(!isset($properties['defaultValue'])){
- $firstItem = reset($properties['values']);
- if(is_array($firstItem)){
- $firstItem = reset($firstItem);
- }
- $this->inputs[$context][$name]['value'] = $firstItem;
- } else {
- $this->inputs[$context][$name]['value'] = $properties['defaultValue'];
- }
- break;
- default:
- if(isset($properties['defaultValue'])){
- $this->inputs[$context][$name]['value'] = $properties['defaultValue'];
- }
- break;
- }
- }
- }
-
- // Copy global parameter values to the guessed context
- if(array_key_exists('global', static::PARAMETERS)){
- foreach(static::PARAMETERS['global'] as $name => $properties){
- if(isset($inputs[$name])){
- $value = $inputs[$name];
- } elseif (isset($properties['value'])){
- $value = $properties['value'];
- } else {
- continue;
- }
- $this->inputs[$queriedContext][$name]['value'] = $value;
- }
- }
-
- // Only keep guessed context parameters values
- if(isset($this->inputs[$queriedContext])){
- $this->inputs = array($queriedContext => $this->inputs[$queriedContext]);
- } else {
- $this->inputs = array();
- }
- }
-
- protected function getQueriedContext(array $inputs){
- $queriedContexts=array();
- foreach(static::PARAMETERS as $context=>$set){
- $queriedContexts[$context]=null;
- foreach($set as $id=>$properties){
- if(isset($inputs[$id]) && !empty($inputs[$id])){
- $queriedContexts[$context]=true;
- }elseif(isset($properties['required']) &&
- $properties['required']===true){
- $queriedContexts[$context]=false;
- break;
- }
- }
- }
-
- if(array_key_exists('global',static::PARAMETERS) &&
- $queriedContexts['global']===false){
- return null;
- }
- unset($queriedContexts['global']);
-
- switch(array_sum($queriedContexts)){
- case 0:
- foreach($queriedContexts as $context=>$queried){
- if (is_null($queried)){
- return $context;
- }
- }
- return null;
- case 1: return array_search(true,$queriedContexts);
- default: return false;
- }
- }
-
- /**
- * Defined datas with parameters depending choose bridge
- * Note : you can define a cache with "setCache"
- * @param array array with expected bridge paramters
- */
- public function setDatas(array $inputs){
- if(!is_null($this->cache)){
- $this->cache->prepare($inputs);
- $time = $this->cache->getTime();
- if($time !== false && (time() - $this->getCacheDuration() < $time)){
- $this->items = $this->cache->loadData();
- return;
- }
- }
-
- if(empty(static::PARAMETERS)){
- if(!empty($inputs)){
- $this->returnClientError('Invalid parameters value(s)');
- }
-
- $this->collectData();
- if(!is_null($this->cache)){
- $this->cache->saveData($this->getItems());
- }
- return;
- }
-
- if(!$this->validateData($inputs)){
- $this->returnClientError('Invalid parameters value(s)');
- }
-
- // Guess the paramter context from input data
- $this->queriedContext = $this->getQueriedContext($inputs);
- if(is_null($this->queriedContext)){
- $this->returnClientError('Required parameter(s) missing');
- } elseif($this->queriedContext === false){
- $this->returnClientError('Mixed context parameters');
- }
-
- $this->setInputs($inputs, $this->queriedContext);
-
- $this->collectData();
-
- if(!is_null($this->cache)){
- $this->cache->saveData($this->getItems());
- }
- }
-
- function getInput($input){
- if(!isset($this->inputs[$this->queriedContext][$input]['value'])){
- return null;
- }
- return $this->inputs[$this->queriedContext][$input]['value'];
- }
-
- public function getName(){
- return static::NAME;
- }
-
- public function getURI(){
- return static::URI;
- }
-
- public function getCacheDuration(){
- return 3600;
- }
-
- public function setCache(\CacheAbstract $cache){
- $this->cache = $cache;
- }
-
- public function debugMessage($text){
- if(!file_exists('DEBUG')) {
- return;
- }
-
- $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
- $calling = $backtrace[2];
- $message = $calling['file'] . ':'
- . $calling['line'] . ' class '
- . get_class($this) . '->'
- . $calling['function'] . ' - '
- . $text;
-
- error_log($message);
- }
-
- protected function getContents($url
- , $use_include_path = false
- , $context = null
- , $offset = 0
- , $maxlen = null){
- $contextOptions = array(
- 'http' => array(
- 'user_agent' => ini_get('user_agent')
- ),
- );
-
- if(defined('PROXY_URL') && $this->useProxy){
- $contextOptions['http']['proxy'] = PROXY_URL;
- $contextOptions['http']['request_fulluri'] = true;
-
- if(is_null($context)){
- $context = stream_context_create($contextOptions);
- } else {
- $prevContext=$context;
- if(!stream_context_set_option($context, $contextOptions)){
- $context = $prevContext;
- }
- }
- }
-
- if(is_null($maxlen)){
- $content = @file_get_contents($url, $use_include_path, $context, $offset);
- } else {
- $content = @file_get_contents($url, $use_include_path, $context, $offset, $maxlen);
- }
-
- if($content === false)
- $this->debugMessage('Cant\'t download ' . $url);
-
- return $content;
- }
-
- protected function getSimpleHTMLDOM($url
- , $use_include_path = false
- , $context = null
- , $offset = 0
- , $maxLen = null
- , $lowercase = true
- , $forceTagsClosed = true
- , $target_charset = DEFAULT_TARGET_CHARSET
- , $stripRN = true
- , $defaultBRText = DEFAULT_BR_TEXT
- , $defaultSpanText = DEFAULT_SPAN_TEXT){
- $content = $this->getContents($url, $use_include_path, $context, $offset, $maxLen);
- return str_get_html($content
- , $lowercase
- , $forceTagsClosed
- , $target_charset
- , $stripRN
- , $defaultBRText
- , $defaultSpanText);
- }
-
- /**
- * Maintain locally cached versions of pages to avoid multiple downloads.
- * @param url url to cache
- * @param duration duration of the cache file in seconds (default: 24h/86400s)
- * @return content of the file as string
- */
- public function getSimpleHTMLDOMCached($url
- , $duration = 86400
- , $use_include_path = false
- , $context = null
- , $offset = 0
- , $maxLen = null
- , $lowercase = true
- , $forceTagsClosed = true
- , $target_charset = DEFAULT_TARGET_CHARSET
- , $stripRN = true
- , $defaultBRText = DEFAULT_BR_TEXT
- , $defaultSpanText = DEFAULT_SPAN_TEXT){
- $this->debugMessage('Caching url ' . $url . ', duration ' . $duration);
-
- $filepath = __DIR__ . '/../cache/pages/' . sha1($url) . '.cache';
- $this->debugMessage('Cache file ' . $filepath);
-
- if(file_exists($filepath) && filectime($filepath) < time() - $duration){
- unlink ($filepath);
- $this->debugMessage('Cached file deleted: ' . $filepath);
- }
-
- if(file_exists($filepath)){
- $this->debugMessage('Loading cached file ' . $filepath);
- touch($filepath);
- $content = file_get_contents($filepath);
- } else {
- $this->debugMessage('Caching ' . $url . ' to ' . $filepath);
- $dir = substr($filepath, 0, strrpos($filepath, '/'));
-
- if(!is_dir($dir)){
- $this->debugMessage('Creating directory ' . $dir);
- mkdir($dir, 0777, true);
- }
-
- $content = $this->getContents($url, $use_include_path, $context, $offset, $maxLen);
- if($content !== false){
- file_put_contents($filepath, $content);
- }
- }
-
- return str_get_html($content
- , $lowercase
- , $forceTagsClosed
- , $target_charset
- , $stripRN
- , $defaultBRText
- , $defaultSpanText);
- }
+ const NAME = 'Unnamed bridge';
+ const URI = '';
+ const DESCRIPTION = 'No description provided';
+ const MAINTAINER = 'No maintainer';
+ const PARAMETERS = array();
+
+ public $useProxy = true;
+
+ protected $cache;
+ protected $items = array();
+ protected $inputs = array();
+ protected $queriedContext = '';
+
+ protected function returnError($message, $code){
+ throw new \HttpException($message, $code);
+ }
+
+ protected function returnClientError($message){
+ $this->returnError($message, 400);
+ }
+
+ protected function returnServerError($message){
+ $this->returnError($message, 500);
+ }
+
+ /**
+ * Return items stored in the bridge
+ * @return mixed
+ */
+ public function getItems(){
+ return $this->items;
+ }
+
+ protected function validateTextValue($value, $pattern = null){
+ if(!is_null($pattern)){
+ $filteredValue = filter_var($value
+ , FILTER_VALIDATE_REGEXP
+ , array('options' => array(
+ 'regexp' => '/^' . $pattern . '$/'
+ ))
+ );
+ } else {
+ $filteredValue = filter_var($value);
+ }
+
+ if($filteredValue === false)
+ return null;
+
+ return $filteredValue;
+ }
+
+ protected function validateNumberValue($value){
+ $filteredValue = filter_var($value, FILTER_VALIDATE_INT);
+
+ if($filteredValue === false && !empty($value))
+ return null;
+
+ return $filteredValue;
+ }
+
+ protected function validateCheckboxValue($value){
+ $filteredValue = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
+
+ if(is_null($filteredValue))
+ return null;
+
+ return $filteredValue;
+ }
+
+ protected function validateListValue($value, $expectedValues){
+ $filteredValue = filter_var($value);
+
+ if($filteredValue === false)
+ return null;
+
+ if(!in_array($filteredValue, $expectedValues)){ // Check sub-values?
+ foreach($expectedValues as $subName => $subValue){
+ if(is_array($subValue) && in_array($filteredValue, $subValue))
+ return $filteredValue;
+ }
+ return null;
+ }
+
+ return $filteredValue;
+ }
+
+ protected function validateData(&$data){
+ if(!is_array($data))
+ return false;
+
+ foreach($data as $name => $value){
+ $registered = false;
+ foreach(static::PARAMETERS as $context => $set){
+ if(array_key_exists($name, $set)){
+ $registered = true;
+ if(!isset($set[$name]['type'])){
+ $set[$name]['type'] = 'text';
+ }
+
+ switch($set[$name]['type']){
+ case 'number':
+ $data[$name] = $this->validateNumberValue($value);
+ break;
+ case 'checkbox':
+ $data[$name] = $this->validateCheckboxValue($value);
+ break;
+ case 'list':
+ $data[$name] = $this->validateListValue($value, $set[$name]['values']);
+ break;
+ default:
+ case 'text':
+ if(isset($set[$name]['pattern'])){
+ $data[$name] = $this->validateTextValue($value, $set[$name]['pattern']);
+ } else {
+ $data[$name] = $this->validateTextValue($value);
+ }
+ break;
+ }
+
+ if(is_null($data[$name])){
+ echo 'Parameter \'' . $name . '\' is invalid!' . PHP_EOL;
+ return false;
+ }
+ }
+ }
+
+ if(!$registered)
+ return false;
+ }
+
+ return true;
+ }
+
+ protected function setInputs(array $inputs, $queriedContext){
+ // Import and assign all inputs to their context
+ foreach($inputs as $name => $value){
+ foreach(static::PARAMETERS as $context => $set){
+ if(array_key_exists($name, static::PARAMETERS[$context])){
+ $this->inputs[$context][$name]['value'] = $value;
+ }
+ }
+ }
+
+ // Apply default values to missing data
+ $contexts = array($queriedContext);
+ if(array_key_exists('global', static::PARAMETERS)){
+ $contexts[] = 'global';
+ }
+
+ foreach($contexts as $context){
+ foreach(static::PARAMETERS[$context] as $name => $properties){
+ if(isset($this->inputs[$context][$name]['value'])){
+ continue;
+ }
+
+ $type = isset($properties['type']) ? $properties['type'] : 'text';
+
+ switch($type){
+ case 'checkbox':
+ if(!isset($properties['defaultValue'])){
+ $this->inputs[$context][$name]['value'] = false;
+ } else {
+ $this->inputs[$context][$name]['value'] = $properties['defaultValue'];
+ }
+ break;
+ case 'list':
+ if(!isset($properties['defaultValue'])){
+ $firstItem = reset($properties['values']);
+ if(is_array($firstItem)){
+ $firstItem = reset($firstItem);
+ }
+ $this->inputs[$context][$name]['value'] = $firstItem;
+ } else {
+ $this->inputs[$context][$name]['value'] = $properties['defaultValue'];
+ }
+ break;
+ default:
+ if(isset($properties['defaultValue'])){
+ $this->inputs[$context][$name]['value'] = $properties['defaultValue'];
+ }
+ break;
+ }
+ }
+ }
+
+ // Copy global parameter values to the guessed context
+ if(array_key_exists('global', static::PARAMETERS)){
+ foreach(static::PARAMETERS['global'] as $name => $properties){
+ if(isset($inputs[$name])){
+ $value = $inputs[$name];
+ } elseif (isset($properties['value'])){
+ $value = $properties['value'];
+ } else {
+ continue;
+ }
+ $this->inputs[$queriedContext][$name]['value'] = $value;
+ }
+ }
+
+ // Only keep guessed context parameters values
+ if(isset($this->inputs[$queriedContext])){
+ $this->inputs = array($queriedContext => $this->inputs[$queriedContext]);
+ } else {
+ $this->inputs = array();
+ }
+ }
+
+ protected function getQueriedContext(array $inputs){
+ $queriedContexts = array();
+ foreach(static::PARAMETERS as $context => $set){
+ $queriedContexts[$context] = null;
+ foreach($set as $id => $properties){
+ if(isset($inputs[$id]) && !empty($inputs[$id])){
+ $queriedContexts[$context] = true;
+ } elseif(isset($properties['required'])
+ && $properties['required'] === true){
+ $queriedContexts[$context] = false;
+ break;
+ }
+ }
+ }
+
+ if(array_key_exists('global', static::PARAMETERS)
+ && $queriedContexts['global'] === false){
+ return null;
+ }
+ unset($queriedContexts['global']);
+
+ switch(array_sum($queriedContexts)){
+ case 0:
+ foreach($queriedContexts as $context => $queried){
+ if (is_null($queried)){
+ return $context;
+ }
+ }
+ return null;
+ case 1: return array_search(true, $queriedContexts);
+ default: return false;
+ }
+ }
+
+ /**
+ * Defined datas with parameters depending choose bridge
+ * Note : you can define a cache with "setCache"
+ * @param array array with expected bridge paramters
+ */
+ public function setDatas(array $inputs){
+ if(!is_null($this->cache)){
+ $this->cache->prepare($inputs);
+ $time = $this->cache->getTime();
+ if($time !== false && (time() - $this->getCacheDuration() < $time)){
+ $this->items = $this->cache->loadData();
+ return;
+ }
+ }
+
+ if(empty(static::PARAMETERS)){
+ if(!empty($inputs)){
+ $this->returnClientError('Invalid parameters value(s)');
+ }
+
+ $this->collectData();
+ if(!is_null($this->cache)){
+ $this->cache->saveData($this->getItems());
+ }
+ return;
+ }
+
+ if(!$this->validateData($inputs)){
+ $this->returnClientError('Invalid parameters value(s)');
+ }
+
+ // Guess the paramter context from input data
+ $this->queriedContext = $this->getQueriedContext($inputs);
+ if(is_null($this->queriedContext)){
+ $this->returnClientError('Required parameter(s) missing');
+ } elseif($this->queriedContext === false){
+ $this->returnClientError('Mixed context parameters');
+ }
+
+ $this->setInputs($inputs, $this->queriedContext);
+
+ $this->collectData();
+
+ if(!is_null($this->cache)){
+ $this->cache->saveData($this->getItems());
+ }
+ }
+
+ function getInput($input){
+ if(!isset($this->inputs[$this->queriedContext][$input]['value'])){
+ return null;
+ }
+ return $this->inputs[$this->queriedContext][$input]['value'];
+ }
+
+ public function getName(){
+ return static::NAME;
+ }
+
+ public function getURI(){
+ return static::URI;
+ }
+
+ public function getCacheDuration(){
+ return 3600;
+ }
+
+ public function setCache(\CacheAbstract $cache){
+ $this->cache = $cache;
+ }
+
+ public function debugMessage($text){
+ if(!file_exists('DEBUG')) {
+ return;
+ }
+
+ $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
+ $calling = $backtrace[2];
+ $message = $calling['file'] . ':'
+ . $calling['line'] . ' class '
+ . get_class($this) . '->'
+ . $calling['function'] . ' - '
+ . $text;
+
+ error_log($message);
+ }
+
+ protected function getContents($url
+ , $use_include_path = false
+ , $context = null
+ , $offset = 0
+ , $maxlen = null){
+ $contextOptions = array(
+ 'http' => array(
+ 'user_agent' => ini_get('user_agent')
+ )
+ );
+
+ if(defined('PROXY_URL') && $this->useProxy){
+ $contextOptions['http']['proxy'] = PROXY_URL;
+ $contextOptions['http']['request_fulluri'] = true;
+
+ if(is_null($context)){
+ $context = stream_context_create($contextOptions);
+ } else {
+ $prevContext=$context;
+ if(!stream_context_set_option($context, $contextOptions)){
+ $context = $prevContext;
+ }
+ }
+ }
+
+ if(is_null($maxlen)){
+ $content = @file_get_contents($url, $use_include_path, $context, $offset);
+ } else {
+ $content = @file_get_contents($url, $use_include_path, $context, $offset, $maxlen);
+ }
+
+ if($content === false)
+ $this->debugMessage('Cant\'t download ' . $url);
+
+ return $content;
+ }
+
+ protected function getSimpleHTMLDOM($url
+ , $use_include_path = false
+ , $context = null
+ , $offset = 0
+ , $maxLen = null
+ , $lowercase = true
+ , $forceTagsClosed = true
+ , $target_charset = DEFAULT_TARGET_CHARSET
+ , $stripRN = true
+ , $defaultBRText = DEFAULT_BR_TEXT
+ , $defaultSpanText = DEFAULT_SPAN_TEXT){
+ $content = $this->getContents($url, $use_include_path, $context, $offset, $maxLen);
+ return str_get_html($content
+ , $lowercase
+ , $forceTagsClosed
+ , $target_charset
+ , $stripRN
+ , $defaultBRText
+ , $defaultSpanText);
+ }
+
+ /**
+ * Maintain locally cached versions of pages to avoid multiple downloads.
+ * @param url url to cache
+ * @param duration duration of the cache file in seconds (default: 24h/86400s)
+ * @return content of the file as string
+ */
+ public function getSimpleHTMLDOMCached($url
+ , $duration = 86400
+ , $use_include_path = false
+ , $context = null
+ , $offset = 0
+ , $maxLen = null
+ , $lowercase = true
+ , $forceTagsClosed = true
+ , $target_charset = DEFAULT_TARGET_CHARSET
+ , $stripRN = true
+ , $defaultBRText = DEFAULT_BR_TEXT
+ , $defaultSpanText = DEFAULT_SPAN_TEXT){
+ $this->debugMessage('Caching url ' . $url . ', duration ' . $duration);
+
+ $filepath = __DIR__ . '/../cache/pages/' . sha1($url) . '.cache';
+ $this->debugMessage('Cache file ' . $filepath);
+
+ if(file_exists($filepath) && filectime($filepath) < time() - $duration){
+ unlink ($filepath);
+ $this->debugMessage('Cached file deleted: ' . $filepath);
+ }
+
+ if(file_exists($filepath)){
+ $this->debugMessage('Loading cached file ' . $filepath);
+ touch($filepath);
+ $content = file_get_contents($filepath);
+ } else {
+ $this->debugMessage('Caching ' . $url . ' to ' . $filepath);
+ $dir = substr($filepath, 0, strrpos($filepath, '/'));
+
+ if(!is_dir($dir)){
+ $this->debugMessage('Creating directory ' . $dir);
+ mkdir($dir, 0777, true);
+ }
+
+ $content = $this->getContents($url, $use_include_path, $context, $offset, $maxLen);
+ if($content !== false){
+ file_put_contents($filepath, $content);
+ }
+ }
+
+ return str_get_html($content
+ , $lowercase
+ , $forceTagsClosed
+ , $target_charset
+ , $stripRN
+ , $defaultBRText
+ , $defaultSpanText);
+ }
}
diff --git a/lib/BridgeInterface.php b/lib/BridgeInterface.php
index 5054d102..a63b63f5 100644
--- a/lib/BridgeInterface.php
+++ b/lib/BridgeInterface.php
@@ -1,7 +1,7 @@
<?php
interface BridgeInterface {
- public function collectData();
- public function getCacheDuration();
- public function getName();
- public function getURI();
+ public function collectData();
+ public function getCacheDuration();
+ public function getName();
+ public function getURI();
}
diff --git a/lib/Cache.php b/lib/Cache.php
index 572b96dc..b04f53ee 100644
--- a/lib/Cache.php
+++ b/lib/Cache.php
@@ -1,91 +1,93 @@
<?php
require_once(__DIR__ . '/CacheInterface.php');
-class Cache{
+class Cache {
- static protected $dirCache;
+ static protected $dirCache;
- public function __construct(){
- throw new \LogicException('Please use ' . __CLASS__ . '::create for new object.');
- }
+ public function __construct(){
+ throw new \LogicException('Please use ' . __CLASS__ . '::create for new object.');
+ }
- static public function create($nameCache){
- if( !static::isValidNameCache($nameCache) ){
- throw new \InvalidArgumentException('Name cache must be at least one uppercase follow or not by alphanumeric or dash characters.');
- }
+ static public function create($nameCache){
+ if(!static::isValidNameCache($nameCache)){
+ throw new \InvalidArgumentException('Name cache must be at least'
+ . ' one uppercase follow or not by alphanumeric or dash characters.');
+ }
- $pathCache = self::getDir() . $nameCache . '.php';
+ $pathCache = self::getDir() . $nameCache . '.php';
- if( !file_exists($pathCache) ){
- throw new \Exception('The cache you looking for does not exist.');
- }
+ if(!file_exists($pathCache)){
+ throw new \Exception('The cache you looking for does not exist.');
+ }
- require_once $pathCache;
+ require_once $pathCache;
- return new $nameCache();
- }
+ return new $nameCache();
+ }
- static public function setDir($dirCache){
- if( !is_string($dirCache) ){
- throw new \InvalidArgumentException('Dir cache must be a string.');
- }
+ static public function setDir($dirCache){
+ if(!is_string($dirCache)){
+ throw new \InvalidArgumentException('Dir cache must be a string.');
+ }
- if( !file_exists($dirCache) ){
- throw new \Exception('Dir cache does not exist.');
- }
+ if(!file_exists($dirCache)){
+ throw new \Exception('Dir cache does not exist.');
+ }
- self::$dirCache = $dirCache;
- }
+ self::$dirCache = $dirCache;
+ }
- static public function getDir(){
- $dirCache = self::$dirCache;
+ static public function getDir(){
+ $dirCache = self::$dirCache;
- if( is_null($dirCache) ){
- throw new \LogicException(__CLASS__ . ' class need to know cache path !');
- }
+ if(is_null($dirCache)){
+ throw new \LogicException(__CLASS__ . ' class need to know cache path !');
+ }
+
+ return $dirCache;
+ }
- return $dirCache;
- }
+ static public function isValidNameCache($nameCache){
+ return preg_match('@^[A-Z][a-zA-Z0-9-]*$@', $nameCache);
+ }
- static public function isValidNameCache($nameCache){
- return preg_match('@^[A-Z][a-zA-Z0-9-]*$@', $nameCache);
- }
+ static public function utf8_encode_deep(&$input){
+ if (is_string($input)){
+ $input = utf8_encode($input);
+ } elseif(is_array($input)){
+ foreach($input as &$value){
+ Cache::utf8_encode_deep($value);
+ }
- static public function utf8_encode_deep(&$input) {
- if (is_string($input)) {
- $input = utf8_encode($input);
- } else if (is_array($input)) {
- foreach ($input as &$value) {
- Cache::utf8_encode_deep($value);
- }
+ unset($value);
+ } elseif(is_object($input)){
+ $vars = array_keys(get_object_vars($input));
- unset($value);
- } else if (is_object($input)) {
- $vars = array_keys(get_object_vars($input));
+ foreach($vars as $var){
+ Cache::utf8_encode_deep($input->$var);
+ }
+ }
+ }
- foreach ($vars as $var) {
- Cache::utf8_encode_deep($input->$var);
- }
- }
- }
-
- static public function purge() {
- $cacheTimeLimit = time() - 60*60*24 ;
+ static public function purge(){
+ $cacheTimeLimit = time() - 60*60*24;
$cachePath = 'cache';
- if(file_exists($cachePath)) {
- $cacheIterator = new RecursiveIteratorIterator(
- new RecursiveDirectoryIterator($cachePath),
- RecursiveIteratorIterator::CHILD_FIRST
- );
- foreach ($cacheIterator as $cacheFile) {
- if (in_array($cacheFile->getBasename(), array('.', '..')))
- continue;
- elseif ($cacheFile->isFile()) {
- if( filemtime($cacheFile->getPathname()) < $cacheTimeLimit )
- unlink( $cacheFile->getPathname() );
- }
- }
+ if(file_exists($cachePath)){
+ $cacheIterator = new RecursiveIteratorIterator(
+ new RecursiveDirectoryIterator($cachePath),
+ RecursiveIteratorIterator::CHILD_FIRST
+ );
+
+ foreach($cacheIterator as $cacheFile){
+ if(in_array($cacheFile->getBasename(), array('.', '..')))
+ continue;
+ elseif($cacheFile->isFile()){
+ if(filemtime($cacheFile->getPathname()) < $cacheTimeLimit)
+ unlink($cacheFile->getPathname());
+ }
+ }
}
}
diff --git a/lib/CacheAbstract.php b/lib/CacheAbstract.php
index 98608b25..e6c39d8c 100644
--- a/lib/CacheAbstract.php
+++ b/lib/CacheAbstract.php
@@ -1,11 +1,11 @@
<?php
require_once(__DIR__ . '/CacheInterface.php');
-abstract class CacheAbstract implements CacheInterface{
- protected $param;
+abstract class CacheAbstract implements CacheInterface {
+ protected $param;
- public function prepare(array $param){
- $this->param = $param;
+ public function prepare(array $param){
+ $this->param = $param;
- return $this;
- }
+ return $this;
+ }
}
diff --git a/lib/CacheInterface.php b/lib/CacheInterface.php
index 89d78ecc..4c59df30 100644
--- a/lib/CacheInterface.php
+++ b/lib/CacheInterface.php
@@ -1,6 +1,6 @@
<?php
-interface CacheInterface{
- public function loadData();
- public function saveData($datas);
- public function getTime();
+interface CacheInterface {
+ public function loadData();
+ public function saveData($datas);
+ public function getTime();
}
diff --git a/lib/Exceptions.php b/lib/Exceptions.php
index 74124eaa..9b906940 100644
--- a/lib/Exceptions.php
+++ b/lib/Exceptions.php
@@ -6,56 +6,55 @@ class HttpException extends \Exception{}
*/
class Http{
- /**
- * Return message corresponding to Http code
- */
- static public function getMessageForCode($code){
- $codes = self::getCodes();
+ /**
+ * Return message corresponding to Http code
+ */
+ static public function getMessageForCode($code){
+ $codes = self::getCodes();
- if( isset($codes[$code]) ){
- return $codes[$code];
- }
+ if(isset($codes[$code]))
+ return $codes[$code];
- return '';
- }
+ return '';
+ }
- /**
- * List of common Http code
- */
- static public function getCodes(){
- return array(
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Moved Temporarily',
- 307 => 'Temporary Redirect',
- 310 => 'Too many Redirects',
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 402 => 'Payment Required',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Time-out',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Requested range unsatisfiable',
- 417 => 'Expectation failed',
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Time-out',
- 508 => 'Loop detected',
- );
- }
+ /**
+ * List of common Http code
+ */
+ static public function getCodes(){
+ return array(
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Moved Temporarily',
+ 307 => 'Temporary Redirect',
+ 310 => 'Too many Redirects',
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Time-out',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested range unsatisfiable',
+ 417 => 'Expectation failed',
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Time-out',
+ 508 => 'Loop detected',
+ );
+ }
}
diff --git a/lib/FeedExpander.php b/lib/FeedExpander.php
index 5566f7c1..f0ec4c62 100644
--- a/lib/FeedExpander.php
+++ b/lib/FeedExpander.php
@@ -2,175 +2,178 @@
require_once(__DIR__ . '/BridgeInterface.php');
abstract class FeedExpander extends BridgeAbstract {
- private $name;
- private $uri;
- private $description;
-
- public function collectExpandableDatas($url, $maxItems = -1){
- if(empty($url)){
- $this->returnServerError('There is no $url for this RSS expander');
- }
-
- $this->debugMessage('Loading from ' . $url);
-
- /* Notice we do not use cache here on purpose:
- * we want a fresh view of the RSS stream each time
- */
- $content = $this->getContents($url)
- or $this->returnServerError('Could not request ' . $url);
- $rssContent = simplexml_load_string($content);
-
- $this->debugMessage('Detecting feed format/version');
- if(isset($rssContent->channel[0])){
- $this->debugMessage('Detected RSS format');
- if(isset($rssContent->item[0])){
- $this->debugMessage('Detected RSS 1.0 format');
- $this->collect_RSS_1_0_data($rssContent, $maxItems);
- } else {
- $this->debugMessage('Detected RSS 0.9x or 2.0 format');
- $this->collect_RSS_2_0_data($rssContent, $maxItems);
- }
- } elseif(isset($rssContent->entry[0])){
- $this->debugMessage('Detected ATOM format');
- $this->collect_ATOM_data($rssContent, $maxItems);
- } else {
- $this->debugMessage('Unknown feed format/version');
- $this->returnServerError('The feed format is unknown!');
- }
- }
-
- protected function collect_RSS_1_0_data($rssContent, $maxItems){
- $this->load_RSS_2_0_feed_data($rssContent->channel[0]);
- foreach($rssContent->item as $item){
- $this->debugMessage('parsing item ' . var_export($item, true));
- $this->items[] = $this->parseItem($item);
- if($maxItems !== -1 && count($this->items) >= $maxItems) break;
- }
- }
-
- protected function collect_RSS_2_0_data($rssContent, $maxItems){
- $rssContent = $rssContent->channel[0];
- $this->debugMessage('RSS content is ===========\n' . var_export($rssContent, true) . '===========');
- $this->load_RSS_2_0_feed_data($rssContent);
- foreach($rssContent->item as $item){
- $this->debugMessage('parsing item ' . var_export($item, true));
- $this->items[] = $this->parseItem($item);
- if($maxItems !== -1 && count($this->items) >= $maxItems) break;
- }
- }
-
- protected function collect_ATOM_data($content, $maxItems){
- $this->load_ATOM_feed_data($content);
- foreach($content->entry as $item){
- $this->debugMessage('parsing item ' . var_export($item, true));
- $this->items[] = $this->parseItem($item);
- if($maxItems !== -1 && count($this->items) >= $maxItems) break;
- }
- }
-
- protected function RSS_2_0_time_to_timestamp($item){
- return DateTime::createFromFormat('D, d M Y H:i:s e', $item->pubDate)->getTimestamp();
- }
-
- // TODO set title, link, description, language, and so on
- protected function load_RSS_2_0_feed_data($rssContent){
- $this->name = trim($rssContent->title);
- $this->uri = trim($rssContent->link);
- $this->description = trim($rssContent->description);
- }
-
- protected function load_ATOM_feed_data($content){
- $this->name = $content->title;
-
- // Find best link (only one, or first of 'alternate')
- if(!isset($content->link)){
- $this->uri = '';
- } elseif (count($content->link) === 1){
- $this->uri = $content->link[0]['href'];
- } else {
- $this->uri = '';
- foreach($content->link as $link){
- if(strtolower($link['rel']) === 'alternate'){
- $this->uri = $link['href'];
- break;
- }
- }
- }
-
- if(isset($content->subtitle))
- $this->description = $content->subtitle;
- }
-
- protected function parseATOMItem($feedItem){
- $item = array();
- if(isset($feedItem->id)) $item['uri'] = $feedItem->id;
- if(isset($feedItem->title)) $item['title'] = $feedItem->title;
- if(isset($feedItem->updated)) $item['timestamp'] = strtotime($feedItem->updated);
- if(isset($feedItem->author)) $item['author'] = $feedItem->author->name;
- if(isset($feedItem->content)) $item['content'] = $feedItem->content;
- return $item;
- }
-
- protected function parseRSS_0_9_1_Item($feedItem){
- $item = array();
- if(isset($feedItem->link)) $item['uri'] = $feedItem->link;
- if(isset($feedItem->title)) $item['title'] = $feedItem->title;
- // rss 0.91 doesn't support timestamps
- // rss 0.91 doesn't support authors
- if(isset($feedItem->description)) $item['content'] = $feedItem->description;
- return $item;
- }
-
- protected function parseRSS_1_0_Item($feedItem){
- // 1.0 adds optional elements around the 0.91 standard
- $item = $this->parseRSS_0_9_1_Item($feedItem);
-
- $namespaces = $feedItem->getNamespaces(true);
- if(isset($namespaces['dc'])){
- $dc = $feedItem->children($namespaces['dc']);
- if(isset($dc->date)) $item['timestamp'] = strtotime($dc->date);
- if(isset($dc->creator)) $item['author'] = $dc->creator;
- }
-
- return $item;
- }
-
- protected function parseRSS_2_0_Item($feedItem){
- // Primary data is compatible to 0.91 with some additional data
- $item = $this->parseRSS_0_9_1_Item($feedItem);
-
- $namespaces = $feedItem->getNamespaces(true);
- if(isset($namespaces['dc'])) $dc = $feedItem->children($namespaces['dc']);
-
- if(isset($feedItem->pubDate)){
- $item['timestamp'] = strtotime($feedItem->pubDate);
- } elseif(isset($dc->date)){
- $item['timestamp'] = strtotime($dc->date);
- }
- if(isset($feedItem->author)){
- $item['author'] = $feedItem->author;
- } elseif(isset($dc->creator)){
- $item['author'] = $dc->creator;
- }
- return $item;
- }
-
- /**
- * Method should return, from a source RSS item given by lastRSS, one of our Items objects
- * @param $item the input rss item
- * @return a RSS-Bridge Item, with (hopefully) the whole content)
- */
- abstract protected function parseItem($item);
-
- public function getURI(){
- return $this->uri;
- }
-
- public function getName(){
- return $this->name;
- }
-
- public function getDescription(){
- return $this->description;
- }
+ private $name;
+ private $uri;
+ private $description;
+
+ public function collectExpandableDatas($url, $maxItems = -1){
+ if(empty($url)){
+ $this->returnServerError('There is no $url for this RSS expander');
+ }
+
+ $this->debugMessage('Loading from ' . $url);
+
+ /* Notice we do not use cache here on purpose:
+ * we want a fresh view of the RSS stream each time
+ */
+ $content = $this->getContents($url)
+ or $this->returnServerError('Could not request ' . $url);
+ $rssContent = simplexml_load_string($content);
+
+ $this->debugMessage('Detecting feed format/version');
+ if(isset($rssContent->channel[0])){
+ $this->debugMessage('Detected RSS format');
+ if(isset($rssContent->item[0])){
+ $this->debugMessage('Detected RSS 1.0 format');
+ $this->collect_RSS_1_0_data($rssContent, $maxItems);
+ } else {
+ $this->debugMessage('Detected RSS 0.9x or 2.0 format');
+ $this->collect_RSS_2_0_data($rssContent, $maxItems);
+ }
+ } elseif(isset($rssContent->entry[0])){
+ $this->debugMessage('Detected ATOM format');
+ $this->collect_ATOM_data($rssContent, $maxItems);
+ } else {
+ $this->debugMessage('Unknown feed format/version');
+ $this->returnServerError('The feed format is unknown!');
+ }
+ }
+
+ protected function collect_RSS_1_0_data($rssContent, $maxItems){
+ $this->load_RSS_2_0_feed_data($rssContent->channel[0]);
+ foreach($rssContent->item as $item){
+ $this->debugMessage('parsing item ' . var_export($item, true));
+ $this->items[] = $this->parseItem($item);
+ if($maxItems !== -1 && count($this->items) >= $maxItems) break;
+ }
+ }
+
+ protected function collect_RSS_2_0_data($rssContent, $maxItems){
+ $rssContent = $rssContent->channel[0];
+ $this->debugMessage('RSS content is ===========\n'
+ . var_export($rssContent, true)
+ . '===========');
+
+ $this->load_RSS_2_0_feed_data($rssContent);
+ foreach($rssContent->item as $item){
+ $this->debugMessage('parsing item ' . var_export($item, true));
+ $this->items[] = $this->parseItem($item);
+ if($maxItems !== -1 && count($this->items) >= $maxItems) break;
+ }
+ }
+
+ protected function collect_ATOM_data($content, $maxItems){
+ $this->load_ATOM_feed_data($content);
+ foreach($content->entry as $item){
+ $this->debugMessage('parsing item ' . var_export($item, true));
+ $this->items[] = $this->parseItem($item);
+ if($maxItems !== -1 && count($this->items) >= $maxItems) break;
+ }
+ }
+
+ protected function RSS_2_0_time_to_timestamp($item){
+ return DateTime::createFromFormat('D, d M Y H:i:s e', $item->pubDate)->getTimestamp();
+ }
+
+ // TODO set title, link, description, language, and so on
+ protected function load_RSS_2_0_feed_data($rssContent){
+ $this->name = trim($rssContent->title);
+ $this->uri = trim($rssContent->link);
+ $this->description = trim($rssContent->description);
+ }
+
+ protected function load_ATOM_feed_data($content){
+ $this->name = $content->title;
+
+ // Find best link (only one, or first of 'alternate')
+ if(!isset($content->link)){
+ $this->uri = '';
+ } elseif (count($content->link) === 1){
+ $this->uri = $content->link[0]['href'];
+ } else {
+ $this->uri = '';
+ foreach($content->link as $link){
+ if(strtolower($link['rel']) === 'alternate'){
+ $this->uri = $link['href'];
+ break;
+ }
+ }
+ }
+
+ if(isset($content->subtitle))
+ $this->description = $content->subtitle;
+ }
+
+ protected function parseATOMItem($feedItem){
+ $item = array();
+ if(isset($feedItem->id)) $item['uri'] = $feedItem->id;
+ if(isset($feedItem->title)) $item['title'] = $feedItem->title;
+ if(isset($feedItem->updated)) $item['timestamp'] = strtotime($feedItem->updated);
+ if(isset($feedItem->author)) $item['author'] = $feedItem->author->name;
+ if(isset($feedItem->content)) $item['content'] = $feedItem->content;
+ return $item;
+ }
+
+ protected function parseRSS_0_9_1_Item($feedItem){
+ $item = array();
+ if(isset($feedItem->link)) $item['uri'] = $feedItem->link;
+ if(isset($feedItem->title)) $item['title'] = $feedItem->title;
+ // rss 0.91 doesn't support timestamps
+ // rss 0.91 doesn't support authors
+ if(isset($feedItem->description)) $item['content'] = $feedItem->description;
+ return $item;
+ }
+
+ protected function parseRSS_1_0_Item($feedItem){
+ // 1.0 adds optional elements around the 0.91 standard
+ $item = $this->parseRSS_0_9_1_Item($feedItem);
+
+ $namespaces = $feedItem->getNamespaces(true);
+ if(isset($namespaces['dc'])){
+ $dc = $feedItem->children($namespaces['dc']);
+ if(isset($dc->date)) $item['timestamp'] = strtotime($dc->date);
+ if(isset($dc->creator)) $item['author'] = $dc->creator;
+ }
+
+ return $item;
+ }
+
+ protected function parseRSS_2_0_Item($feedItem){
+ // Primary data is compatible to 0.91 with some additional data
+ $item = $this->parseRSS_0_9_1_Item($feedItem);
+
+ $namespaces = $feedItem->getNamespaces(true);
+ if(isset($namespaces['dc'])) $dc = $feedItem->children($namespaces['dc']);
+
+ if(isset($feedItem->pubDate)){
+ $item['timestamp'] = strtotime($feedItem->pubDate);
+ } elseif(isset($dc->date)){
+ $item['timestamp'] = strtotime($dc->date);
+ }
+ if(isset($feedItem->author)){
+ $item['author'] = $feedItem->author;
+ } elseif(isset($dc->creator)){
+ $item['author'] = $dc->creator;
+ }
+ return $item;
+ }
+
+ /**
+ * Method should return, from a source RSS item given by lastRSS, one of our Items objects
+ * @param $item the input rss item
+ * @return a RSS-Bridge Item, with (hopefully) the whole content)
+ */
+ abstract protected function parseItem($item);
+
+ public function getURI(){
+ return $this->uri;
+ }
+
+ public function getName(){
+ return $this->name;
+ }
+
+ public function getDescription(){
+ return $this->description;
+ }
}
diff --git a/lib/Format.php b/lib/Format.php
index 618c0a30..182bf0be 100644
--- a/lib/Format.php
+++ b/lib/Format.php
@@ -1,72 +1,73 @@
<?php
require_once(__DIR__ . '/FormatInterface.php');
-class Format{
+class Format {
- static protected $dirFormat;
+ static protected $dirFormat;
- public function __construct(){
- throw new \LogicException('Please use ' . __CLASS__ . '::create for new object.');
- }
+ public function __construct(){
+ throw new \LogicException('Please use ' . __CLASS__ . '::create for new object.');
+ }
- static public function create($nameFormat){
- if( !preg_match('@^[A-Z][a-zA-Z]*$@', $nameFormat)){
- throw new \InvalidArgumentException('Name format must be at least one uppercase follow or not by alphabetic characters.');
- }
+ static public function create($nameFormat){
+ if(!preg_match('@^[A-Z][a-zA-Z]*$@', $nameFormat)){
+ throw new \InvalidArgumentException('Name format must be at least '
+ . 'one uppercase follow or not by alphabetic characters.');
+ }
- $nameFormat=$nameFormat.'Format';
- $pathFormat = self::getDir() . $nameFormat . '.php';
+ $nameFormat = $nameFormat . 'Format';
+ $pathFormat = self::getDir() . $nameFormat . '.php';
- if( !file_exists($pathFormat) ){
- throw new \Exception('The format you looking for does not exist.');
- }
+ if(!file_exists($pathFormat)){
+ throw new \Exception('The format you looking for does not exist.');
+ }
- require_once $pathFormat;
+ require_once $pathFormat;
- return new $nameFormat();
- }
+ return new $nameFormat();
+ }
- static public function setDir($dirFormat){
- if( !is_string($dirFormat) ){
- throw new \InvalidArgumentException('Dir format must be a string.');
- }
+ static public function setDir($dirFormat){
+ if(!is_string($dirFormat)){
+ throw new \InvalidArgumentException('Dir format must be a string.');
+ }
- if( !file_exists($dirFormat) ){
- throw new \Exception('Dir format does not exist.');
- }
+ if(!file_exists($dirFormat)){
+ throw new \Exception('Dir format does not exist.');
+ }
- self::$dirFormat = $dirFormat;
- }
+ self::$dirFormat = $dirFormat;
+ }
- static public function getDir(){
- $dirFormat = self::$dirFormat;
+ static public function getDir(){
+ $dirFormat = self::$dirFormat;
- if( is_null($dirFormat) ){
- throw new \LogicException(__CLASS__ . ' class need to know format path !');
- }
+ if(is_null($dirFormat)){
+ throw new \LogicException(__CLASS__ . ' class need to know format path !');
+ }
- return $dirFormat;
- }
+ return $dirFormat;
+ }
- /**
- * Read format dir and catch informations about each format depending annotation
- * @return array Informations about each format
- */
- static public function searchInformation(){
- $pathDirFormat = self::getDir();
+ /**
+ * Read format dir and catch informations about each format depending annotation
+ * @return array Informations about each format
+ */
+ static public function searchInformation(){
+ $pathDirFormat = self::getDir();
- $listFormat = array();
+ $listFormat = array();
- $searchCommonPattern = array('name');
+ $searchCommonPattern = array('name');
- $dirFiles = scandir($pathDirFormat);
- if( $dirFiles !== false ){
- foreach( $dirFiles as $fileName ){
- if( preg_match('@^([^.]+)Format\.php$@U', $fileName, $out) ){ // Is PHP file ?
- $listFormat[] = $out[1];
- }
- }
- }
+ $dirFiles = scandir($pathDirFormat);
+ if($dirFiles !== false){
+ foreach($dirFiles as $fileName){
+ if(preg_match('@^([^.]+)Format\.php$@U', $fileName, $out)){ // Is PHP file ?
+ $listFormat[] = $out[1];
+ }
+ }
+ }
- return $listFormat;
- }
+ return $listFormat;
+ }
}
diff --git a/lib/FormatAbstract.php b/lib/FormatAbstract.php
index e4a911c1..19629587 100644
--- a/lib/FormatAbstract.php
+++ b/lib/FormatAbstract.php
@@ -1,107 +1,107 @@
<?php
require_once(__DIR__ . '/FormatInterface.php');
-abstract class FormatAbstract implements FormatInterface{
- const DEFAULT_CHARSET = 'UTF-8';
-
- protected
- $contentType,
- $charset,
- $items,
- $extraInfos
- ;
-
- public function setCharset($charset){
- $this->charset = $charset;
-
- return $this;
- }
-
- public function getCharset(){
- $charset = $this->charset;
-
- return is_null($charset) ? self::DEFAULT_CHARSET : $charset;
- }
-
- protected function setContentType($contentType){
- $this->contentType = $contentType;
-
- return $this;
- }
-
- protected function callContentType(){
- header('Content-Type: ' . $this->contentType);
- }
-
- public function display(){
- echo $this->stringify();
-
- return $this;
- }
-
- public function setItems(array $items){
- $this->items = array_map(array($this, 'array_trim'), $items);
-
- return $this;
- }
-
- public function getItems(){
- if(!is_array($this->items))
- throw new \LogicException('Feed the ' . get_class($this) . ' with "setItems" method before !');
-
- return $this->items;
- }
-
- /**
- * Define common informations can be required by formats and set default value for unknow values
- * @param array $extraInfos array with know informations (there isn't merge !!!)
- * @return this
- */
- public function setExtraInfos(array $extraInfos = array()){
- foreach(array('name', 'uri') as $infoName){
- if( !isset($extraInfos[$infoName]) ){
- $extraInfos[$infoName] = '';
- }
- }
-
- $this->extraInfos = $extraInfos;
-
- return $this;
- }
-
- /**
- * Return extra infos
- * @return array See "setExtraInfos" detail method to know what extra are disponibles
- */
- public function getExtraInfos(){
- if( is_null($this->extraInfos) ){ // No extra info ?
- $this->setExtraInfos(); // Define with default value
- }
-
- return $this->extraInfos;
- }
-
- /**
- * Sanitized html while leaving it functionnal.
- * The aim is to keep html as-is (with clickable hyperlinks)
- * while reducing annoying and potentially dangerous things.
- * Yes, I know sanitizing HTML 100% is an impossible task.
- * Maybe we'll switch to http://htmlpurifier.org/
- * or http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/index.php
- */
- protected function sanitizeHtml($html)
- {
- $html = str_replace('<script','<&zwnj;script',$html); // Disable scripts, but leave them visible.
- $html = str_replace('<iframe','<&zwnj;iframe',$html);
- $html = str_replace('<link','<&zwnj;link',$html);
- // We leave alone object and embed so that videos can play in RSS readers.
- return $html;
- }
-
- protected function array_trim($elements){
- foreach($elements as $key => $value){
- if(is_string($value))
- $elements[$key] = trim($value);
- }
- return $elements;
- }
+abstract class FormatAbstract implements FormatInterface {
+ const DEFAULT_CHARSET = 'UTF-8';
+
+ protected
+ $contentType,
+ $charset,
+ $items,
+ $extraInfos
+ ;
+
+ public function setCharset($charset){
+ $this->charset = $charset;
+
+ return $this;
+ }
+
+ public function getCharset(){
+ $charset = $this->charset;
+
+ return is_null($charset) ? self::DEFAULT_CHARSET : $charset;
+ }
+
+ protected function setContentType($contentType){
+ $this->contentType = $contentType;
+
+ return $this;
+ }
+
+ protected function callContentType(){
+ header('Content-Type: ' . $this->contentType);
+ }
+
+ public function display(){
+ echo $this->stringify();
+
+ return $this;
+ }
+
+ public function setItems(array $items){
+ $this->items = array_map(array($this, 'array_trim'), $items);
+
+ return $this;
+ }
+
+ public function getItems(){
+ if(!is_array($this->items))
+ throw new \LogicException('Feed the ' . get_class($this) . ' with "setItems" method before !');
+
+ return $this->items;
+ }
+
+ /**
+ * Define common informations can be required by formats and set default value for unknow values
+ * @param array $extraInfos array with know informations (there isn't merge !!!)
+ * @return this
+ */
+ public function setExtraInfos(array $extraInfos = array()){
+ foreach(array('name', 'uri') as $infoName){
+ if( !isset($extraInfos[$infoName]) ){
+ $extraInfos[$infoName] = '';
+ }
+ }
+
+ $this->extraInfos = $extraInfos;
+
+ return $this;
+ }
+
+ /**
+ * Return extra infos
+ * @return array See "setExtraInfos" detail method to know what extra are disponibles
+ */
+ public function getExtraInfos(){
+ if( is_null($this->extraInfos) ){ // No extra info ?
+ $this->setExtraInfos(); // Define with default value
+ }
+
+ return $this->extraInfos;
+ }
+
+ /**
+ * Sanitized html while leaving it functionnal.
+ * The aim is to keep html as-is (with clickable hyperlinks)
+ * while reducing annoying and potentially dangerous things.
+ * Yes, I know sanitizing HTML 100% is an impossible task.
+ * Maybe we'll switch to http://htmlpurifier.org/
+ * or http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/index.php
+ */
+ protected function sanitizeHtml($html)
+ {
+ $html = str_replace('<script','<&zwnj;script',$html); // Disable scripts, but leave them visible.
+ $html = str_replace('<iframe','<&zwnj;iframe',$html);
+ $html = str_replace('<link','<&zwnj;link',$html);
+ // We leave alone object and embed so that videos can play in RSS readers.
+ return $html;
+ }
+
+ protected function array_trim($elements){
+ foreach($elements as $key => $value){
+ if(is_string($value))
+ $elements[$key] = trim($value);
+ }
+ return $elements;
+ }
}
diff --git a/lib/FormatInterface.php b/lib/FormatInterface.php
index ea0cf233..2fac3fcc 100644
--- a/lib/FormatInterface.php
+++ b/lib/FormatInterface.php
@@ -1,6 +1,6 @@
<?php
interface FormatInterface{
- public function stringify();
- public function display();
- public function setItems(array $bridges);
+ public function stringify();
+ public function display();
+ public function setItems(array $bridges);
}
diff --git a/lib/HTMLUtils.php b/lib/HTMLUtils.php
index 7e0061d4..e2e582f3 100644
--- a/lib/HTMLUtils.php
+++ b/lib/HTMLUtils.php
@@ -1,9 +1,8 @@
<?php
class HTMLUtils {
-
public static function displayBridgeCard($bridgeName, $formats, $isActive = true){
$bridgeElement = Bridge::create($bridgeName);
- $bridgeClass=$bridgeName.'Bridge';
+ $bridgeClass = $bridgeName . 'Bridge';
if($bridgeElement == false)
return "";
@@ -22,15 +21,30 @@ class HTMLUtils {
CARD;
// If we don't have any parameter for the bridge, we print a generic form to load it.
- if(count($bridgeClass::PARAMETERS) == 0) {
+ if(count($bridgeClass::PARAMETERS) == 0){
$card .= HTMLUtils::getFormHeader($bridgeName);
- if ($isActive){
+ if($isActive){
if(defined('PROXY_URL') && PROXY_BYBRIDGE){
- $idArg = 'arg-' . urlencode($bridgeName) . '-' . urlencode('proxyoff') . '-' . urlencode('_noproxy');
- $card .= '<input id="' . $idArg . '" type="checkbox" name="_noproxy" />' . PHP_EOL;
- $card .= '<label for="' .$idArg. '">Disable proxy ('.((defined('PROXY_NAME') && PROXY_NAME)?PROXY_NAME:PROXY_URL).')</label><br />' . PHP_EOL;
+ $idArg = 'arg-'
+ . urlencode($bridgeName)
+ . '-'
+ . urlencode('proxyoff')
+ . '-'
+ . urlencode('_noproxy');
+
+ $card .= '<input id="'
+ . $idArg
+ . '" type="checkbox" name="_noproxy" />'
+ . PHP_EOL;
+
+ $card .= '<label for="'
+ . $idArg
+ . '">Disable proxy ('
+ . ((defined('PROXY_NAME') && PROXY_NAME) ? PROXY_NAME : PROXY_URL)
+ . ')</label><br />'
+ . PHP_EOL;
}
$card .= HTMLUtils::getHelperButtonsFormat($formats);
@@ -59,7 +73,7 @@ CARD;
$card .= HTMLUtils::getFormHeader($bridgeName);
- foreach($parameter as $id=>$inputEntry) {
+ foreach($parameter as $id=>$inputEntry){
$additionalInfoString = '';
if(isset($inputEntry['required']) && $inputEntry['required'] === true)
@@ -77,55 +91,140 @@ CARD;
if(!isset($inputEntry['defaultValue']))
$inputEntry['defaultValue'] = '';
- $idArg = 'arg-' . urlencode($bridgeName) . '-' . urlencode($parameterName) . '-' . urlencode($id);
- $card .= '<label for="' . $idArg . '">' . $inputEntry['name'] . ' : </label>' . PHP_EOL;
-
- if(!isset($inputEntry['type']) || $inputEntry['type'] == 'text') {
- $card .= '<input ' . $additionalInfoString . ' id="' . $idArg . '" type="text" value="' . $inputEntry['defaultValue'] . '" placeholder="' . $inputEntry['exampleValue'] . '" name="' . $id . '" /><br />' . PHP_EOL;
- } else if($inputEntry['type'] == 'number') {
- $card .= '<input ' . $additionalInfoString . ' id="' . $idArg . '" type="number" value="' . $inputEntry['defaultValue'] . '" placeholder="' . $inputEntry['exampleValue'] . '" name="' . $id . '" /><br />' . PHP_EOL;
- } else if($inputEntry['type'] == 'list') {
- $card .= '<select ' . $additionalInfoString . ' id="' . $idArg . '" name="' . $id . '" >';
-
- foreach($inputEntry['values'] as $name=>$value) {
- if(is_array($value)){
- $card.='<optgroup label="'.htmlentities($name).'">';
- foreach($value as $subname=>$subvalue){
- if($inputEntry['defaultValue'] === $subname || $inputEntry['defaultValue'] === $subvalue)
- $card .= '<option value="' . $subvalue . '" selected>' . $subname . '</option>';
- else
- $card .= '<option value="' . $subvalue . '">' . $subname . '</option>';
- }
- $card.='</optgroup>';
- }else{
- if($inputEntry['defaultValue'] === $name || $inputEntry['defaultValue'] === $value)
- $card .= '<option value="' . $value . '" selected>' . $name . '</option>';
- else
- $card .= '<option value="' . $value . '">' . $name . '</option>';
- }
- }
-
+ $idArg = 'arg-'
+ . urlencode($bridgeName)
+ . '-'
+ . urlencode($parameterName)
+ . '-'
+ . urlencode($id);
+
+ $card .= '<label for="'
+ . $idArg
+ . '">'
+ . $inputEntry['name']
+ . ' : </label>'
+ . PHP_EOL;
+
+ if(!isset($inputEntry['type']) || $inputEntry['type'] == 'text'){
+ $card .= '<input '
+ . $additionalInfoString
+ . ' id="'
+ . $idArg
+ . '" type="text" value="'
+ . $inputEntry['defaultValue']
+ . '" placeholder="'
+ . $inputEntry['exampleValue']
+ . '" name="'
+ . $id
+ . '" /><br />'
+ . PHP_EOL;
+ } elseif($inputEntry['type'] == 'number'){
+ $card .= '<input '
+ . $additionalInfoString
+ . ' id="'
+ . $idArg
+ . '" type="number" value="'
+ . $inputEntry['defaultValue']
+ . '" placeholder="'
+ . $inputEntry['exampleValue']
+ . '" name="'
+ . $id
+ . '" /><br />'
+ . PHP_EOL;
+ } else if($inputEntry['type'] == 'list'){
+ $card .= '<select '
+ . $additionalInfoString
+ . ' id="'
+ . $idArg
+ . '" name="'
+ . $id
+ . '" >';
+
+ foreach($inputEntry['values'] as $name => $value){
+ if(is_array($value)){
+ $card .= '<optgroup label="' . htmlentities($name) . '">';
+ foreach($value as $subname => $subvalue){
+ if($inputEntry['defaultValue'] === $subname
+ || $inputEntry['defaultValue'] === $subvalue){
+ $card .= '<option value="'
+ . $subvalue
+ . '" selected>'
+ . $subname
+ . '</option>';
+ } else {
+ $card .= '<option value="'
+ . $subvalue
+ . '">'
+ . $subname
+ . '</option>';
+ }
+ }
+ $card .= '</optgroup>';
+ } else {
+ if($inputEntry['defaultValue'] === $name
+ || $inputEntry['defaultValue'] === $value){
+ $card .= '<option value="'
+ . $value
+ . '" selected>'
+ . $name
+ . '</option>';
+ } else {
+ $card .= '<option value="'
+ . $value
+ . '">'
+ . $name
+ . '</option>';
+ }
+ }
+ }
$card .= '</select><br >';
- } else if($inputEntry['type'] == 'checkbox') {
+ } elseif($inputEntry['type'] == 'checkbox'){
if($inputEntry['defaultValue'] === 'checked')
- $card .= '<input ' . $additionalInfoString . ' id="' . $idArg . '" type="checkbox" name="' . $id . '" checked /><br />' . PHP_EOL;
+ $card .= '<input '
+ . $additionalInfoString
+ . ' id="'
+ . $idArg
+ . '" type="checkbox" name="'
+ . $id
+ . '" checked /><br />'
+ . PHP_EOL;
else
- $card .= '<input ' . $additionalInfoString . ' id="' . $idArg . '" type="checkbox" name="' . $id . '" /><br />' . PHP_EOL;
+ $card .= '<input '
+ . $additionalInfoString
+ . ' id="'
+ . $idArg
+ . '" type="checkbox" name="'
+ . $id
+ . '" /><br />'
+ . PHP_EOL;
}
}
- if ($isActive){
+ if($isActive){
if(defined('PROXY_URL') && PROXY_BYBRIDGE){
- $idArg = 'arg-' . urlencode($bridgeName) . '-' . urlencode('proxyoff') . '-' . urlencode('_noproxy');
- $card .= '<input id="' . $idArg . '" type="checkbox" name="_noproxy" />' . PHP_EOL;
- $card .= '<label for="' .$idArg. '">Disable proxy ('.((defined('PROXY_NAME') && PROXY_NAME)?PROXY_NAME:PROXY_URL).')</label><br />' . PHP_EOL;
+ $idArg = 'arg-'
+ . urlencode($bridgeName)
+ . '-'
+ . urlencode('proxyoff')
+ . '-'
+ . urlencode('_noproxy');
+
+ $card .= '<input id="'
+ . $idArg
+ . '" type="checkbox" name="_noproxy" />'
+ . PHP_EOL;
+
+ $card .= '<label for="'
+ . $idArg
+ . '">Disable proxy ('
+ . ((defined('PROXY_NAME') && PROXY_NAME) ? PROXY_NAME : PROXY_URL)
+ . ')</label><br />'
+ . PHP_EOL;
}
-
$card .= HTMLUtils::getHelperButtonsFormat($formats);
} else {
$card .= '<span style="font-weight: bold;">Inactive</span>';
}
-
$card .= '</form>' . PHP_EOL;
}
@@ -138,8 +237,13 @@ CARD;
private static function getHelperButtonsFormat($formats){
$buttons = '';
- foreach( $formats as $name){
- $buttons .= '<button type="submit" name="format" value="' . $name . '">' . $name . '</button>' . PHP_EOL;
+ foreach($formats as $name){
+ $buttons .= '<button type="submit" name="format" value="'
+ . $name
+ . '">'
+ . $name
+ . '</button>'
+ . PHP_EOL;
}
return $buttons;
@@ -164,22 +268,24 @@ class HTMLSanitizer {
public static $KEPT_ATTRIBUTES = ["title", "href", "src"];
public static $ONLY_TEXT = [];
- public function __construct($tags_to_remove = null, $kept_attributes = null, $only_keep_text = null) {
- $this->tagsToRemove = $tags_to_remove == null ? HTMLSanitizer::$DEFAULT_CLEAR_TAGS : $tags_to_remove;
- $this->keptAttributes = $kept_attributes == null ? HTMLSanitizer::$KEPT_ATTRIBUTES : $kept_attributes;
- $this->onlyKeepText = $only_keep_text == null ? HTMLSanitizer::$ONLY_TEXT : $only_keep_text;
+ public function __construct($tags_to_remove = null
+ , $kept_attributes = null
+ , $only_keep_text = null){
+ $this->tagsToRemove = is_null($tags_to_remove) ? HTMLSanitizer::$DEFAULT_CLEAR_TAGS : $tags_to_remove;
+ $this->keptAttributes = is_null($kept_attributes) ? HTMLSanitizer::$KEPT_ATTRIBUTES : $kept_attributes;
+ $this->onlyKeepText = is_null($only_keep_text) ? HTMLSanitizer::$ONLY_TEXT : $only_keep_text;
}
- public function sanitize($textToSanitize) {
+ public function sanitize($textToSanitize){
$htmlContent = str_get_html($textToSanitize);
- foreach($htmlContent->find('*[!b38fd2b1fe7f4747d6b1c1254ccd055e]') as $element) {
- if(in_array($element->tag, $this->onlyKeepText)) {
+ foreach($htmlContent->find('*[!b38fd2b1fe7f4747d6b1c1254ccd055e]') as $element){
+ if(in_array($element->tag, $this->onlyKeepText)){
$element->outertext = $element->plaintext;
- } else if(in_array($element->tag, $this->tagsToRemove)) {
+ } elseif(in_array($element->tag, $this->tagsToRemove)){
$element->outertext = '';
} else {
- foreach($element->getAllAttributes() as $attributeName => $attribute) {
+ foreach($element->getAllAttributes() as $attributeName => $attribute){
if(!in_array($attributeName, $this->keptAttributes))
$element->removeAttribute($attributeName);
}
@@ -189,10 +295,12 @@ class HTMLSanitizer {
return $htmlContent;
}
- public static function defaultImageSrcTo($content, $server) {
- foreach($content->find('img') as $image) {
- if(strpos($image->src, "http") == NULL && strpos($image->src, "//") == NULL && strpos($image->src, "data:") == NULL)
- $image->src = $server.$image->src;
+ public static function defaultImageSrcTo($content, $server){
+ foreach($content->find('img') as $image){
+ if(is_null(strpos($image->src, "http"))
+ && is_null(strpos($image->src, "//"))
+ && is_null(strpos($image->src, "data:")))
+ $image->src = $server . $image->src;
}
return $content;
}
diff --git a/lib/RssBridge.php b/lib/RssBridge.php
index 07286831..d7ef70f2 100644
--- a/lib/RssBridge.php
+++ b/lib/RssBridge.php
@@ -19,28 +19,33 @@ require __DIR__ . '/HTMLUtils.php';
$vendorLibSimpleHtmlDom = __DIR__ . PATH_VENDOR . '/simplehtmldom/simple_html_dom.php';
if( !file_exists($vendorLibSimpleHtmlDom) ){
- throw new \HttpException('"PHP Simple HTML DOM Parser" library is missing. Get it from http://simplehtmldom.sourceforge.net and place the script "simple_html_dom.php" in '.substr(PATH_VENDOR,4) . '/simplehtmldom/', 500);
+ throw new \HttpException('"PHP Simple HTML DOM Parser" library is missing.'
+ . ' Get it from http://simplehtmldom.sourceforge.net and place the script'
+ . ' "simple_html_dom.php" in '
+ . substr(PATH_VENDOR,4)
+ . '/simplehtmldom/'
+ , 500);
}
require_once $vendorLibSimpleHtmlDom;
/* Example use
-
- require_once __DIR__ . '/lib/RssBridge.php';
-
- // Data retrieval
- Bridge::setDir(__DIR__ . '/bridges/');
- $bridge = Bridge::create('GoogleSearch');
- $bridge->collectData($_REQUEST);
-
- // Data transformation
- Format::setDir(__DIR__ . '/formats/');
- $format = Format::create('Atom');
- $format
- ->setItems($bridge->getItems())
- ->setExtraInfos(array(
- 'name' => $bridge->getName(),
- 'uri' => $bridge->getURI(),
- ))
- ->display();
+
+ require_once __DIR__ . '/lib/RssBridge.php';
+
+ // Data retrieval
+ Bridge::setDir(__DIR__ . '/bridges/');
+ $bridge = Bridge::create('GoogleSearch');
+ $bridge->collectData($_REQUEST);
+
+ // Data transformation
+ Format::setDir(__DIR__ . '/formats/');
+ $format = Format::create('Atom');
+ $format
+ ->setItems($bridge->getItems())
+ ->setExtraInfos(array(
+ 'name' => $bridge->getName(),
+ 'uri' => $bridge->getURI(),
+ ))
+ ->display();
*/