CWIS Developer Documentation
Axis--RSS.php
Go to the documentation of this file.
1 <?PHP
2 
3 #
4 # Axis--RSS.php
5 # An Object to Support RSS 0.92 (Rich Site Summary) Output
6 #
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).
11 #
12 # Author: Edward Almasy (almasy@axisdata.com)
13 #
14 # Part of the AxisPHP library v1.2.5
15 # For more information see http://www.axisdata.com/AxisPHP/
16 #
17 
18 
19 class RSS {
20 
21  # ---- PUBLIC INTERFACE --------------------------------------------------
22 
23  function RSS()
24  {
25  $this->ChannelCount = -1;
26 
27  # default encoding is UTF-8
28  $this->Encoding = "UTF-8";
29  }
30 
31  # required channel values
32  function AddChannel($Title, $Link, $Description, $RssLink)
33  {
34  $this->ChannelCount++;
35  $this->ItemCounts[$this->ChannelCount] = -1;
36  $this->Channels[$this->ChannelCount]["Title"] = $Title;
37  $this->Channels[$this->ChannelCount]["Link"] = $Link;
38  $this->Channels[$this->ChannelCount]["Description"] = $Description;
39  $this->Channels[$this->ChannelCount]["RssLink"] = $RssLink;
40  $this->Channels[$this->ChannelCount]["CategoryCount"] = 0;
41  }
42  function SetImage($Url, $Height = NULL, $Width = NULL, $Description = NULL)
43  {
44  $this->Channels[$this->ChannelCount]["ImageUrl"] = $Url;
45  $this->Channels[$this->ChannelCount]["ImageHeight"] = $Height;
46  $this->Channels[$this->ChannelCount]["ImageWidth"] = $Width;
47  $this->Channels[$this->ChannelCount]["ImageDescription"] = $Description;
48  }
49 
50  # optional channel values
51  function SetEncoding($Value) { $this->Encoding = $Value; }
52  function SetLanguage($Value) { $this->Channels[$this->ChannelCount]["Language"] = $Value; }
53  function SetCopyright($Value) { $this->Channels[$this->ChannelCount]["Copyright"] = $Value; }
54  function SetManagingEditor($Value) { $this->Channels[$this->ChannelCount]["ManagingEditor"] = $Value; }
55  function SetWebmaster($Value) { $this->Channels[$this->ChannelCount]["Webmaster"] = $Value; }
56  function AddCategory($Value) { $this->Channels[$this->ChannelCount]["Category"][] = $Value; }
57  function SetPicsRating($Value) { $this->Channels[$this->ChannelCount]["PicsRating"] = $Value; }
58  function SetPublicationDate($Value) { $this->Channels[$this->ChannelCount]["PublicationDate"] = $this->FormatDate($Value); }
59  function SetLastChangeDate($Value) { $this->Channels[$this->ChannelCount]["LastChangeDate"] = $this->FormatDate($Value); }
60  function SetTextInput($Title, $Description, $Name)
61  {
62  $this->Channels[$this->ChannelCount]["TextInputTitle"] = $Title;
63  $this->Channels[$this->ChannelCount]["TextInputDescription"] = $Description;
64  $this->Channels[$this->ChannelCount]["TextInputName"] = $Name;
65  }
66  function SetSkipTimes($Days, $Hours)
67  {
68  # ???
69  }
70  function SetCloud($Domain, $Port, $Path, $Procedure, $Protocol)
71  {
72  # ???
73  }
74 
75  # add item to channel
76  function AddItem($Title = NULL, $Link = NULL, $Description = NULL, $Date = NULL)
77  {
78  $this->ItemCounts[$this->ChannelCount]++;
79  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Title"] = $Title;
80  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Link"] = $Link;
81  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Description"] = $Description;
82  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Date"] = $this->FormatDate($Date);
83  }
84  function AddItemAuthor($Email)
85  {
86  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Author"] = $Email;
87  }
88  function AddItemCategory($Category, $Url = NULL)
89  {
90  $this->CategoryCount++;
91  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Category"][$this->CategoryCount] = $Category;
92  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["CategoryUrl"][$this->CategoryCount] = $Url;
93  }
94  function AddItemComments($Url)
95  {
96  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Comments"] = $Url;
97  }
98  function AddItemEnclosure($Url, $Length, $Type)
99  {
100  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["EnclosureUrl"] = $Url;
101  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["EnclosureLength"] = $Length;
102  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["EnclosureType"] = $Type;
103  }
104 
105  # write out and RSS page
106  function PrintRSS()
107  {
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);
112 
113  # for each channel
114  for ($this->ChannelIndex = 0; $this->ChannelIndex <= $this->ChannelCount; $this->ChannelIndex++)
115  {
116  # open channel element
117  FTOut("<channel>");
118 
119  # print required channel elements
120  $this->PrintChannelElement("Title", "title");
121  $this->PrintChannelElement("Link", "link");
122  $this->PrintChannelElement("Description", "description");
123  FTOut(
124  "<atom:link href='"
125  .$this->Channels[$this->ChannelCount]["RssLink"]
126  ."' rel='self' type='application/rss+xml' />");
127 
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"))
131  {
132  FTOut("<image>");
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");
139  FTOut("</image>");
140  }
141 
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>");
153 
154  # for each item in this channel
155  for ($this->ItemIndex = 0; $this->ItemIndex <= $this->ItemCounts[$this->ChannelCount]; $this->ItemIndex++)
156  {
157  # open item element
158  FTOut("<item>");
159 
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))
168  {
169  FTOut("<author>" . $this->Items[$this->ChannelIndex][$this->ItemIndex]["Author"] . "</author>");
170  }
171  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["Category"]))
172  {
173  foreach ($this->Items[$this->ChannelIndex][$this->ItemIndex]["Category"] as $Count => $Category)
174  {
175  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["CategoryUrl"][$Count])
176  && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["CategoryUrl"][$Count]) != NULL)
177  {
178  FTOut("<category domain='".$this->Items[$this->ChannelIndex][$this->ItemIndex]["CategoryUrl"][$Count]."'>"
179  . $Category . "</category>");
180  }
181  else
182  {
183  FTOut("<category>". $Category . "</category>");
184  }
185  }
186  }
187  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["Comments"])
188  && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["Comments"] != NULL))
189  {
190  FTOut("<comments>" . $this->Items[$this->ChannelIndex][$this->ItemIndex]["Comments"] . "</comments>");
191  }
192  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureUrl"])
193  && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureUrl"] != NULL))
194  {
195  FTOut("<enclosure "
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"]."' />");
199  }
200 
201  # close item element
202  FTOut("</item>");
203  }
204 
205  # close channel element
206  FTOut("</channel>");
207  }
208 
209  # print closing elements
210  FTOut("</rss>");
211  }
212 
213 
214  # ---- PRIVATE INTERFACE -------------------------------------------------
215 
218  var $Items;
223 
229  private function IsChannelElementSet($VarName)
230  {
231  return (isset($this->Channels[$this->ChannelIndex][$VarName])
232  && $this->Channels[$this->ChannelIndex][$VarName] != NULL
233  && strlen($this->Channels[$this->ChannelIndex][$VarName]));
234  }
235 
241  private function IsItemElementSet($VarName)
242  {
243  return (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName])
244  && $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName] != NULL);
245  }
246 
252  private function PrintChannelElement($VarName, $TagName)
253  {
254  # only print channel elements if set
255  if (!$this->IsChannelElementSet($VarName))
256  {
257  return;
258  }
259 
260  $InnerText = $this->EscapeInnerText(
261  $this->Channels[$this->ChannelIndex][$VarName]);
262 
263  FTOut("<${TagName}>".$InnerText."</${TagName}>");
264  }
265 
269  private function PrintChannelCategories()
270  {
271  # only print categories if there is at least one
272  if (!isset($this->Channels[$this->ChannelIndex]["Category"]))
273  {
274  return;
275  }
276 
277  foreach ($this->Channels[$this->ChannelIndex]["Category"] as $Category)
278  {
279  $InnerText = $this->EscapeInnerText($Category);
280  FTOut("<category>".$InnerText."</category>");
281  }
282  }
283 
289  private function PrintItemElement($VarName, $TagName)
290  {
291  # only print elements that are set
292  if (!$this->IsItemElementSet($VarName))
293  {
294  return;
295  }
296 
297  # do not escape inner text for description
298  if ($VarName == "Description")
299  {
300  $InnerText = $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName];
301  }
302  else
303  {
304  $InnerText = $this->EscapeInnerText(
305  $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName]);
306  }
307 
308  FTOut("<${TagName}>".$InnerText."</${TagName}>");
309  }
310 
318  private function FormatDate($Value)
319  {
320  return date("D, j M Y H:i:s O", strtotime($Value));
321  }
322 
329  private function EscapeInnerText($Text)
330  {
331  # remove control characters
332  $Intermediate = preg_replace("/[\\x00-\\x1F]+/", "", $Text);
333 
334  # escape XML special characters for PHP version < 5.2.3
335  if (version_compare(phpversion(), "5.2.3", "<"))
336  {
337  $Intermediate = htmlspecialchars(
338  $Intermediate, ENT_QUOTES, $this->Encoding);
339  }
340 
341  # escape XML special characters for PHP version >= 5.2.3
342  else
343  {
344  $Intermediate = htmlspecialchars(
345  $Intermediate, ENT_QUOTES, $this->Encoding, FALSE);
346  }
347 
348  # map named entities to their hex references
349  $Replacements = array(
350  "&amp;" => "&#x26;",
351  "&lt;" => "&#x3C;",
352  "&gt;" => "&#x3E;",
353  "&quot;" => "&#x22;",
354  "&rsquo;" => "&#x2019;",
355  "&#039;" => "&#x27;");
356 
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),
362  $Intermediate);
363 
364  return $Intermediate;
365  }
366 
367 }
368 
369 # (FTOut == Formatted Tag Output)
370 function FTOut($String, $NewIndent = NULL)
371 {
372  static $Indent = 0;
373 
374  $IndentSize = 4;
375 
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--; }
378 
379  # reset indent if value is supplied
380  if ($NewIndent != NULL) { $Indent = $NewIndent; }
381 
382  # print string
383  print(substr(" ",
384  0, ($Indent * $IndentSize)).$String."\n");
385 
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))
390  {
391  $Indent++;
392  }
393 }
AddItemAuthor($Email)
Definition: Axis--RSS.php:84
SetSkipTimes($Days, $Hours)
Definition: Axis--RSS.php:66
$ChannelCount
Definition: Axis--RSS.php:219
RSS()
Definition: Axis--RSS.php:23
$ItemCounts
Definition: Axis--RSS.php:220
AddItem($Title=NULL, $Link=NULL, $Description=NULL, $Date=NULL)
Definition: Axis--RSS.php:76
PrintRSS()
Definition: Axis--RSS.php:106
SetTextInput($Title, $Description, $Name)
Definition: Axis--RSS.php:60
AddChannel($Title, $Link, $Description, $RssLink)
Definition: Axis--RSS.php:32
SetCopyright($Value)
Definition: Axis--RSS.php:53
SetCloud($Domain, $Port, $Path, $Procedure, $Protocol)
Definition: Axis--RSS.php:70
SetPublicationDate($Value)
Definition: Axis--RSS.php:58
SetLanguage($Value)
Definition: Axis--RSS.php:52
SetWebmaster($Value)
Definition: Axis--RSS.php:55
$ChannelIndex
Definition: Axis--RSS.php:221
AddItemComments($Url)
Definition: Axis--RSS.php:94
AddCategory($Value)
Definition: Axis--RSS.php:56
$ItemIndex
Definition: Axis--RSS.php:222
SetLastChangeDate($Value)
Definition: Axis--RSS.php:59
SetEncoding($Value)
Definition: Axis--RSS.php:51
$Items
Definition: Axis--RSS.php:218
$Encoding
Definition: Axis--RSS.php:216
$Channels
Definition: Axis--RSS.php:217
FTOut($String, $NewIndent=NULL)
Definition: Axis--RSS.php:370
AddItemCategory($Category, $Url=NULL)
Definition: Axis--RSS.php:88
SetPicsRating($Value)
Definition: Axis--RSS.php:57
SetImage($Url, $Height=NULL, $Width=NULL, $Description=NULL)
Definition: Axis--RSS.php:42
AddItemEnclosure($Url, $Length, $Type)
Definition: Axis--RSS.php:98
SetManagingEditor($Value)
Definition: Axis--RSS.php:54