Przeglądaj źródła

[core] Apply common indentation

All files are now using tabs for indentation
logmanoriginal 7 lat temu
rodzic
commit
62eec43980

+ 74 - 79
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';
+	}
 }

+ 57 - 56
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);
+	}
 }

+ 42 - 43
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();
+	}
 }

+ 11 - 12
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();
+	}
 }

+ 53 - 53
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);
+	}
 }

+ 12 - 12
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();
-    }
-}
+		return parent::display();
+	}
+}

+ 98 - 96
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;
+		}
+	}
 }

+ 441 - 440
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);
+	}
 }

+ 4 - 4
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();
 }

+ 68 - 66
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());
+				}
+			}
 		}
 	}
 

+ 6 - 6
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;
+	}
 }

+ 4 - 4
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();
 }

+ 48 - 49
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',
+		);
+	}
 }

+ 174 - 171
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;
+	}
 }

+ 52 - 51
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;
+	}
 }

+ 104 - 104
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;
+	}
 }

+ 3 - 3
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);
 }

+ 168 - 60
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;
 	}

+ 24 - 19
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();
 
 */