Parse(data,template,newscount); */ /* */ /* , где: */ /* */ /* - dateformat - формат даты (как у функции date()) */ /* - data - данные для обработки */ /* - выходной шаблон */ /* - количество обрабатываемых новостей */ class RSS091Parser { var $DATA; var $template; var $xml_parser; var $newscount; var $dateformat; function RSS091Parser($idateformat) { $this->dateformat=$idateformat; $this->DATA=Array(); $this->DATA["count"]=0; } /* RSS 0.91 XML Handlers */ function startElement($parser, $name, $attrs) { $this->DATA["curtag"]=$name; $this->DATA[$name]=""; } function endElement($parser, $name) { if ($name=="ITEM" && $this->DATA["count"]<$this->newscount) { $t=$this->template; if (!empty($this->dateformat)) { $ttime=strtotime($this->DATA["PUBDATE"]); $this->DATA["PUBDATE"]=date($this->dateformat,$ttime); } $t=str_replace("%URL%",$this->DATA["LINK"],$t); $t=str_replace("%TITLE%",$this->DATA["TITLE"],$t); $t=str_replace("%DESCRIPTION%",$this->DATA["DESCRIPTION"],$t); $t=str_replace("%PUBDATE%",$this->DATA["PUBDATE"],$t); $this->DATA["data"].=$t; $this->DATA["count"]++; } $this->DATA["curtag"]=""; } function characterData($parser, $data) { $this->DATA[$this->DATA["curtag"]].=$data; } function Parse($data,$itemplate,$newscount) { $this->template=$itemplate; $this->newscount=$newscount; $this->xml_parser=xml_parser_create(); xml_set_object($this->xml_parser, &$this); xml_set_element_handler($this->xml_parser, "startElement", "endElement"); xml_set_character_data_handler($this->xml_parser, "characterData"); xml_parse($this->xml_parser, $data) or die("Error parsing XML"); xml_parser_free($this->xml_parser); return($this->DATA["data"]); } }; /* Вспомогательный класс для разбора входного файла */ /* */ /* Парсер ULTRAMODE */ /* */ /* Используется следующим образом: */ /* */ /* $parser=new ULTRAMODEParser(dateformat); */ /* $result=$parser->Parse(data,template,newscount); */ /* */ /* , где: */ /* */ /* - dateformat - формат даты (как у функции date()) */ /* - data - данные для обработки */ /* - выходной шаблон */ /* - количество обрабатываемых новостей */ class ULTRAMODEParser { var $dateformat; function ULTRAMODEParser($idateformat="") { $this->dateformat=$idateformat; } function Parse($data,$itemplate,$newscount) { if (strpos($data,"\n\r")) $data=explode("\n\r",$data); elseif (strpos($data,"\r\n")) $data=explode("\r\n",$data); elseif (strpos($data,"\n")) $data=explode("\n",$data); elseif (strpos($data,"\r")) $data=explode("\r",$data); $c=count($data); $s=0;while (substr($data[$s],0,2)!="%%" && $s<$c) $s++; $s++;$news=0;$result=""; for ($i=$s;$i<$c;$i+=8) { if ($news>=$newscount) break; $t=$itemplate; $pubdate=trim($data[$i+2]); if (!empty($this->dateformat)) { $ttime=strtotime($pubdate); $pubdate=date($this->dateformat,$ttime); } $t=str_replace("%URL%",trim($data[$i+1]),$t); $t=str_replace("%TITLE%",trim($data[$i+0]),$t); $t=str_replace("%PUBDATE%",$pubdate,$t); $t=str_replace("%AUTHOR%",trim($data[$i+3]),$t); $t=str_replace("%TOPIC%",trim($data[$i+4]),$t); $t=str_replace("%COMMENTS%",trim($data[$i+5]),$t); $t=str_replace("%IMAGE%",trim($data[$i+6]),$t); $news++; $result.=$t; } return($result); } }; /* Основной класс */ class News { var $type; // Tип импортируемого файла (rss091, ultramode) var $updatetime; // Дата обновления кеша var $template; // Шаблон одной новости var $save; // Куда сохранять (mysql,file) var $newscount; // Количество новостей var $MYCONN; // MySql connection var $dateformat; // Lормат датv. +сли пусто, то остается по старому. // Если save==mysql var $mysql_server; // MySql сервер var $mysql_login; // MySql логин var $mysql_password; // MySql пароль var $mysql_database; // MySql имя базv даннvх // Если save==file var $file_path; // Путь для сохранения временного файла var $file_prefix; // Префикс временного файла /* Конструктор */ /* */ /* iupdatetime - частота обновления, в секундах (по умолчанию 1 час) */ /* itype - тип файла экспорта новостей (rss091 или ultramode) */ /* inewscount - колчество обрабатываемых новостей (по умолчанию 10) */ /* */ /* Пример: */ /* */ /* $news=new News(28800,"ultramode",5); */ /* */ function News($iupdatetime=3600,$itype="rss091",$inewscount=10) { $this->MYCONN=FALSE; $this->save="file"; $this->mysql_server="locahost"; $this->mysql_login="root"; $this->mysql_password=""; $this->mysql_database="news"; $this->file_prefix="news_"; $this->file_path="/tmp/"; $this->type=$itype; $this->newscount=$inewscount; $this->updatetime=$iupdatetime; $this->template="%TITLE%\n
%DESCRIPTION%\n
\n"; } /* Установка параметров MySql. Если этот метод не вызывается, то */ /* кеширование производится в файл, иначе в MySql таблицу: */ /* */ /* CREATE TABLE `newsimport` ( */ /* `id` int(11) NOT NULL default '0', */ /* `d_update` int(11) NOT NULL default '0', */ /* `data` text NOT NULL */ /* ) TYPE=MyISAM; */ /* */ /* server - сервер (хост), например localhost */ /* login - логин для подключения к MySql */ /* password - пароль для подключения к MySql */ /* database - база данных */ /* */ /* Пример: */ /* */ /* $news->setmysql("localhost","root","","mydatabase"); */ /* */ function setmysql($server,$login,$password,$database) { $this->save="mysql"; $this->mysql_server=$server; $this->mysql_login=$login; $this->mysql_password=$password; $this->mysql_database=$database; } /* Установка параметров кеш файлов. Если этот метод вызывается, то */ /* кеширование производится в файл. */ /* */ /* Пример производит кегирование в /usr/home/andrey/tmp/codenet_* */ /* */ /* $news->setfile("/usr/home/andrey/tmp/","codenet_"); */ /* */ /* */ function setfile($path,$prefix) { $this->save="file"; $this->file_prefix=$prefix; $this->file_path=$path; } /* */ /* Чтение шаблона из файла */ /* */ /* filename - имя файла с шаблоном */ /* idateformat - формат даты (как у функции date()) */ /* */ function readtemplate($filename,$idateformat="") { if (!is_file($filename)) die("File '".$filename."' not found\n"); $this->dateformat=$idateformat; $this->template=implode("",file($filename)); } /* */ /* Установка шаблона из переменной */ /* */ /* template - имя файла с шаблоном */ /* idateformat - формат даты (как у функции date()) */ /* */ function settemplate($template,$idateformat="") { $this->dateformat=$idateformat; $this->template=$template; } /* */ /* Получение, обработка и кеширование новостей - основной метод */ /* */ /* url - адрес, откуда берутся новости */ /* */ function read($url) { /* исползуем crc32 от адреса, в качестве уникального */ /* идентификатора источника новостей */ $id=crc32($url); /* установим время последнего обновления новости в 0 */ $lastupdatetime=0; switch ($this->save) { /* для кеширования в MySql */ case "mysql": /* соединение с базой данных */ if (!$this->MYCONN) { $this->MYCONN=mysql_connect($this->mysql_server, $this->mysql_login, $this->mysql_password) or die(mysql_error()); mysql_select_db($this->mysql_database,$this->MYCONN) or die(mysql_error()); } /* Получим дату последнего обновления новостей */ $r=mysql_query("SELECT d_update FROM newsimport WHERE id='".$id."';",$this->MYCONN) or die(mysql_error()); if (mysql_num_rows($r)==1) { $lastupdatetime=mysql_result($r,0,0); } /* Если записи с такми ID не существует, то новости с этого */ /* сервера импортируется впервые, и необходимо создать для */ /* него запись, а $lastupdatetime оставить равной нулю */ elseif (mysql_num_rows($r)==0) { mysql_query("INSERT INTO newsimport SET id='".$id."', d_update=UNIX_TIMESTAMP();"); } mysql_free_result($r); break; /* для кеширования в файл */ case "file": default: /* получим имя полное файла */ $fname=$this->file_path.$this->file_prefix.$id; /* получим дату последнего обновления */ $d=@file($fname.".time"); if (is_array($d)) $lastupdatetime=intval($d[0]); /* Если такого файла не существует, то новости с этого */ /* сервера импортируется впервые, и необходимо создать для */ /* него запись, а $lastupdatetime оставить равной нулю */ else { $fw=fopen($fname.".time","wt"); if (!$fw) die("Невозможно сохранить дату обновления в кеш файле - \"".$fname.".time\""); fputs($fw,time()); fclose($fw); } } $fromcache=0; /* Если пора обновлять кеш... */ if (time()-$this->updatetime>$lastupdatetime) { /* то получим данные с сервера новостей */ $d=@file($url); if (is_array($d)) { $d=implode("",$d); /* Обраобаем данные, в зависимости от типа, с помощью */ /* специальных объектов (см. выше) */ switch ($this->type) { case "ultramode": $parser=new ULTRAMODEParser($this->dateformat); $result=$parser->Parse($d, $this->template, $this->newscount); break; case "rss091": default: $parser=new RSS091Parser($this->dateformat); $result=$parser->Parse($d, $this->template, $this->newscount); } /* Сохоаним данные в MySql или файле */ /* Изменим дату последнего обновления на текущую */ switch ($this->save) { case "mysql": mysql_query("UPDATE newsimport SET d_update=UNIX_TIMESTAMP(), data='".$result."' WHERE id='".$id."';") or die(mysql_error()); break; case "file": default: $fname=$this->file_path.$this->file_prefix.$id; $fw=@fopen($fname.".time","wt"); if (!$fw) die("Невозможно сохранить дату обновления в кеш файле - \"".$fname.".time\""); fputs($fw,time()); fclose($fw); $fw=@fopen($fname.".text","wt"); if (!$fw) die("Невозможно сохранить текст новостей в кеш файле - \"".$fname.".text\""); fputs($fw,$result); fclose($fw); } } else $fromcache=1; } else $fromcache=1; /* Если не надо получать новости с сервера новосей, или он не */ /* работает, то возьмем из их кеша */ if ($fromcache==1) { switch ($this->save) { /* Для MySql */ case "mysql": $r=mysql_query("SELECT data FROM newsimport WHERE id='".$id."';") or die(mysql_error()); $result=mysql_result($r,0,0); mysql_free_result($r); break; /* Для файлов */ case "file": default: $result=implode("",file($this->file_path. $this->file_prefix. $id. ".text")); } } return($result); } }; ?>