| [ Index ] |
|
Code source de Serendipity 1.2 |
1 <?php 2 3 /* Copyright 2002-2003 Edward Swindelles (ed@readinged.com) 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 if (!defined('ONYX_RSS_VERS')) 21 { 22 define('ONYX_RSS_VERS', '1.0'); 23 define('ONYX_ERR_NO_PARSER', '<a href="http://www.php.net/manual/en/ref.xml.php">PHP\'s XML Extension</a> is not loaded or available.'); 24 define('ONYX_ERR_NOT_WRITEABLE', 'The specified cache directory is not writeable.'); 25 define('ONYX_ERR_INVALID_URI', 'The specified file could not be opened.'); 26 define('ONYX_ERR_INVALID_ITEM', 'Invalid item index specified.'); 27 define('ONYX_ERR_NO_STREAM', 'Could not open the specified file. Check the path, and make sure that you have write permissions to this file.'); 28 define('ONYX_META', 'meta'); 29 define('ONYX_ITEMS', 'items'); 30 define('ONYX_IMAGE', 'image'); 31 define('ONYX_TEXTINPUT', 'textinput'); 32 define('ONYX_NAMESPACES', 'namespaces'); 33 define('ONYX_CACHE_AGE', 'cache_age'); 34 define('ONYX_FETCH_ASSOC', 1); 35 define('ONYX_FETCH_OBJECT', 2); 36 } 37 38 class ONYX_RSS 39 { 40 var $parser; 41 var $conf; 42 var $rss; 43 var $data; 44 var $type; 45 /* For when PHP v.5 is released 46 * http://www.phpvolcano.com/eide/php5.php?page=variables 47 * private $parser; 48 * private $conf; 49 * private $rss; 50 * private $data; 51 * private $type; 52 */ 53 54 function ONYX_RSS($charset = 'UTF-8') 55 { 56 $this->__construct($charset); 57 } 58 59 // Forward compatibility with PHP v.5 60 // http://www.phpvolcano.com/eide/php5.php?page=start 61 function __construct($charset = 'UTF-8') 62 { 63 $this->conf = array(); 64 $this->conf['error'] = '<br /><strong>Error on line %s of '.__FILE__.'</strong>: %s<br />'; 65 $this->conf['cache_path'] = dirname(__FILE__); 66 $this->conf['cache_time'] = 180; 67 $this->conf['debug_mode'] = true; 68 $this->conf['fetch_mode'] = ONYX_FETCH_ASSOC; 69 70 if (!function_exists('xml_parser_create')) 71 { 72 $this->raiseError((__LINE__-2), ONYX_ERR_NO_PARSER); 73 return false; 74 } 75 76 if ($charset == 'native') { 77 $charset = LANG_CHARSET; 78 } 79 $this->parser = @xml_parser_create($charset); 80 if (!is_resource($this->parser)) 81 { 82 $this->raiseError((__LINE__-3), ONYX_ERR_NO_PARSER); 83 return false; 84 } 85 xml_set_object($this->parser, $this); 86 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false); 87 @xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, LANG_CHARSET); 88 xml_set_element_handler($this->parser, 'tag_open', 'tag_close'); 89 xml_set_character_data_handler($this->parser, 'cdata'); 90 } 91 92 function parse($uri, $file=false, $time=false, $local=false) 93 { 94 $this->rss = array(); 95 $this->rss['cache_age'] = 0; 96 $this->rss['current_tag'] = ''; 97 $this->rss['index'] = 0; 98 $this->rss['output_index'] = -1; 99 $this->data = array(); 100 101 if ($file) 102 { 103 if (!is_writeable($this->conf['cache_path'])) 104 { 105 $this->raiseError((__LINE__-2), ONYX_ERR_NOT_WRITEABLE); 106 return false; 107 } 108 $file = str_replace('//', '/', $this->conf['cache_path'].'/'.$file); 109 if (!$time) 110 $time = $this->conf['cache_time']; 111 $this->rss['cache_age'] = file_exists($file) ? ceil((time() - filemtime($file)) / 60) : 0; 112 113 clearstatcache(); 114 if (!$local && file_exists($file)) 115 if (($mod = $this->mod_time($uri)) === false) 116 { 117 $this->raiseError((__LINE__-2), ONYX_ERR_INVALID_URI); 118 return false; 119 } 120 else 121 $mod = ($mod !== 0) ? strtotime($mod) : (time()+3600); 122 elseif ($local) 123 $mod = (file_exists($file) && ($m = filemtime($uri))) ? $m : time()+3600; 124 } 125 if ( !$file || 126 ($file && !file_exists($file)) || 127 ($file && file_exists($file) && $time <= $this->rss['cache_age'] && $mod >= (time() - ($this->rss['cache_age'] * 60)))) 128 { 129 clearstatcache(); 130 131 require_once S9Y_PEAR_PATH . 'HTTP/Request.php'; 132 serendipity_request_start(); 133 $req = &new HTTP_Request($uri, array('allowRedirects' => true, 'maxRedirects' => 5)); 134 $res = $req->sendRequest(); 135 136 if (PEAR::isError($res) || $req->getResponseCode() != '200') 137 { 138 serendipity_request_end(); 139 $this->raiseError((__LINE__-2), ONYX_ERR_INVALID_URI . ' (#' . $req->getResponseCode() . ')'); 140 return false; 141 } 142 143 $fContent = $req->getResponseBody(); 144 serendipity_request_end(); 145 if (@preg_match('@<?xml[^>]*encoding="([^"]+)"@i', $fContent, $xml_encoding)) { 146 $this->rss['encoding'] = strtolower($xml_encoding[1]); 147 } 148 149 $parsedOkay = xml_parse($this->parser, $fContent, true); 150 if (!$parsedOkay && xml_get_error_code($this->parser) != XML_ERROR_NONE) 151 { 152 $this->raiseError((__LINE__-3), 'File has an XML error (<em>'.xml_error_string(xml_get_error_code($this->parser)).'</em> at line <em>'.xml_get_current_line_number($this->parser).'</em>).'); 153 return false; 154 } 155 156 clearstatcache(); 157 if ($file) 158 { 159 if (!($cache = @fopen($file, 'w'))) 160 { 161 $this->raiseError((__LINE__-2), 'Could not write to cache file (<em>'.$file.'</em>). The path may be invalid or you may not have write permissions.'); 162 return false; 163 } 164 fwrite($cache, serialize($this->data)); 165 fclose($cache); 166 $this->rss['cache_age'] = 0; 167 } 168 } 169 else 170 { 171 clearstatcache(); 172 if (!($fp = @fopen($file, 'r'))) 173 { 174 $this->raiseError((__LINE__-2), 'Could not read contents of cache file (<em>'.$cache_file.'</em>).'); 175 return false; 176 } 177 $this->data = unserialize(fread($fp, filesize($file))); 178 fclose($fp); 179 } 180 return true; 181 } 182 183 function parseLocal($uri, $file=false, $time=false) 184 { 185 return $this->parse($uri, $file, $time, true); 186 } 187 188 //private function tag_open($parser, $tag, $attrs) 189 function tag_open($parser, $tag, $attrs) 190 { 191 $this->rss['current_tag'] = $tag = strtolower($tag); 192 switch ($tag) 193 { 194 case 'channel': 195 case 'image': 196 case 'textinput': 197 $this->type = $tag; 198 break; 199 case 'item': 200 $this->type = $tag; 201 $this->rss['index']++; 202 break; 203 default: 204 break; 205 } 206 if (sizeof($attrs)) 207 foreach ($attrs as $k => $v) 208 if (strpos($k, 'xmlns') !== false) 209 $this->data['namespaces'][$k] = $v; 210 } 211 212 //private function tag_close($parser, $tag){} 213 function tag_close($parser, $tag){} 214 215 //private function cdata($parser, $cdata) 216 function cdata($parser, $cdata) 217 { 218 if (strlen(trim($cdata)) && $cdata != "\n") 219 switch ($this->type) 220 { 221 case 'channel': 222 case 'image': 223 case 'textinput': 224 (!isset($this->data[$this->type][$this->rss['current_tag']]) || 225 !strlen($this->data[$this->type][$this->rss['current_tag']])) ? 226 $this->data[$this->type][$this->rss['current_tag']] = $cdata : 227 $this->data[$this->type][$this->rss['current_tag']].= $cdata; 228 break; 229 case 'item': 230 (!isset($this->data['items'][$this->rss['index']-1][$this->rss['current_tag']]) || 231 !strlen($this->data['items'][$this->rss['index']-1][$this->rss['current_tag']])) ? 232 $this->data['items'][$this->rss['index']-1][$this->rss['current_tag']] = $cdata : 233 $this->data['items'][$this->rss['index']-1][$this->rss['current_tag']].= $cdata; 234 break; 235 } 236 } 237 238 function getData($type) 239 { 240 if ($type == ONYX_META) 241 return $this->conf['fetch_mode'] == 1 ? $this->data['channel'] : (object)$this->data['channel']; 242 if ($type == ONYX_IMAGE) 243 return $this->conf['fetch_mode'] == 1 ? $this->data['image'] : (object)$this->data['image']; 244 if ($type == ONYX_TEXTINPUT) 245 return $this->conf['fetch_mode'] == 1 ? $this->data['textinput'] : (object)$this->data['textinput']; 246 if ($type == ONYX_ITEMS) 247 { 248 if ($this->conf['fetch_mode'] == 1) 249 return $this->data['items']; 250 251 $temp = array(); 252 for ($i=0; $i < sizeof($this->data['items']); $i++) 253 $temp[] = (object)$this->data['items'][$i]; 254 255 return $temp; 256 } 257 if ($type == ONYX_NAMESPACES) 258 return $this->conf['fetch_mode'] == 1 ? $this->data['namespaces'] : (object)$this->data['namespaces']; 259 if ($type == ONYX_CACHE_AGE) 260 return $this->rss['cache_age']; 261 262 return false; 263 } 264 265 function numItems() 266 { 267 return sizeof($this->data['items']); 268 } 269 270 function getNextItem($max=false) 271 { 272 $type = $this->conf['fetch_mode']; 273 $this->rss['output_index']++; 274 if (($max && $this->rss['output_index'] > $max) || !isset($this->data['items'][$this->rss['output_index']])) 275 return false; 276 277 return ($type == ONYX_FETCH_ASSOC) ? $this->data['items'][$this->rss['output_index']] : 278 (($type == ONYX_FETCH_OBJECT) ? (object)$this->data['items'][$this->rss['output_index']] : false); 279 } 280 281 function itemAt($num) 282 { 283 if (!isset($this->data['items'][$num])) 284 { 285 $this->raiseError((__LINE__-3), ONYX_ERR_INVALID_ITEM); 286 return false; 287 } 288 289 $type = $this->conf['fetch_mode']; 290 return ($type == ONYX_FETCH_ASSOC) ? $this->data['items'][$num] : 291 (($type == ONYX_FETCH_OBJECT) ? (object)$this->data['items'][$num] : false); 292 } 293 294 function startBuffer($file=false) 295 { 296 $this->conf['output_file'] = $file; 297 ob_start(); 298 } 299 300 function endBuffer() 301 { 302 if (!$this->conf['output_file']) 303 ob_end_flush(); 304 else 305 { 306 if (!($fp = @fopen($this->conf['output_file'], 'w'))) 307 { 308 $this->raiseError((__LINE__-2), ONYX_ERR_NO_STREAM); 309 ob_end_flush(); 310 return; 311 } 312 fwrite($fp, ob_get_contents()); 313 fclose($fp); 314 ob_end_clean(); 315 } 316 } 317 318 //private function raiseError($line, $err) 319 function raiseError($line, $err) 320 { 321 if ($this->conf['debug_mode']) 322 printf($this->conf['error'], $line, $err); 323 } 324 325 function setCachePath($path) 326 { 327 $this->conf['cache_path'] = $path; 328 } 329 330 function setExpiryTime($time) 331 { 332 $this->conf['cache_time'] = $time; 333 } 334 335 function setDebugMode($state) 336 { 337 $this->conf['debug_mode'] = (bool)$state; 338 } 339 340 function setFetchMode($mode) 341 { 342 $this->conf['fetch_mode'] = $mode; 343 } 344 345 //private function mod_time($uri) 346 function mod_time($uri) 347 { 348 if (function_exists('version_compare') && version_compare(phpversion(), '4.3.0') >= 0) 349 { 350 require_once S9Y_PEAR_PATH . 'HTTP/Request.php'; 351 serendipity_request_start(); 352 $req = &new HTTP_Request($uri); 353 354 if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') { 355 serendipity_request_end(); 356 return false; 357 } 358 359 $fHeader = $req->getResponseHeader(); 360 if (isset($fHeader['last-modified'])) { 361 $modtime = $fHeader['last-modified']; 362 } 363 serendipity_request_end(); 364 } 365 else 366 { 367 $parts = parse_url($uri); 368 $host = $parts['host']; 369 $path = $parts['path']; 370 371 if (!($fp = @fsockopen($host, 80))) 372 return false; 373 374 $req = "HEAD $path HTTP/1.1\r\nUser-Agent: PHP/".phpversion(); 375 $req.= "\r\nHost: $host\r\nAccept: */*\r\n\r\n"; 376 fputs($fp, $req); 377 378 while (!feof($fp)) 379 { 380 $str = fgets($fp, 4096); 381 if (strpos(strtolower($str), 'last-modified') !== false) 382 { 383 $modtime = substr($str, 15); 384 break; 385 } 386 } 387 fclose($fp); 388 } 389 return (isset($modtime)) ? $modtime : 0; 390 } 391 } 392 393 394 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sat Nov 24 09:00:37 2007 | par Balluche grâce à PHPXref 0.7 |
|