Axis--RSS.php
Go to the documentation of this file.
00001 <?PHP 00002 00003 # 00004 # Axis--RSS.php 00005 # An Object to Support RSS 0.92 (Rich Site Summary) Output 00006 # 00007 # Copyright 2002 Axis Data 00008 # This code is free software that can be used or redistributed under the 00009 # terms of Version 2 of the GNU General Public License, as published by the 00010 # Free Software Foundation (http://www.fsf.org). 00011 # 00012 # Author: Edward Almasy (almasy@axisdata.com) 00013 # 00014 # Part of the AxisPHP library v1.2.5 00015 # For more information see http://www.axisdata.com/AxisPHP/ 00016 # 00017 00018 00019 class RSS { 00020 00021 # ---- PUBLIC INTERFACE -------------------------------------------------- 00022 00023 function RSS() 00024 { 00025 $this->ChannelCount = -1; 00026 00027 # default encoding is UTF-8 00028 $this->Encoding = "UTF-8"; 00029 } 00030 00031 # required channel values 00032 function AddChannel($Title, $Link, $Description, $RssLink) 00033 { 00034 $this->ChannelCount++; 00035 $this->ItemCounts[$this->ChannelCount] = -1; 00036 $this->Channels[$this->ChannelCount]["Title"] = $Title; 00037 $this->Channels[$this->ChannelCount]["Link"] = $Link; 00038 $this->Channels[$this->ChannelCount]["Description"] = $Description; 00039 $this->Channels[$this->ChannelCount]["RssLink"] = $RssLink; 00040 } 00041 function SetImage($Url, $Height = NULL, $Width = NULL, $Description = NULL) 00042 { 00043 $this->Channels[$this->ChannelCount]["ImageUrl"] = $Url; 00044 $this->Channels[$this->ChannelCount]["ImageHeight"] = $Height; 00045 $this->Channels[$this->ChannelCount]["ImageWidth"] = $Width; 00046 $this->Channels[$this->ChannelCount]["ImageDescription"] = $Description; 00047 } 00048 00049 # optional channel values 00050 function SetEncoding($Value) { $this->Encoding = $Value; } 00051 function SetLanguage($Value) { $this->Channels[$this->ChannelCount]["Language"] = $Value; } 00052 function SetCopyright($Value) { $this->Channels[$this->ChannelCount]["Copyright"] = $Value; } 00053 function SetManagingEditor($Value) { $this->Channels[$this->ChannelCount]["ManagingEditor"] = $Value; } 00054 function SetWebmaster($Value) { $this->Channels[$this->ChannelCount]["Webmaster"] = $Value; } 00055 function SetPicsRating($Value) { $this->Channels[$this->ChannelCount]["PicsRating"] = $Value; } 00056 function SetPublicationDate($Value) { $this->Channels[$this->ChannelCount]["PublicationDate"] = $this->FormatDate($Value); } 00057 function SetLastChangeDate($Value) { $this->Channels[$this->ChannelCount]["LastChangeDate"] = $this->FormatDate($Value); } 00058 function SetTextInput($Title, $Description, $Name) 00059 { 00060 $this->Channels[$this->ChannelCount]["TextInputTitle"] = $Title; 00061 $this->Channels[$this->ChannelCount]["TextInputDescription"] = $Description; 00062 $this->Channels[$this->ChannelCount]["TextInputName"] = $Name; 00063 } 00064 function SetSkipTimes($Days, $Hours) 00065 { 00066 # ??? 00067 } 00068 function SetCloud($Domain, $Port, $Path, $Procedure, $Protocol) 00069 { 00070 # ??? 00071 } 00072 00073 # add item to channel 00074 function AddItem($Title = NULL, $Link = NULL, $Description = NULL, $Date = NULL) 00075 { 00076 $this->ItemCounts[$this->ChannelCount]++; 00077 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Title"] = $Title; 00078 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Link"] = $Link; 00079 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Description"] = $Description; 00080 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Date"] = $this->FormatDate($Date); 00081 } 00082 function AddItemCategory($Category, $Url) 00083 { 00084 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Category"] = $Category; 00085 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["CategoryUrl"] = $Url; 00086 } 00087 function AddItemEnclosure($Url, $Length, $Type) 00088 { 00089 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["EnclosureUrl"] = $Url; 00090 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["EnclosureLength"] = $Length; 00091 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["EnclosureType"] = $Type; 00092 } 00093 function AddItemSource($Source, $Url) 00094 { 00095 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Source"] = $Source; 00096 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["SourceUrl"] = $Url; 00097 } 00098 00099 # write out and RSS page 00100 function PrintRSS() 00101 { 00102 # print opening elements 00103 header("Content-type: application/rss+xml; charset=".$this->Encoding, TRUE); 00104 FTOut("<?xml version='1.0' encoding='".$this->Encoding."' ?>"); 00105 FTOut("<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>", 0); 00106 00107 # for each channel 00108 for ($this->ChannelIndex = 0; $this->ChannelIndex <= $this->ChannelCount; $this->ChannelIndex++) 00109 { 00110 # open channel element 00111 FTOut("<channel>"); 00112 00113 # print required channel elements 00114 $this->PrintChannelElement("Title", "title"); 00115 $this->PrintChannelElement("Link", "link"); 00116 $this->PrintChannelElement("Description", "description"); 00117 FTOut( 00118 "<atom:link href='" 00119 .$this->Channels[$this->ChannelCount]["RssLink"] 00120 ."' rel='self' type='application/rss+xml' />"); 00121 00122 # print image element if set (url, title, link required) 00123 # title and link should be the same as those for the channel 00124 if ($this->IsChannelElementSet("ImageUrl")) 00125 { 00126 FTOut("<image>"); 00127 $this->PrintChannelElement("ImageUrl", "url"); 00128 $this->PrintChannelElement("Title", "title"); 00129 $this->PrintChannelElement("Link", "link"); 00130 $this->PrintChannelElement("ImageWidth", "width"); 00131 $this->PrintChannelElement("ImageHeight", "height"); 00132 $this->PrintChannelElement("ImageDescription", "description"); 00133 FTOut("</image>"); 00134 } 00135 00136 # print optional channel elements 00137 $this->PrintChannelElement("Language", "language"); 00138 $this->PrintChannelElement("Copyright", "copyright"); 00139 $this->PrintChannelElement("ManagingEditor", "managingEditor"); 00140 $this->PrintChannelElement("Webmaster", "webMaster"); 00141 $this->PrintChannelElement("PicsRating", "rating"); 00142 $this->PrintChannelElement("PublicationDate", "pubDate"); 00143 $this->PrintChannelElement("LastChangeDate", "lastBuildDate"); 00144 # ??? STILL TO DO: SkipDays, SkipHours, Cloud 00145 FTOut("<docs>http://www.rssboard.org/rss-2-0-1</docs>"); 00146 00147 # for each item in this channel 00148 for ($this->ItemIndex = 0; $this->ItemIndex <= $this->ItemCounts[$this->ChannelCount]; $this->ItemIndex++) 00149 { 00150 # open item element 00151 FTOut("<item>"); 00152 00153 # print item elements 00154 $this->PrintItemElement("Title", "title"); 00155 $this->PrintItemElement("Link", "link"); 00156 $this->PrintItemElement("Link", "guid"); 00157 $this->PrintItemElement("Description", "description"); 00158 $this->PrintItemElement("Date", "pubDate"); 00159 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["Category"]) 00160 && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["Category"] != NULL)) 00161 { 00162 FTOut("<category url='".$this->Items[$this->ChannelIndex][$this->ItemIndex]["CategoryUrl"]."'>"); 00163 FTOut($this->Items[$this->ChannelIndex][$this->ItemIndex]["Category"]); 00164 FTOut("</category>"); 00165 } 00166 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureUrl"]) 00167 && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureUrl"] != NULL)) 00168 { 00169 FTOut("<enclosure " 00170 ."url='".$this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureUrl"]."' " 00171 ."length='".$this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureLength"]."' " 00172 ."type='".$this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureType"]."' />"); 00173 } 00174 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["Source"]) 00175 && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["Source"] != NULL)) 00176 { 00177 FTOut("<source url='".$this->Items[$this->ChannelIndex][$this->ItemIndex]["SourceUrl"]."'>"); 00178 FTOut($this->Items[$this->ChannelIndex][$this->ItemIndex]["Source"]); 00179 FTOut("</source>"); 00180 } 00181 00182 # close item element 00183 FTOut("</item>"); 00184 } 00185 00186 # close channel element 00187 FTOut("</channel>"); 00188 } 00189 00190 # print closing elements 00191 FTOut("</rss>"); 00192 } 00193 00194 00195 # ---- PRIVATE INTERFACE ------------------------------------------------- 00196 00197 var $Encoding; 00198 var $Channels; 00199 var $Items; 00200 var $ChannelCount; 00201 var $ItemCounts; 00202 var $ChannelIndex; 00203 var $ItemIndex; 00204 00210 private function IsChannelElementSet($VarName) 00211 { 00212 return (isset($this->Channels[$this->ChannelIndex][$VarName]) 00213 && $this->Channels[$this->ChannelIndex][$VarName] != NULL 00214 && strlen($this->Channels[$this->ChannelIndex][$VarName])); 00215 } 00216 00222 private function IsItemElementSet($VarName) 00223 { 00224 return (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName]) 00225 && $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName] != NULL); 00226 } 00227 00233 private function PrintChannelElement($VarName, $TagName) 00234 { 00235 # only print channel elements if set 00236 if (!$this->IsChannelElementSet($VarName)) 00237 { 00238 return; 00239 } 00240 00241 $InnerText = $this->EscapeInnerText( 00242 $this->Channels[$this->ChannelIndex][$VarName]); 00243 00244 FTOut("<${TagName}>".$InnerText."</${TagName}>"); 00245 } 00246 00252 private function PrintItemElement($VarName, $TagName) 00253 { 00254 # only print elements that are set 00255 if (!$this->IsItemElementSet($VarName)) 00256 { 00257 return; 00258 } 00259 00260 $InnerText = $this->EscapeInnerText( 00261 $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName]); 00262 00263 FTOut("<${TagName}>".$InnerText."</${TagName}>"); 00264 } 00265 00273 private function FormatDate($Value) 00274 { 00275 return date("D, j M Y h:i:s O", strtotime($Value)); 00276 } 00277 00284 private function EscapeInnerText($Text) 00285 { 00286 # remove control characters 00287 $Intermediate = preg_replace("/[\\x00-\\x1F]+/", "", $Text); 00288 00289 # escape XML special characters for PHP version < 5.2.3 00290 if (version_compare(phpversion(), "5.2.3", "<")) 00291 { 00292 $Intermediate = htmlspecialchars( 00293 $Intermediate, ENT_QUOTES, $this->Encoding); 00294 } 00295 00296 # escape XML special characters for PHP version >= 5.2.3 00297 else 00298 { 00299 $Intermediate = htmlspecialchars( 00300 $Intermediate, ENT_QUOTES, $this->Encoding, FALSE); 00301 } 00302 00303 # map named entities to their hex references 00304 $Replacements = array( 00305 "&" => "&", 00306 "<" => "<", 00307 ">" => ">", 00308 """ => """, 00309 "'" => "'"); 00310 00311 # replace named entities with hex references for compatibility as 00312 # specified by the RSS spec/best practices 00313 $Intermediate = str_replace( 00314 array_keys($Replacements), 00315 array_values($Replacements), 00316 $Intermediate); 00317 00318 return $Intermediate; 00319 } 00320 00321 } 00322 00323 # (FTOut == Formatted Tag Output) 00324 function FTOut($String, $NewIndent = NULL) 00325 { 00326 static $Indent = 0; 00327 00328 $IndentSize = 4; 00329 00330 # decrease indent if string contains end tag and does not start with begin tag 00331 if (preg_match("/<\/[A-Za-z0-9]+>/", $String) && !preg_match("/^<[^\/]+/", $String)) { $Indent--; } 00332 00333 # reset indent if value is supplied 00334 if ($NewIndent != NULL) { $Indent = $NewIndent; } 00335 00336 # print string 00337 print(substr(" ", 00338 0, ($Indent * $IndentSize)).$String."\n"); 00339 00340 # inrease indent if string starts with begin tag and does not contain end tag 00341 if (preg_match("/^<[^\/]+/", $String) 00342 && !preg_match("/<\/[A-Za-z0-9]+>/", $String) 00343 && !preg_match("/\/>$/", $String)) 00344 { 00345 $Indent++; 00346 } 00347 }