00001 <?php
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 define("TIME_ZONE","+01:00");
00168
00169
00170
00171
00175 define("FEEDCREATOR_VERSION", "FeedCreator 1.7.2");
00176
00177
00178
00185 class FeedItem extends HtmlDescribable {
00189 var $title, $description, $link;
00190
00194 var $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator;
00195
00209 var $date;
00210
00219 var $additionalElements = Array();
00220
00221
00222
00223 }
00224
00225
00226
00232 class FeedImage extends HtmlDescribable {
00236 var $title, $url, $link;
00237
00241 var $width, $height, $description;
00242 }
00243
00244
00245
00250 class HtmlDescribable {
00254 var $descriptionHtmlSyndicated;
00255
00259 var $descriptionTruncSize;
00260
00266 function getDescription() {
00267 $descriptionField = new FeedHtmlField($this->description);
00268 $descriptionField->syndicateHtml = $this->descriptionHtmlSyndicated;
00269 $descriptionField->truncSize = $this->descriptionTruncSize;
00270 return $descriptionField->output();
00271 }
00272
00273 }
00274
00275
00283 class FeedHtmlField {
00287 var $rawFieldContent;
00288
00293 var $truncSize, $syndicateHtml;
00294
00299 function FeedHtmlField($parFieldContent) {
00300 if ($parFieldContent) {
00301 $this->rawFieldContent = $parFieldContent;
00302 }
00303 }
00304
00305
00310 function output() {
00311
00312
00313
00314 if (!$this->rawFieldContent) {
00315 $result = "";
00316 } elseif ($this->syndicateHtml) {
00317 $result = "<![CDATA[".$this->rawFieldContent."]]>";
00318 } else {
00319 if ($this->truncSize and is_int($this->truncSize)) {
00320 $result = FeedCreator::iTrunc(htmlspecialchars($this->rawFieldContent),$this->truncSize);
00321 } else {
00322 $result = htmlspecialchars($this->rawFieldContent);
00323 }
00324 }
00325 return $result;
00326 }
00327
00328 }
00329
00330
00331
00341 class UniversalFeedCreator extends FeedCreator {
00342 var $_feed;
00343
00344 function _setFormat($format) {
00345 switch (strtoupper($format)) {
00346
00347 case "2.0":
00348
00349 case "RSS2.0":
00350 $this->_feed = new RSSCreator20();
00351 break;
00352
00353 case "1.0":
00354
00355 case "RSS1.0":
00356 $this->_feed = new RSSCreator10();
00357 break;
00358
00359 case "0.91":
00360
00361 case "RSS0.91":
00362 $this->_feed = new RSSCreator091();
00363 break;
00364
00365 case "PIE0.1":
00366 $this->_feed = new PIECreator01();
00367 break;
00368
00369 case "MBOX":
00370 $this->_feed = new MBOXCreator();
00371 break;
00372
00373 case "OPML":
00374 $this->_feed = new OPMLCreator();
00375 break;
00376
00377 case "ATOM":
00378
00379
00380 case "ATOM0.3":
00381 $this->_feed = new AtomCreator03();
00382 break;
00383
00384 case "HTML":
00385 $this->_feed = new HTMLCreator();
00386 break;
00387
00388 case "JS":
00389
00390 case "JAVASCRIPT":
00391 $this->_feed = new JSCreator();
00392 break;
00393
00394 default:
00395 $this->_feed = new RSSCreator091();
00396 break;
00397 }
00398
00399 $vars = get_object_vars($this);
00400 foreach ($vars as $key => $value) {
00401
00402 if (!in_array($key, array("_feed", "contentType", "encoding"))) {
00403 $this->_feed->{$key} = $this->{$key};
00404 }
00405 }
00406 }
00407
00416 function createFeed($format = "RSS0.91") {
00417 $this->_setFormat($format);
00418 return $this->_feed->createFeed();
00419 }
00420
00421
00422
00433 function saveFeed($format="RSS0.91", $filename="", $displayContents=true) {
00434 $this->_setFormat($format);
00435 $this->_feed->saveFeed($filename, $displayContents);
00436 }
00437
00438
00451 function useCached($format="RSS0.91", $filename="", $timeout=3600) {
00452 $this->_setFormat($format);
00453 $this->_feed->useCached($filename, $timeout);
00454 }
00455
00456 }
00457
00458
00467 class FeedCreator extends HtmlDescribable {
00468
00472 var $title, $description, $link;
00473
00474
00478 var $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
00479
00484 var $xslStyleSheet = "";
00485
00486
00490 var $items = Array();
00491
00492
00498 var $contentType = "application/xml";
00499
00500
00505 var $encoding = "ISO-8859-1";
00506
00507
00516 var $additionalElements = Array();
00517
00518
00525 function addItem($item) {
00526 $this->items[] = $item;
00527 }
00528
00529
00542 function iTrunc($string, $length) {
00543 if (strlen($string)<=$length) {
00544 return $string;
00545 }
00546
00547 $pos = strrpos($string,".");
00548 if ($pos>=$length-4) {
00549 $string = substr($string,0,$length-4);
00550 $pos = strrpos($string,".");
00551 }
00552 if ($pos>=$length*0.4) {
00553 return substr($string,0,$pos+1)." ...";
00554 }
00555
00556 $pos = strrpos($string," ");
00557 if ($pos>=$length-4) {
00558 $string = substr($string,0,$length-4);
00559 $pos = strrpos($string," ");
00560 }
00561 if ($pos>=$length*0.4) {
00562 return substr($string,0,$pos)." ...";
00563 }
00564
00565 return substr($string,0,$length-4)." ...";
00566
00567 }
00568
00569
00575 function _createGeneratorComment() {
00576 return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
00577 }
00578
00579
00587 function _createAdditionalElements($elements, $indentString="") {
00588 $ae = "";
00589 if (is_array($elements)) {
00590 foreach($elements AS $key => $value) {
00591 $ae.= $indentString."<$key>$value</$key>\n";
00592 }
00593 }
00594 return $ae;
00595 }
00596
00597 function _createStylesheetReferences() {
00598 $xml = "";
00599 if ($this->cssStyleSheet) $xml .= "<?xml-stylesheet href=\"".$this->cssStyleSheet."\" type=\"text/css\"?>\n";
00600 if ($this->xslStyleSheet) $xml .= "<?xml-stylesheet href=\"".$this->xslStyleSheet."\" type=\"text/xsl\"?>\n";
00601 return $xml;
00602 }
00603
00604
00610 function createFeed() {
00611 }
00612
00629 function _generateFilename() {
00630 if (defined('FEEDCREATOR_TMP_DIR'))
00631 $tmpDir = FEEDCREATOR_TMP_DIR;
00632 else
00633 $tmpDir = '/tmp';
00634
00635 return "$tmpDir/FEEDCREATOR_" . md5($_SERVER['REQUEST_URI']) . ".xml";
00636 }
00637
00638
00643 function _redirect($filename) {
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 if (strpos($_SERVER["HTTP_USER_AGENT"], 'Mozilla') !== null)
00660 header("Content-Type: text/xml");
00661 else
00662 header("Content-Type: application/rss+xml");
00663
00664
00665 echo file_get_contents($filename, "r");
00666 die();
00667 }
00668
00679 function useCached($filename="", $timeout=3600) {
00680 $this->_timeout = $timeout;
00681 if ($filename=="") {
00682 $filename = $this->_generateFilename();
00683 }
00684 if (file_exists($filename) AND (time()-filemtime($filename) < $timeout)) {
00685 $this->_redirect($filename);
00686 }
00687 }
00688
00689
00698 function saveFeed($filename="", $displayContents=true) {
00699 if ($filename=="") {
00700 $filename = $this->_generateFilename();
00701 }
00702 $feedFile = fopen($filename, "w+");
00703 if ($feedFile) {
00704 fputs($feedFile,$this->createFeed());
00705 fclose($feedFile);
00706 if ($displayContents) {
00707 $this->_redirect($filename);
00708 }
00709 } else {
00710 echo "<br /><b>Error creating feed file, please check write permissions.</b><br />";
00711 }
00712 }
00713
00714 }
00715
00716
00721 class FeedDate {
00722 var $unix;
00723
00729 function FeedDate($dateString="") {
00730 if ($dateString=="") $dateString = date("r");
00731
00732 if (is_integer($dateString)) {
00733 $this->unix = $dateString;
00734 return;
00735 }
00736 if (preg_match("~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~",$dateString,$matches)) {
00737 $months = Array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
00738 $this->unix = mktime($matches[4],$matches[5],$matches[6],$months[$matches[2]],$matches[1],$matches[3]);
00739 if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
00740 $tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
00741 } else {
00742 if (strlen($matches[7])==1) {
00743 $oneHour = 3600;
00744 $ord = ord($matches[7]);
00745 if ($ord < ord("M")) {
00746 $tzOffset = (ord("A") - $ord - 1) * $oneHour;
00747 } elseif ($ord >= ord("M") AND $matches[7]!="Z") {
00748 $tzOffset = ($ord - ord("M")) * $oneHour;
00749 } elseif ($matches[7]=="Z") {
00750 $tzOffset = 0;
00751 }
00752 }
00753 switch ($matches[7]) {
00754 case "UT":
00755 case "GMT": $tzOffset = 0;
00756 }
00757 }
00758 $this->unix += $tzOffset;
00759 return;
00760 }
00761 if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~",$dateString,$matches)) {
00762 $this->unix = mktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]);
00763 if (substr($matches[7],0,1)=='+' OR substr($matches[7],0,1)=='-') {
00764 $tzOffset = (substr($matches[7],0,3) * 60 + substr($matches[7],-2)) * 60;
00765 } else {
00766 if ($matches[7]=="Z") {
00767 $tzOffset = 0;
00768 }
00769 }
00770 $this->unix += $tzOffset;
00771 return;
00772 }
00773 $this->unix = 0;
00774 }
00775
00781 function rfc822() {
00782
00783 $date = gmdate("D, d M Y H:i:s", $this->unix);
00784 if (TIME_ZONE!="") $date .= " ".str_replace(":","",TIME_ZONE);
00785 return $date;
00786 }
00787
00793 function iso8601() {
00794 $date = gmdate("Y-m-d\TH:i:sO",$this->unix);
00795 $date = substr($date,0,22) . ':' . substr($date,-2);
00796 if (TIME_ZONE!="") $date = str_replace("+00:00",TIME_ZONE,$date);
00797 return $date;
00798 }
00799
00805 function unix() {
00806 return $this->unix;
00807 }
00808 }
00809
00810
00818 class RSSCreator10 extends FeedCreator {
00819
00825 function createFeed() {
00826 $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
00827 $feed.= $this->_createGeneratorComment();
00828 if ($this->cssStyleSheet=="") {
00829 $cssStyleSheet = "http://www.w3.org/2000/08/w3c-synd/style.css";
00830 }
00831 $feed.= $this->_createStylesheetReferences();
00832 $feed.= "<rdf:RDF\n";
00833 $feed.= " xmlns=\"http://purl.org/rss/1.0/\"\n";
00834 $feed.= " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n";
00835 $feed.= " xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\"\n";
00836 $feed.= " xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
00837 $feed.= " <channel rdf:about=\"".$this->syndicationURL."\">\n";
00838 $feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
00839 $feed.= " <description>".htmlspecialchars($this->description)."</description>\n";
00840 $feed.= " <link>".$this->link."</link>\n";
00841 if ($this->image!=null) {
00842 $feed.= " <image rdf:resource=\"".$this->image->url."\" />\n";
00843 }
00844 $now = new FeedDate();
00845 $feed.= " <dc:date>".htmlspecialchars($now->iso8601())."</dc:date>\n";
00846 $feed.= " <items>\n";
00847 $feed.= " <rdf:Seq>\n";
00848 for ($i=0;$i<count($this->items);$i++) {
00849 $feed.= " <rdf:li rdf:resource=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
00850 }
00851 $feed.= " </rdf:Seq>\n";
00852 $feed.= " </items>\n";
00853 $feed.= " </channel>\n";
00854 if ($this->image!=null) {
00855 $feed.= " <image rdf:about=\"".$this->image->url."\">\n";
00856 $feed.= " <title>".$this->image->title."</title>\n";
00857 $feed.= " <link>".$this->image->link."</link>\n";
00858 $feed.= " <url>".$this->image->url."</url>\n";
00859 $feed.= " </image>\n";
00860 }
00861 $feed.= $this->_createAdditionalElements($this->additionalElements, " ");
00862
00863 for ($i=0;$i<count($this->items);$i++) {
00864 $feed.= " <item rdf:about=\"".htmlspecialchars($this->items[$i]->link)."\">\n";
00865
00866 $feed.= " <dc:format>text/html</dc:format>\n";
00867 if ($this->items[$i]->date!=null) {
00868 $itemDate = new FeedDate($this->items[$i]->date);
00869 $feed.= " <dc:date>".htmlspecialchars($itemDate->iso8601())."</dc:date>\n";
00870 }
00871 if ($this->items[$i]->source!="") {
00872 $feed.= " <dc:source>".htmlspecialchars($this->items[$i]->source)."</dc:source>\n";
00873 }
00874 if ($this->items[$i]->author!="") {
00875 $feed.= " <dc:creator>".htmlspecialchars($this->items[$i]->author)."</dc:creator>\n";
00876 }
00877 $feed.= " <title>".htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r"," ")))."</title>\n";
00878 $feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
00879 $feed.= " <description>".htmlspecialchars($this->items[$i]->description)."</description>\n";
00880 $feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
00881 $feed.= " </item>\n";
00882 }
00883 $feed.= "</rdf:RDF>\n";
00884 return $feed;
00885 }
00886 }
00887
00888
00889
00897 class RSSCreator091 extends FeedCreator {
00898
00903 var $RSSVersion;
00904
00905 function RSSCreator091() {
00906 $this->_setRSSVersion("0.91");
00907 $this->contentType = "application/rss+xml";
00908 }
00909
00914 function _setRSSVersion($version) {
00915 $this->RSSVersion = $version;
00916 }
00917
00923 function createFeed() {
00924 $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
00925 $feed.= $this->_createGeneratorComment();
00926 $feed.= $this->_createStylesheetReferences();
00927 $feed.= "<rss version=\"".$this->RSSVersion."\">\n";
00928 $feed.= " <channel>\n";
00929 $feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
00930 $this->descriptionTruncSize = 500;
00931 $feed.= " <description>".$this->getDescription()."</description>\n";
00932 $feed.= " <link>".htmlspecialchars($this->link)."</link>\n";
00933 $now = new FeedDate();
00934 $feed.= " <lastBuildDate>".htmlspecialchars($now->rfc822())."</lastBuildDate>\n";
00935 $feed.= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
00936
00937 if ($this->image!=null) {
00938 $feed.= " <image>\n";
00939 $feed.= " <url>".$this->image->url."</url>\n";
00940 $feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->image->title),100)."</title>\n";
00941 $feed.= " <link>".$this->image->link."</link>\n";
00942 if ($this->image->width!="") {
00943 $feed.= " <width>".$this->image->width."</width>\n";
00944 }
00945 if ($this->image->height!="") {
00946 $feed.= " <height>".$this->image->height."</height>\n";
00947 }
00948 if ($this->image->description!="") {
00949 $feed.= " <description>".$this->image->getDescription()."</description>\n";
00950 }
00951 $feed.= " </image>\n";
00952 }
00953 if ($this->language!="") {
00954 $feed.= " <language>".$this->language."</language>\n";
00955 }
00956 if ($this->copyright!="") {
00957 $feed.= " <copyright>".FeedCreator::iTrunc(htmlspecialchars($this->copyright),100)."</copyright>\n";
00958 }
00959 if ($this->editor!="") {
00960 $feed.= " <managingEditor>".FeedCreator::iTrunc(htmlspecialchars($this->editor),100)."</managingEditor>\n";
00961 }
00962 if ($this->webmaster!="") {
00963 $feed.= " <webMaster>".FeedCreator::iTrunc(htmlspecialchars($this->webmaster),100)."</webMaster>\n";
00964 }
00965 if ($this->pubDate!="") {
00966 $pubDate = new FeedDate($this->pubDate);
00967 $feed.= " <pubDate>".htmlspecialchars($pubDate->rfc822())."</pubDate>\n";
00968 }
00969 if ($this->category!="") {
00970 $feed.= " <category>".htmlspecialchars($this->category)."</category>\n";
00971 }
00972 if ($this->docs!="") {
00973 $feed.= " <docs>".FeedCreator::iTrunc(htmlspecialchars($this->docs),500)."</docs>\n";
00974 }
00975 if ($this->ttl!="") {
00976 $feed.= " <ttl>".htmlspecialchars($this->ttl)."</ttl>\n";
00977 }
00978 if ($this->rating!="") {
00979 $feed.= " <rating>".FeedCreator::iTrunc(htmlspecialchars($this->rating),500)."</rating>\n";
00980 }
00981 if ($this->skipHours!="") {
00982 $feed.= " <skipHours>".htmlspecialchars($this->skipHours)."</skipHours>\n";
00983 }
00984 if ($this->skipDays!="") {
00985 $feed.= " <skipDays>".htmlspecialchars($this->skipDays)."</skipDays>\n";
00986 }
00987 $feed.= $this->_createAdditionalElements($this->additionalElements, " ");
00988
00989 for ($i=0;$i<count($this->items);$i++) {
00990 $feed.= " <item>\n";
00991 $feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
00992 $feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
00993 $feed.= " <description>".$this->items[$i]->getDescription()."</description>\n";
00994
00995 if ($this->items[$i]->author!="") {
00996 $feed.= " <author>".htmlspecialchars($this->items[$i]->author)."</author>\n";
00997 }
00998
00999
01000
01001
01002
01003
01004 if ($this->items[$i]->category!="") {
01005 $feed.= " <category>".htmlspecialchars($this->items[$i]->category)."</category>\n";
01006 }
01007 if ($this->items[$i]->comments!="") {
01008 $feed.= " <comments>".htmlspecialchars($this->items[$i]->comments)."</comments>\n";
01009 }
01010 if ($this->items[$i]->date!="") {
01011 $itemDate = new FeedDate($this->items[$i]->date);
01012 $feed.= " <pubDate>".htmlspecialchars($itemDate->rfc822())."</pubDate>\n";
01013 }
01014 if ($this->items[$i]->guid!="") {
01015 $feed.= " <guid>".htmlspecialchars($this->items[$i]->guid)."</guid>\n";
01016 }
01017 $feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
01018 $feed.= " </item>\n";
01019 }
01020 $feed.= " </channel>\n";
01021 $feed.= "</rss>\n";
01022 return $feed;
01023 }
01024 }
01025
01026
01027
01035 class RSSCreator20 extends RSSCreator091 {
01036
01037 function RSSCreator20() {
01038 parent::_setRSSVersion("2.0");
01039 }
01040
01041 }
01042
01043
01052 class PIECreator01 extends FeedCreator {
01053
01054 function PIECreator01() {
01055 $this->encoding = "utf-8";
01056 }
01057
01058 function createFeed() {
01059 $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
01060 $feed.= $this->_createStylesheetReferences();
01061 $feed.= "<feed version=\"0.1\" xmlns=\"http://example.com/newformat#\">\n";
01062 $feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</title>\n";
01063 $this->truncSize = 500;
01064 $feed.= " <subtitle>".$this->getDescription()."</subtitle>\n";
01065 $feed.= " <link>".$this->link."</link>\n";
01066 for ($i=0;$i<count($this->items);$i++) {
01067 $feed.= " <entry>\n";
01068 $feed.= " <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100)."</title>\n";
01069 $feed.= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
01070 $itemDate = new FeedDate($this->items[$i]->date);
01071 $feed.= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
01072 $feed.= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
01073 $feed.= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
01074 $feed.= " <id>".htmlspecialchars($this->items[$i]->guid)."</id>\n";
01075 if ($this->items[$i]->author!="") {
01076 $feed.= " <author>\n";
01077 $feed.= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
01078 if ($this->items[$i]->authorEmail!="") {
01079 $feed.= " <email>".$this->items[$i]->authorEmail."</email>\n";
01080 }
01081 $feed.=" </author>\n";
01082 }
01083 $feed.= " <content type=\"text/html\" xml:lang=\"en-us\">\n";
01084 $feed.= " <div xmlns=\"http://www.w3.org/1999/xhtml\">".$this->items[$i]->getDescription()."</div>\n";
01085 $feed.= " </content>\n";
01086 $feed.= " </entry>\n";
01087 }
01088 $feed.= "</feed>\n";
01089 return $feed;
01090 }
01091 }
01092
01093
01110 class AtomCreator03 extends FeedCreator {
01111
01112 function AtomCreator03() {
01113 $this->contentType = "application/atom+xml";
01114 $this->encoding = "utf-8";
01115 }
01116
01117 function createFeed() {
01118 $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
01119 $feed.= $this->_createGeneratorComment();
01120 $feed.= $this->_createStylesheetReferences();
01121 $feed.= "<feed version=\"0.3\" xmlns=\"http://purl.org/atom/ns#\"";
01122 if ($this->language!="") {
01123 $feed.= " xml:lang=\"".$this->language."\"";
01124 }
01125 $feed.= ">\n";
01126 $feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
01127 $feed.= " <tagline>".htmlspecialchars($this->description)."</tagline>\n";
01128 $feed.= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->link)."\"/>\n";
01129 $feed.= " <id>".htmlspecialchars($this->link)."</id>\n";
01130 $now = new FeedDate();
01131 $feed.= " <modified>".htmlspecialchars($now->iso8601())."</modified>\n";
01132 if ($this->editor!="") {
01133 $feed.= " <author>\n";
01134 $feed.= " <name>".$this->editor."</name>\n";
01135 if ($this->editorEmail!="") {
01136 $feed.= " <email>".$this->editorEmail."</email>\n";
01137 }
01138 $feed.= " </author>\n";
01139 }
01140 $feed.= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
01141 $feed.= $this->_createAdditionalElements($this->additionalElements, " ");
01142 for ($i=0;$i<count($this->items);$i++) {
01143 $feed.= " <entry>\n";
01144 $feed.= " <title>".htmlspecialchars(strip_tags($this->items[$i]->title))."</title>\n";
01145 $feed.= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
01146 if ($this->items[$i]->date=="") {
01147 $this->items[$i]->date = time();
01148 }
01149 $itemDate = new FeedDate($this->items[$i]->date);
01150 $feed.= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
01151 $feed.= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
01152 $feed.= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
01153 $feed.= " <id>".htmlspecialchars($this->items[$i]->link)."</id>\n";
01154 $feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
01155 if ($this->items[$i]->author!="") {
01156 $feed.= " <author>\n";
01157 $feed.= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
01158 $feed.= " </author>\n";
01159 }
01160 if ($this->items[$i]->description!="") {
01161 $feed.= " <summary>".htmlspecialchars($this->items[$i]->description)."</summary>\n";
01162 }
01163 $feed.= " </entry>\n";
01164 }
01165 $feed.= "</feed>\n";
01166 return $feed;
01167 }
01168 }
01169
01170
01178 class MBOXCreator extends FeedCreator {
01179
01180 function MBOXCreator() {
01181 $this->contentType = "text/plain";
01182 $this->encoding = "ISO-8859-15";
01183 }
01184
01185 function qp_enc($input = "", $line_max = 76) {
01186 $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
01187 $lines = preg_split("/(?:\r\n|\r|\n)/", $input);
01188 $eol = "\r\n";
01189 $escape = "=";
01190 $output = "";
01191 while( list(, $line) = each($lines) ) {
01192
01193 $linlen = strlen($line);
01194 $newline = "";
01195 for($i = 0; $i < $linlen; $i++) {
01196 $c = substr($line, $i, 1);
01197 $dec = ord($c);
01198 if ( ($dec == 32) && ($i == ($linlen - 1)) ) {
01199 $c = "=20";
01200 } elseif ( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ) {
01201 $h2 = floor($dec/16); $h1 = floor($dec%16);
01202 $c = $escape.$hex["$h2"].$hex["$h1"];
01203 }
01204 if ( (strlen($newline) + strlen($c)) >= $line_max ) {
01205 $output .= $newline.$escape.$eol;
01206 $newline = "";
01207 }
01208 $newline .= $c;
01209 }
01210 $output .= $newline.$eol;
01211 }
01212 return trim($output);
01213 }
01214
01215
01220 function createFeed() {
01221 for ($i=0;$i<count($this->items);$i++) {
01222 if ($this->items[$i]->author!="") {
01223 $from = $this->items[$i]->author;
01224 } else {
01225 $from = $this->title;
01226 }
01227 $itemDate = new FeedDate($this->items[$i]->date);
01228 $feed.= "From ".strtr(MBOXCreator::qp_enc($from)," ","_")." ".date("D M d H:i:s Y",$itemDate->unix())."\n";
01229 $feed.= "Content-Type: text/plain;\n";
01230 $feed.= " charset=\"".$this->encoding."\"\n";
01231 $feed.= "Content-Transfer-Encoding: quoted-printable\n";
01232 $feed.= "Content-Type: text/plain\n";
01233 $feed.= "From: \"".MBOXCreator::qp_enc($from)."\"\n";
01234 $feed.= "Date: ".$itemDate->rfc822()."\n";
01235 $feed.= "Subject: ".MBOXCreator::qp_enc(FeedCreator::iTrunc($this->items[$i]->title,100))."\n";
01236 $feed.= "\n";
01237 $body = chunk_split(MBOXCreator::qp_enc($this->items[$i]->description));
01238 $feed.= preg_replace("~\nFrom ([^\n]*)(\n?)~","\n>From $1$2\n",$body);
01239 $feed.= "\n";
01240 $feed.= "\n";
01241 }
01242 return $feed;
01243 }
01244
01251 function _generateFilename() {
01252 $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
01253 return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".mbox";
01254 }
01255 }
01256
01257
01265 class OPMLCreator extends FeedCreator {
01266
01267 function OPMLCreator() {
01268 $this->encoding = "utf-8";
01269 }
01270
01271 function createFeed() {
01272 $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
01273 $feed.= $this->_createGeneratorComment();
01274 $feed.= $this->_createStylesheetReferences();
01275 $feed.= "<opml xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
01276 $feed.= " <head>\n";
01277 $feed.= " <title>".htmlspecialchars($this->title)."</title>\n";
01278 if ($this->pubDate!="") {
01279 $date = new FeedDate($this->pubDate);
01280 $feed.= " <dateCreated>".$date->rfc822()."</dateCreated>\n";
01281 }
01282 if ($this->lastBuildDate!="") {
01283 $date = new FeedDate($this->lastBuildDate);
01284 $feed.= " <dateModified>".$date->rfc822()."</dateModified>\n";
01285 }
01286 if ($this->editor!="") {
01287 $feed.= " <ownerName>".$this->editor."</ownerName>\n";
01288 }
01289 if ($this->editorEmail!="") {
01290 $feed.= " <ownerEmail>".$this->editorEmail."</ownerEmail>\n";
01291 }
01292 $feed.= " </head>\n";
01293 $feed.= " <body>\n";
01294 for ($i=0;$i<count($this->items);$i++) {
01295 $feed.= " <outline type=\"rss\" ";
01296 $title = htmlspecialchars(strip_tags(strtr($this->items[$i]->title,"\n\r"," ")));
01297 $feed.= " title=\"".$title."\"";
01298 $feed.= " text=\"".$title."\"";
01299
01300 $feed.= " url=\"".htmlspecialchars($this->items[$i]->link)."\"";
01301 $feed.= "/>\n";
01302 }
01303 $feed.= " </body>\n";
01304 $feed.= "</opml>\n";
01305 return $feed;
01306 }
01307 }
01308
01309
01310
01322 class HTMLCreator extends FeedCreator {
01323
01324 var $contentType = "text/html";
01325
01329 var $header;
01330
01334 var $footer ;
01335
01340 var $separator;
01341
01346 var $stylePrefix;
01347
01351 var $openInNewWindow = true;
01352
01353 var $imageAlign ="right";
01354
01362 var $stylelessOutput ="";
01363
01368 function createFeed() {
01369
01370 if ($this->stylelessOutput!="") {
01371 return $this->stylelessOutput;
01372 }
01373
01374
01375 if ($this->stylePrefix=="") {
01376 $this->stylePrefix = str_replace(".", "_", $this->_generateFilename())."_";
01377 }
01378
01379
01380 if ($this->openInNewWindow) {
01381 $targetInsert = " target='_blank'";
01382 }
01383
01384
01385 $feedArray = array();
01386 if ($this->image!=null) {
01387 $imageStr = "<a href='".$this->image->link."'".$targetInsert.">".
01388 "<img src='".$this->image->url."' border='0' alt='".
01389 FeedCreator::iTrunc(htmlspecialchars($this->image->title),100).
01390 "' align='".$this->imageAlign."' ";
01391 if ($this->image->width) {
01392 $imageStr .=" width='".$this->image->width. "' ";
01393 }
01394 if ($this->image->height) {
01395 $imageStr .=" height='".$this->image->height."' ";
01396 }
01397 $imageStr .="/></a>";
01398 $feedArray[] = $imageStr;
01399 }
01400
01401 if ($this->title) {
01402 $feedArray[] = "<div class='".$this->stylePrefix."title'><a href='".$this->link."' ".$targetInsert." class='".$this->stylePrefix."title'>".
01403 FeedCreator::iTrunc(htmlspecialchars($this->title),100)."</a></div>";
01404 }
01405 if ($this->getDescription()) {
01406 $feedArray[] = "<div class='".$this->stylePrefix."description'>".
01407 str_replace("]]>", "", str_replace("<![CDATA[", "", $this->getDescription())).
01408 "</div>";
01409 }
01410
01411 if ($this->header) {
01412 $feedArray[] = "<div class='".$this->stylePrefix."header'>".$this->header."</div>";
01413 }
01414
01415 for ($i=0;$i<count($this->items);$i++) {
01416 if ($this->separator and $i > 0) {
01417 $feedArray[] = "<div class='".$this->stylePrefix."separator'>".$this->separator."</div>";
01418 }
01419
01420 if ($this->items[$i]->title) {
01421 if ($this->items[$i]->link) {
01422 $feedArray[] =
01423 "<div class='".$this->stylePrefix."item_title'><a href='".$this->items[$i]->link."' class='".$this->stylePrefix.
01424 "item_title'".$targetInsert.">".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100).
01425 "</a></div>";
01426 } else {
01427 $feedArray[] =
01428 "<div class='".$this->stylePrefix."item_title'>".
01429 FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),100).
01430 "</div>";
01431 }
01432 }
01433 if ($this->items[$i]->getDescription()) {
01434 $feedArray[] =
01435 "<div class='".$this->stylePrefix."item_description'>".
01436 str_replace("]]>", "", str_replace("<![CDATA[", "", $this->items[$i]->getDescription())).
01437 "</div>";
01438 }
01439 }
01440 if ($this->footer) {
01441 $feedArray[] = "<div class='".$this->stylePrefix."footer'>".$this->footer."</div>";
01442 }
01443
01444 $feed= "".join($feedArray, "\r\n");
01445 return $feed;
01446 }
01447
01455 function _generateFilename() {
01456 $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
01457 return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".html";
01458 }
01459 }
01460
01461
01468 class JSCreator extends HTMLCreator {
01469 var $contentType = "text/javascript";
01470
01475 function createFeed()
01476 {
01477 $feed = parent::createFeed();
01478 $feedArray = explode("\n",$feed);
01479
01480 $jsFeed = "";
01481 foreach ($feedArray as $value) {
01482 $jsFeed .= "document.write('".trim(addslashes($value))."');\n";
01483 }
01484 return $jsFeed;
01485 }
01486
01494 function _generateFilename() {
01495 $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
01496 return substr($fileInfo["basename"],0,-(strlen($fileInfo["extension"])+1)).".js";
01497 }
01498
01499 }
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01560 ?>