4 # An Object to Support RSS 0.92 (Rich Site Summary) Output 6 # Copyright 2002-2016 Axis Data 7 # This code is free software that can be used or redistributed under the 8 # terms of Version 2 of the GNU General Public License, as published by the 9 # Free Software Foundation (http://www.fsf.org). 11 # Part of the AxisPHP library v1.2.5 12 # For more information see http://www.axisdata.com/AxisPHP/ 17 # ---- PUBLIC INTERFACE -------------------------------------------------- 21 $this->ChannelCount = -1;
23 # default encoding is UTF-8 24 $this->Encoding =
"UTF-8";
27 # required channel values 28 public function AddChannel($Title, $Link, $Description, $RssLink)
30 $this->ChannelCount++;
31 $this->ItemCounts[$this->ChannelCount] = -1;
32 $this->Channels[$this->ChannelCount][
"Title"] = $Title;
33 $this->Channels[$this->ChannelCount][
"Link"] = $Link;
34 $this->Channels[$this->ChannelCount][
"Description"] = $Description;
35 $this->Channels[$this->ChannelCount][
"RssLink"] = $RssLink;
36 $this->Channels[$this->ChannelCount][
"CategoryCount"] = 0;
38 public function SetImage($Url, $Height = NULL, $Width = NULL, $Description = NULL)
40 $this->Channels[$this->ChannelCount][
"ImageUrl"] = $Url;
41 $this->Channels[$this->ChannelCount][
"ImageHeight"] = $Height;
42 $this->Channels[$this->ChannelCount][
"ImageWidth"] = $Width;
43 $this->Channels[$this->ChannelCount][
"ImageDescription"] = $Description;
46 # optional channel values 47 public function SetEncoding($Value) { $this->Encoding = $Value; }
48 public function SetLanguage($Value) { $this->Channels[$this->ChannelCount][
"Language"] = $Value; }
49 public function SetCopyright($Value) { $this->Channels[$this->ChannelCount][
"Copyright"] = $Value; }
50 public function SetManagingEditor($Value) { $this->Channels[$this->ChannelCount][
"ManagingEditor"] = $Value; }
51 public function SetWebmaster($Value) { $this->Channels[$this->ChannelCount][
"Webmaster"] = $Value; }
52 public function AddCategory($Value) { $this->Channels[$this->ChannelCount][
"Category"][] = $Value; }
53 public function SetPicsRating($Value) { $this->Channels[$this->ChannelCount][
"PicsRating"] = $Value; }
54 public function SetPublicationDate($Value) { $this->Channels[$this->ChannelCount][
"PublicationDate"] = $this->FormatDate($Value); }
55 public function SetLastChangeDate($Value) { $this->Channels[$this->ChannelCount][
"LastChangeDate"] = $this->FormatDate($Value); }
58 $this->Channels[$this->ChannelCount][
"TextInputTitle"] = $Title;
59 $this->Channels[$this->ChannelCount][
"TextInputDescription"] = $Description;
60 $this->Channels[$this->ChannelCount][
"TextInputName"] = $Name;
66 public function SetCloud($Domain, $Port, $Path, $Procedure, $Protocol)
72 public function AddItem($Title = NULL, $Link = NULL, $Description = NULL, $Date = NULL)
74 $this->ItemCounts[$this->ChannelCount]++;
75 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"Title"] = $Title;
76 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"Link"] = $Link;
77 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"Description"] = $Description;
78 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"Date"] = $this->FormatDate($Date);
82 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"Author"] = $Email;
86 $this->CategoryCount++;
87 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"Category"][$this->CategoryCount] = $Category;
88 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"CategoryUrl"][$this->CategoryCount] = $Url;
92 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"Comments"] = $Url;
96 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"EnclosureUrl"] = $Url;
97 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"EnclosureLength"] = $Length;
98 $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]][
"EnclosureType"] = $Type;
101 # write out and RSS page 104 # print opening elements 105 header(
"Content-type: application/rss+xml; charset=".$this->Encoding, TRUE);
106 $this->FTOut(
"<?xml version='1.0' encoding='".$this->Encoding.
"' ?>");
107 $this->FTOut(
"<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>", 0);
110 for ($this->ChannelIndex = 0; $this->ChannelIndex <= $this->ChannelCount; $this->ChannelIndex++)
112 # open channel element 113 $this->FTOut(
"<channel>");
115 # print required channel elements 116 $this->PrintChannelElement(
"Title",
"title");
117 $this->PrintChannelElement(
"Link",
"link");
118 $this->PrintChannelElement(
"Description",
"description");
121 .$this->Channels[$this->ChannelCount][
"RssLink"]
122 .
"' rel='self' type='application/rss+xml' />");
124 # print image element if set (url, title, link required) 125 # title and link should be the same as those for the channel 126 if ($this->IsChannelElementSet(
"ImageUrl"))
128 $this->FTOut(
"<image>");
129 $this->PrintChannelElement(
"ImageUrl",
"url");
130 $this->PrintChannelElement(
"Title",
"title");
131 $this->PrintChannelElement(
"Link",
"link");
132 $this->PrintChannelElement(
"ImageWidth",
"width");
133 $this->PrintChannelElement(
"ImageHeight",
"height");
134 $this->PrintChannelElement(
"ImageDescription",
"description");
135 $this->FTOut(
"</image>");
138 # print optional channel elements 139 $this->PrintChannelElement(
"Language",
"language");
140 $this->PrintChannelElement(
"Copyright",
"copyright");
141 $this->PrintChannelElement(
"ManagingEditor",
"managingEditor");
142 $this->PrintChannelElement(
"Webmaster",
"webMaster");
143 $this->PrintChannelCategories();
144 $this->PrintChannelElement(
"PicsRating",
"rating");
145 $this->PrintChannelElement(
"PublicationDate",
"pubDate");
146 $this->PrintChannelElement(
"LastChangeDate",
"lastBuildDate");
147 # ??? STILL TO DO: SkipDays, SkipHours, Cloud 148 $this->FTOut(
"<docs>http://www.rssboard.org/rss-2-0-1</docs>");
150 # for each item in this channel 151 for ($this->ItemIndex = 0; $this->ItemIndex <= $this->ItemCounts[$this->ChannelCount]; $this->ItemIndex++)
154 $this->FTOut(
"<item>");
156 # print item elements 157 $this->PrintItemElement(
"Title",
"title");
158 $this->PrintItemElement(
"Link",
"link");
159 $this->PrintItemElement(
"Link",
"guid");
160 $this->PrintItemElement(
"Description",
"description");
161 $this->PrintItemElement(
"Date",
"pubDate");
162 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Author"])
163 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Author"] != NULL))
165 $this->FTOut(
"<author>" . $this->Items[$this->ChannelIndex][$this->ItemIndex][
"Author"] .
"</author>");
167 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Category"]))
169 foreach ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Category"] as $Count => $Category)
171 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"CategoryUrl"][$Count])
172 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"CategoryUrl"][$Count]) != NULL)
174 $this->FTOut(
"<category domain='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"CategoryUrl"][$Count].
"'>" 175 . $Category .
"</category>");
179 $this->FTOut(
"<category>". $Category .
"</category>");
183 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Comments"])
184 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Comments"] != NULL))
186 $this->FTOut(
"<comments>" . $this->Items[$this->ChannelIndex][$this->ItemIndex][
"Comments"] .
"</comments>");
188 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureUrl"])
189 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureUrl"] != NULL))
191 $this->FTOut(
"<enclosure " 192 .
"url='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureUrl"].
"' " 193 .
"length='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureLength"].
"' " 194 .
"type='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureType"].
"' />");
198 $this->FTOut(
"</item>");
201 # close channel element 202 $this->FTOut(
"</channel>");
205 # print closing elements 206 $this->FTOut(
"</rss>");
210 # ---- PRIVATE INTERFACE ------------------------------------------------- 212 private $CategoryCount;
213 private $ChannelCount;
214 private $ChannelIndex;
226 private function IsChannelElementSet($VarName)
228 return (isset($this->Channels[$this->ChannelIndex][$VarName])
229 && $this->Channels[$this->ChannelIndex][$VarName] != NULL
230 && strlen($this->Channels[$this->ChannelIndex][$VarName]));
238 private function IsItemElementSet($VarName)
240 return (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName])
241 && $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName] != NULL);
249 private function PrintChannelElement($VarName, $TagName)
251 # only print channel elements if set 252 if (!$this->IsChannelElementSet($VarName))
257 $InnerText = $this->EscapeInnerText(
258 $this->Channels[$this->ChannelIndex][$VarName]);
260 $this->FTOut(
"<${TagName}>".$InnerText.
"</${TagName}>");
266 private function PrintChannelCategories()
268 # only print categories if there is at least one 269 if (!isset($this->Channels[$this->ChannelIndex][
"Category"]))
274 foreach ($this->Channels[$this->ChannelIndex][
"Category"] as $Category)
276 $InnerText = $this->EscapeInnerText($Category);
277 $this->FTOut(
"<category>".$InnerText.
"</category>");
286 private function PrintItemElement($VarName, $TagName)
288 # only print elements that are set 289 if (!$this->IsItemElementSet($VarName))
294 # do not escape inner text for description 295 if ($VarName ==
"Description")
297 $InnerText = $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName];
301 $InnerText = $this->EscapeInnerText(
302 $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName]);
305 $this->FTOut(
"<${TagName}>".$InnerText.
"</${TagName}>");
315 private function FormatDate($Value)
317 return date(
"D, j M Y H:i:s O", strtotime($Value));
326 private function EscapeInnerText($Text)
328 # remove control characters 329 $Intermediate = preg_replace(
"/[\\x00-\\x1F]+/",
"", $Text);
331 # escape XML special characters for PHP version < 5.2.3 332 if (version_compare(phpversion(),
"5.2.3",
"<"))
334 $Intermediate = htmlspecialchars(
335 $Intermediate, ENT_QUOTES, $this->Encoding);
338 # escape XML special characters for PHP version >= 5.2.3 341 $Intermediate = htmlspecialchars(
342 $Intermediate, ENT_QUOTES, $this->Encoding, FALSE);
345 # map named entities to their hex references 346 $Replacements = array(
350 """ =>
""",
351 "’" =>
"’",
352 "'" =>
"'");
354 # replace named entities with hex references for compatibility as 355 # specified by the RSS spec/best practices 356 $Intermediate = str_replace(
357 array_keys($Replacements),
358 array_values($Replacements),
361 return $Intermediate;
364 # (FTOut == Formatted Tag Output) 365 private function FTOut($String, $NewIndent = NULL)
371 # decrease indent if string contains end tag and does not start with begin tag 372 if (preg_match(
"/<\/[A-Za-z0-9]+>/", $String) && !preg_match(
"/^<[^\/]+/", $String)) { $Indent--; }
374 # reset indent if value is supplied 375 if ($NewIndent != NULL) { $Indent = $NewIndent; }
379 0, ($Indent * $IndentSize)).$String.
"\n");
381 # inrease indent if string starts with begin tag and does not contain end tag 382 if (preg_match(
"/^<[^\/]+/", $String)
383 && !preg_match(
"/<\/[A-Za-z0-9]+>/", $String)
384 && !preg_match(
"/\/>$/", $String))