'http://foo.bar', 'title'=>'My beautiful foobar', 'content'='Hello, world !','timestamp'=>'1375864834'), * Array('uri'=>'http://toto.com', 'title'=>'Welcome to toto', 'content'='What is this website about ?','timestamp'=>'1375868313') * ) * Keys in dictionnaries: * uri (string;mandatory) = The URI the item points to. * title (string;mandatory) = Title of item * content (string;optionnal) = item content (usually HTML code) * timestamp (string;optionnal) = item date. Must be in EPOCH format. * Other keys can be added, but will be ignored. * $items will be used to build the ATOM feed, json and other outputs. */ var $items; private $contentType; // MIME type returned to browser. /** * Sets the content-type returns to browser. * Example: $this->setContentType('text/html; charset=UTF-8') */ private function setContentType($value) { $this->contentType = $value; header('Content-Type: '.$value); } /** * collectData() will be called to ask the bridge to go collect data on the net. * All derived classes must implement this method. * This method must fill $this->items with collected items. * Input: $request : The incoming request (=$_GET). This can be used or ignored by the bridge. */ abstract protected function collectData($request); /** * Returns a HTTP error to user, with a message. * Example: $this->returnError('404 Not Found', 'ERROR: no results.'); */ protected function returnError($code, $message) { header("HTTP/1.1 $code"); header('Content-Type: text/plain;charset=UTF-8'); die($message); } /** * Builds an ATOM feed from $this->items and return it to browser. */ private function returnATOM() { $this->setContentType('application/atom+xml; charset=UTF-8'); echo ''."\n"; echo ''.htmlspecialchars($this->bridgeName).''."\n"; echo 'http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '')."://{$_SERVER['HTTP_HOST']}{$_SERVER['PATH_INFO']}".'/'."\n"; echo ''."\n"; // FIXME echo ''."\n"; echo ''."\n"."\n"; foreach($this->items as $item) { echo ''.htmlspecialchars($this->bridgeName).''.htmlspecialchars($this->bridgeURI).''."\n"; echo '<![CDATA['.$item['title'].']]>'."\n"; echo ''."\n"; echo ''.$item['uri'].''."\n"; if (isset($item['timestamp'])) { echo ''.date(DATE_ATOM, $item['timestamp']).''."\n"; } else { echo ''."\n"; } if (isset($item['content'])) { echo ''."\n"; } else { echo ''."\n"; } // FIXME: Security: Disable Javascript ? echo ''."\n\n"; } echo ''; } private function returnHTML() { $this->setContentType('text/html; charset=UTF-8'); echo ''.htmlspecialchars($this->bridgeName).''; echo ''; echo '

'.htmlspecialchars($this->bridgeName).'

'; foreach($this->items as $item) { echo '

'.htmlspecialchars(strip_tags($item['title'])).'

'; if (isset($item['timestamp'])) { echo ''.date(DATE_ATOM, $item['timestamp']).''; } if (isset($item['content'])) { echo '

'.$item['content'].'

'; } echo "
\n\n"; } echo ''; } /** * Builds a JSON string from $this->items and return it to browser. */ private function returnJSON() { $this->setContentType('application/json'); echo json_encode($this->items); } /** * Returns $this->items as raw php data. */ private function returnPlaintext() { $this->setContentType('text/plain;charset=UTF-8'); print_r($this->items); } /** * Start processing request and return response to browser. */ public function process() { $this->serveCachedVersion(); // Cache file does not exists or has expired: We re-fetch the results and cache it. $this->collectData($_GET); if (empty($this->items)) { $this->returnError('404 Not Found', 'ERROR: no results.'); } $format = 'atom'; if (!empty($_GET['format'])) { $format = $_GET['format']; } switch($format) { case 'plaintext': $this->returnPlaintext(); break; case 'json': $this->returnJSON(); break; case 'html': $this->returnHTML(); break; default: $this->returnATOM(); } $this->storeReponseInCache(); } /** * Returns the cached version of current request URI directly to the browser * if it exists and if cache has not expired. * Continues execution no cached version available. */ private function serveCachedVersion() { // See if cache exists for this request $cachefile = CACHEDIR.hash('sha1',$_SERVER['REQUEST_URI']).'.cache'; // Cache path and filename if (file_exists($cachefile)) { // The cache file exists. if (time() - ($this->cacheDuration*60) < filemtime($cachefile)) { // Cache file has not expired. Serve it. $data = json_decode(file_get_contents($cachefile),true); header('Content-Type: '.$data['Content-Type']); // Send proper MIME Type header('X-Cached-Version: '.date(DATE_ATOM, filemtime($cachefile))); echo $data['data']; exit(); } } } /** * Stores currently generated page in cache. */ private function storeReponseInCache() { $cachefile = CACHEDIR.hash('sha1',$_SERVER['REQUEST_URI']).'.cache'; // Cache path and filename $data = Array('data'=>ob_get_contents(), 'Content-Type'=>$this->contentType); file_put_contents($cachefile,json_encode($data)); ob_end_flush(); } } ?>