5 # An Object to Support RSS 0.92 (Rich Site Summary) Output
7 # Copyright 2002 Axis Data
8 # This code is free software that can be used or redistributed under the
9 # terms of Version 2 of the GNU General Public License, as published by the
10 # Free Software Foundation (http://www.fsf.org).
12 # Author: Edward Almasy (almasy@axisdata.com)
14 # Part of the AxisPHP library v1.2.5
15 # For more information see http://www.axisdata.com/AxisPHP/
21 # ---- PUBLIC INTERFACE --------------------------------------------------
25 $this->ChannelCount = -1;
27 # default encoding is UTF-8
28 $this->Encoding =
"UTF-8";
31 # required channel values
32 function AddChannel($Title, $Link, $Description, $RssLink)
34 $this->ChannelCount++;
42 function SetImage($Url, $Height = NULL, $Width = NULL, $Description = NULL)
50 # optional channel values
70 function SetCloud($Domain, $Port, $Path, $Procedure, $Protocol)
76 function AddItem($Title = NULL, $Link = NULL, $Description = NULL, $Date = NULL)
90 $this->CategoryCount++;
105 # write out and RSS page
108 # print opening elements
109 header(
"Content-type: application/rss+xml; charset=".$this->Encoding, TRUE);
110 FTOut(
"<?xml version='1.0' encoding='".$this->Encoding.
"' ?>");
111 FTOut(
"<rss version='2.0' xmlns:atom='http://www.w3.org/2005/Atom'>", 0);
114 for ($this->ChannelIndex = 0; $this->ChannelIndex <=
$this->ChannelCount; $this->ChannelIndex++)
116 # open channel element
119 # print required channel elements
120 $this->PrintChannelElement(
"Title",
"title");
121 $this->PrintChannelElement(
"Link",
"link");
122 $this->PrintChannelElement(
"Description",
"description");
125 .$this->Channels[$this->ChannelCount][
"RssLink"]
126 .
"' rel='self' type='application/rss+xml' />");
128 # print image element if set (url, title, link required)
129 # title and link should be the same as those for the channel
130 if ($this->IsChannelElementSet(
"ImageUrl"))
133 $this->PrintChannelElement(
"ImageUrl",
"url");
134 $this->PrintChannelElement(
"Title",
"title");
135 $this->PrintChannelElement(
"Link",
"link");
136 $this->PrintChannelElement(
"ImageWidth",
"width");
137 $this->PrintChannelElement(
"ImageHeight",
"height");
138 $this->PrintChannelElement(
"ImageDescription",
"description");
142 # print optional channel elements
143 $this->PrintChannelElement(
"Language",
"language");
144 $this->PrintChannelElement(
"Copyright",
"copyright");
145 $this->PrintChannelElement(
"ManagingEditor",
"managingEditor");
146 $this->PrintChannelElement(
"Webmaster",
"webMaster");
147 $this->PrintChannelCategories();
148 $this->PrintChannelElement(
"PicsRating",
"rating");
149 $this->PrintChannelElement(
"PublicationDate",
"pubDate");
150 $this->PrintChannelElement(
"LastChangeDate",
"lastBuildDate");
151 # ??? STILL TO DO: SkipDays, SkipHours, Cloud
152 FTOut(
"<docs>http://www.rssboard.org/rss-2-0-1</docs>");
154 # for each item in this channel
155 for ($this->ItemIndex = 0; $this->ItemIndex <= $this->ItemCounts[
$this->ChannelCount]; $this->ItemIndex++)
160 # print item elements
161 $this->PrintItemElement(
"Title",
"title");
162 $this->PrintItemElement(
"Link",
"link");
163 $this->PrintItemElement(
"Link",
"guid");
164 $this->PrintItemElement(
"Description",
"description");
165 $this->PrintItemElement(
"Date",
"pubDate");
166 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Author"])
167 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Author"] != NULL))
169 FTOut(
"<author>" . $this->Items[$this->ChannelIndex][$this->ItemIndex][
"Author"] .
"</author>");
171 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Category"]))
173 foreach ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Category"] as $Count => $Category)
175 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"CategoryUrl"][$Count])
176 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"CategoryUrl"][$Count]) != NULL)
178 FTOut(
"<category domain='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"CategoryUrl"][$Count].
"'>"
179 . $Category .
"</category>");
183 FTOut(
"<category>". $Category .
"</category>");
187 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Comments"])
188 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"Comments"] != NULL))
190 FTOut(
"<comments>" . $this->Items[$this->ChannelIndex][$this->ItemIndex][
"Comments"] .
"</comments>");
192 if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureUrl"])
193 && ($this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureUrl"] != NULL))
196 .
"url='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureUrl"].
"' "
197 .
"length='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureLength"].
"' "
198 .
"type='".$this->Items[$this->ChannelIndex][$this->ItemIndex][
"EnclosureType"].
"' />");
205 # close channel element
209 # print closing elements
214 # ---- PRIVATE INTERFACE -------------------------------------------------
229 private function IsChannelElementSet($VarName)
231 return (isset($this->Channels[$this->ChannelIndex][$VarName])
232 && $this->Channels[$this->ChannelIndex][$VarName] != NULL
233 && strlen($this->Channels[$this->ChannelIndex][$VarName]));
241 private function IsItemElementSet($VarName)
243 return (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName])
244 && $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName] != NULL);
252 private function PrintChannelElement($VarName, $TagName)
254 # only print channel elements if set
255 if (!$this->IsChannelElementSet($VarName))
260 $InnerText = $this->EscapeInnerText(
261 $this->Channels[$this->ChannelIndex][$VarName]);
263 FTOut(
"<${TagName}>".$InnerText.
"</${TagName}>");
269 private function PrintChannelCategories()
271 # only print categories if there is at least one
272 if (!isset($this->Channels[$this->ChannelIndex][
"Category"]))
277 foreach ($this->Channels[$this->ChannelIndex][
"Category"] as $Category)
279 $InnerText = $this->EscapeInnerText($Category);
280 FTOut(
"<category>".$InnerText.
"</category>");
289 private function PrintItemElement($VarName, $TagName)
291 # only print elements that are set
292 if (!$this->IsItemElementSet($VarName))
297 # do not escape inner text for description
298 if ($VarName ==
"Description")
304 $InnerText = $this->EscapeInnerText(
305 $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName]);
308 FTOut(
"<${TagName}>".$InnerText.
"</${TagName}>");
318 private function FormatDate($Value)
320 return date(
"D, j M Y H:i:s O", strtotime($Value));
329 private function EscapeInnerText($Text)
331 # remove control characters
332 $Intermediate = preg_replace(
"/[\\x00-\\x1F]+/",
"", $Text);
334 # escape XML special characters for PHP version < 5.2.3
335 if (version_compare(phpversion(),
"5.2.3",
"<"))
337 $Intermediate = htmlspecialchars(
338 $Intermediate, ENT_QUOTES, $this->Encoding);
341 # escape XML special characters for PHP version >= 5.2.3
344 $Intermediate = htmlspecialchars(
345 $Intermediate, ENT_QUOTES, $this->Encoding, FALSE);
348 # map named entities to their hex references
349 $Replacements = array(
353 """ =>
""",
354 "’" =>
"’",
355 "'" =>
"'");
357 # replace named entities with hex references for compatibility as
358 # specified by the RSS spec/best practices
359 $Intermediate = str_replace(
360 array_keys($Replacements),
361 array_values($Replacements),
364 return $Intermediate;
369 # (FTOut == Formatted Tag Output)
370 function FTOut($String, $NewIndent = NULL)
376 # decrease indent if string contains end tag and does not start with begin tag
377 if (preg_match(
"/<\/[A-Za-z0-9]+>/", $String) && !preg_match(
"/^<[^\/]+/", $String)) { $Indent--; }
379 # reset indent if value is supplied
380 if ($NewIndent != NULL) { $Indent = $NewIndent; }
384 0, ($Indent * $IndentSize)).$String.
"\n");
386 # inrease indent if string starts with begin tag and does not contain end tag
387 if (preg_match(
"/^<[^\/]+/", $String)
388 && !preg_match(
"/<\/[A-Za-z0-9]+>/", $String)
389 && !preg_match(
"/\/>$/", $String))