1
0
Selaa lähdekoodia

[core] Apply common indentation

All files are now using tabs for indentation
logmanoriginal 7 vuotta sitten
vanhempi
commit
62eec43980

+ 74 - 79
caches/FileCache.php

@@ -2,93 +2,88 @@
 /**
 /**
 * Cache with file system
 * 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
 <?php
 /**
 /**
 * Atom
 * 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{
 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;
 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">
 <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}
 {$entries}
 </feed>
 </feed>
 EOD;
 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
 <?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">
 <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>
 </section>
 
 
 EOD;
 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>
 <!DOCTYPE html>
 <html>
 <html>
 <head>
 <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>
 </head>
 <body>
 <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}
 {$entries}
 </body>
 </body>
 </html>
 </html>
 EOD;
 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
 * Json
 * Builds a JSON string from $this->items and return it to browser.
 * 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
 * Mrss
 * Documentation Source http://www.rssboard.org/media-rss
 * 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;
 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">
 <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>
 </rss>
 EOD;
 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
 * Plaintext
 * Returns $this->items as raw php data.
 * 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');
 require_once(__DIR__ . '/BridgeInterface.php');
 class Bridge {
 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
 'nameBridge' must start with one uppercase character followed or not by
 alphanumeric or dash characters!
 alphanumeric or dash characters!
 EOD;
 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');
 require_once(__DIR__ . '/BridgeInterface.php');
 abstract class BridgeAbstract implements BridgeInterface {
 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
 <?php
 interface BridgeInterface {
 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
 <?php
 require_once(__DIR__ . '/CacheInterface.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';
 		$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
 <?php
 require_once(__DIR__ . '/CacheInterface.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
 <?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{
 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');
 require_once(__DIR__ . '/BridgeInterface.php');
 abstract class FeedExpander extends BridgeAbstract {
 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
 <?php
 require_once(__DIR__ . '/FormatInterface.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
 <?php
 require_once(__DIR__ . '/FormatInterface.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
 <?php
 interface FormatInterface{
 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
 <?php
 class HTMLUtils {
 class HTMLUtils {
-
 	public static function displayBridgeCard($bridgeName, $formats, $isActive = true){
 	public static function displayBridgeCard($bridgeName, $formats, $isActive = true){
 		$bridgeElement = Bridge::create($bridgeName);
 		$bridgeElement = Bridge::create($bridgeName);
-        $bridgeClass=$bridgeName.'Bridge';
+		$bridgeClass = $bridgeName . 'Bridge';
 
 
 		if($bridgeElement == false)
 		if($bridgeElement == false)
 			return "";
 			return "";
@@ -22,15 +21,30 @@ class HTMLUtils {
 CARD;
 CARD;
 
 
 		// If we don't have any parameter for the bridge, we print a generic form to load it.
 		// 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);
 			$card .= HTMLUtils::getFormHeader($bridgeName);
 
 
-			if ($isActive){
+			if($isActive){
 				if(defined('PROXY_URL') && PROXY_BYBRIDGE){
 				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);
 				$card .= HTMLUtils::getHelperButtonsFormat($formats);
@@ -59,7 +73,7 @@ CARD;
 
 
 			$card .= HTMLUtils::getFormHeader($bridgeName);
 			$card .= HTMLUtils::getFormHeader($bridgeName);
 
 
-			foreach($parameter as $id=>$inputEntry) {
+			foreach($parameter as $id=>$inputEntry){
 				$additionalInfoString = '';
 				$additionalInfoString = '';
 
 
 				if(isset($inputEntry['required']) && $inputEntry['required'] === true)
 				if(isset($inputEntry['required']) && $inputEntry['required'] === true)
@@ -77,55 +91,140 @@ CARD;
 				if(!isset($inputEntry['defaultValue']))
 				if(!isset($inputEntry['defaultValue']))
 					$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 >';
 					$card .= '</select><br >';
-				} else if($inputEntry['type'] == 'checkbox') {
+				} elseif($inputEntry['type'] == 'checkbox'){
 					if($inputEntry['defaultValue'] === 'checked')
 					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
 					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){
 				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);
 				$card .= HTMLUtils::getHelperButtonsFormat($formats);
 			} else {
 			} else {
 				$card .= '<span style="font-weight: bold;">Inactive</span>';
 				$card .= '<span style="font-weight: bold;">Inactive</span>';
 			}
 			}
-
 			$card .= '</form>' . PHP_EOL;
 			$card .= '</form>' . PHP_EOL;
 		}
 		}
 
 
@@ -138,8 +237,13 @@ CARD;
 
 
 	private static function getHelperButtonsFormat($formats){
 	private static function getHelperButtonsFormat($formats){
 		$buttons = '';
 		$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;
 		return $buttons;
@@ -164,22 +268,24 @@ class HTMLSanitizer {
 	public static $KEPT_ATTRIBUTES = ["title", "href", "src"];
 	public static $KEPT_ATTRIBUTES = ["title", "href", "src"];
 	public static $ONLY_TEXT = [];
 	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);
 		$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;
 				$element->outertext = $element->plaintext;
-			} else if(in_array($element->tag, $this->tagsToRemove)) {
+			} elseif(in_array($element->tag, $this->tagsToRemove)){
 				$element->outertext = '';
 				$element->outertext = '';
 			} else {
 			} else {
-				foreach($element->getAllAttributes() as $attributeName => $attribute) {
+				foreach($element->getAllAttributes() as $attributeName => $attribute){
 					if(!in_array($attributeName, $this->keptAttributes))
 					if(!in_array($attributeName, $this->keptAttributes))
 						$element->removeAttribute($attributeName);
 						$element->removeAttribute($attributeName);
 				}
 				}
@@ -189,10 +295,12 @@ class HTMLSanitizer {
 		return $htmlContent;
 		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;
 		return $content;
 	}
 	}

+ 24 - 19
lib/RssBridge.php

@@ -19,28 +19,33 @@ require __DIR__ . '/HTMLUtils.php';
 
 
 $vendorLibSimpleHtmlDom = __DIR__ . PATH_VENDOR . '/simplehtmldom/simple_html_dom.php';
 $vendorLibSimpleHtmlDom = __DIR__ . PATH_VENDOR . '/simplehtmldom/simple_html_dom.php';
 if( !file_exists($vendorLibSimpleHtmlDom) ){
 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;
 require_once $vendorLibSimpleHtmlDom;
 
 
 /* Example use
 /* 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();
 
 
 */
 */