CWIS Developer Documentation
RSS.php
Go to the documentation of this file.
1 <?PHP
2 #
3 # Axis--RSS.php
4 # An Object to Support RSS 0.92 (Rich Site Summary) Output
5 #
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).
10 #
11 # Part of the AxisPHP library v1.2.5
12 # For more information see http://www.axisdata.com/AxisPHP/
13 #
14 
15 class RSS {
16 
17  # ---- PUBLIC INTERFACE --------------------------------------------------
18 
19  public function RSS()
20  {
21  $this->ChannelCount = -1;
22 
23  # default encoding is UTF-8
24  $this->Encoding = "UTF-8";
25  }
26 
27  # required channel values
28  public function AddChannel($Title, $Link, $Description, $RssLink)
29  {
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;
37  }
38  public function SetImage($Url, $Height = NULL, $Width = NULL, $Description = NULL)
39  {
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;
44  }
45 
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); }
56  public function SetTextInput($Title, $Description, $Name)
57  {
58  $this->Channels[$this->ChannelCount]["TextInputTitle"] = $Title;
59  $this->Channels[$this->ChannelCount]["TextInputDescription"] = $Description;
60  $this->Channels[$this->ChannelCount]["TextInputName"] = $Name;
61  }
62  public function SetSkipTimes($Days, $Hours)
63  {
64  # ???
65  }
66  public function SetCloud($Domain, $Port, $Path, $Procedure, $Protocol)
67  {
68  # ???
69  }
70 
71  # add item to channel
72  public function AddItem($Title = NULL, $Link = NULL, $Description = NULL, $Date = NULL)
73  {
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);
79  }
80  public function AddItemAuthor($Email)
81  {
82  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Author"] = $Email;
83  }
84  public function AddItemCategory($Category, $Url = NULL)
85  {
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;
89  }
90  public function AddItemComments($Url)
91  {
92  $this->Items[$this->ChannelCount][$this->ItemCounts[$this->ChannelCount]]["Comments"] = $Url;
93  }
94  public function AddItemEnclosure($Url, $Length, $Type)
95  {
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;
99  }
100 
101  # write out and RSS page
102  public function PrintRSS()
103  {
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);
108 
109  # for each channel
110  for ($this->ChannelIndex = 0; $this->ChannelIndex <= $this->ChannelCount; $this->ChannelIndex++)
111  {
112  # open channel element
113  $this->FTOut("<channel>");
114 
115  # print required channel elements
116  $this->PrintChannelElement("Title", "title");
117  $this->PrintChannelElement("Link", "link");
118  $this->PrintChannelElement("Description", "description");
119  $this->FTOut(
120  "<atom:link href='"
121  .$this->Channels[$this->ChannelCount]["RssLink"]
122  ."' rel='self' type='application/rss+xml' />");
123 
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"))
127  {
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>");
136  }
137 
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>");
149 
150  # for each item in this channel
151  for ($this->ItemIndex = 0; $this->ItemIndex <= $this->ItemCounts[$this->ChannelCount]; $this->ItemIndex++)
152  {
153  # open item element
154  $this->FTOut("<item>");
155 
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))
164  {
165  $this->FTOut("<author>" . $this->Items[$this->ChannelIndex][$this->ItemIndex]["Author"] . "</author>");
166  }
167  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["Category"]))
168  {
169  foreach ($this->Items[$this->ChannelIndex][$this->ItemIndex]["Category"] as $Count => $Category)
170  {
171  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["CategoryUrl"][$Count])
172  && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["CategoryUrl"][$Count]) != NULL)
173  {
174  $this->FTOut("<category domain='".$this->Items[$this->ChannelIndex][$this->ItemIndex]["CategoryUrl"][$Count]."'>"
175  . $Category . "</category>");
176  }
177  else
178  {
179  $this->FTOut("<category>". $Category . "</category>");
180  }
181  }
182  }
183  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["Comments"])
184  && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["Comments"] != NULL))
185  {
186  $this->FTOut("<comments>" . $this->Items[$this->ChannelIndex][$this->ItemIndex]["Comments"] . "</comments>");
187  }
188  if (isset($this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureUrl"])
189  && ($this->Items[$this->ChannelIndex][$this->ItemIndex]["EnclosureUrl"] != NULL))
190  {
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"]."' />");
195  }
196 
197  # close item element
198  $this->FTOut("</item>");
199  }
200 
201  # close channel element
202  $this->FTOut("</channel>");
203  }
204 
205  # print closing elements
206  $this->FTOut("</rss>");
207  }
208 
209 
210  # ---- PRIVATE INTERFACE -------------------------------------------------
211 
212  private $CategoryCount;
213  private $ChannelCount;
214  private $ChannelIndex;
215  private $Channels;
216  private $Encoding;
217  private $ItemCounts;
218  private $ItemIndex;
219  private $Items;
220 
226  private function IsChannelElementSet($VarName)
227  {
228  return (isset($this->Channels[$this->ChannelIndex][$VarName])
229  && $this->Channels[$this->ChannelIndex][$VarName] != NULL
230  && strlen($this->Channels[$this->ChannelIndex][$VarName]));
231  }
232 
238  private function IsItemElementSet($VarName)
239  {
240  return (isset($this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName])
241  && $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName] != NULL);
242  }
243 
249  private function PrintChannelElement($VarName, $TagName)
250  {
251  # only print channel elements if set
252  if (!$this->IsChannelElementSet($VarName))
253  {
254  return;
255  }
256 
257  $InnerText = $this->EscapeInnerText(
258  $this->Channels[$this->ChannelIndex][$VarName]);
259 
260  $this->FTOut("<${TagName}>".$InnerText."</${TagName}>");
261  }
262 
266  private function PrintChannelCategories()
267  {
268  # only print categories if there is at least one
269  if (!isset($this->Channels[$this->ChannelIndex]["Category"]))
270  {
271  return;
272  }
273 
274  foreach ($this->Channels[$this->ChannelIndex]["Category"] as $Category)
275  {
276  $InnerText = $this->EscapeInnerText($Category);
277  $this->FTOut("<category>".$InnerText."</category>");
278  }
279  }
280 
286  private function PrintItemElement($VarName, $TagName)
287  {
288  # only print elements that are set
289  if (!$this->IsItemElementSet($VarName))
290  {
291  return;
292  }
293 
294  # do not escape inner text for description
295  if ($VarName == "Description")
296  {
297  $InnerText = $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName];
298  }
299  else
300  {
301  $InnerText = $this->EscapeInnerText(
302  $this->Items[$this->ChannelIndex][$this->ItemIndex][$VarName]);
303  }
304 
305  $this->FTOut("<${TagName}>".$InnerText."</${TagName}>");
306  }
307 
315  private function FormatDate($Value)
316  {
317  return date("D, j M Y H:i:s O", strtotime($Value));
318  }
319 
326  private function EscapeInnerText($Text)
327  {
328  # remove control characters
329  $Intermediate = preg_replace("/[\\x00-\\x1F]+/", "", $Text);
330 
331  # escape XML special characters for PHP version < 5.2.3
332  if (version_compare(phpversion(), "5.2.3", "<"))
333  {
334  $Intermediate = htmlspecialchars(
335  $Intermediate, ENT_QUOTES, $this->Encoding);
336  }
337 
338  # escape XML special characters for PHP version >= 5.2.3
339  else
340  {
341  $Intermediate = htmlspecialchars(
342  $Intermediate, ENT_QUOTES, $this->Encoding, FALSE);
343  }
344 
345  # map named entities to their hex references
346  $Replacements = array(
347  "&amp;" => "&#x26;",
348  "&lt;" => "&#x3C;",
349  "&gt;" => "&#x3E;",
350  "&quot;" => "&#x22;",
351  "&rsquo;" => "&#x2019;",
352  "&#039;" => "&#x27;");
353 
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),
359  $Intermediate);
360 
361  return $Intermediate;
362  }
363 
364  # (FTOut == Formatted Tag Output)
365  private function FTOut($String, $NewIndent = NULL)
366  {
367  static $Indent = 0;
368 
369  $IndentSize = 4;
370 
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--; }
373 
374  # reset indent if value is supplied
375  if ($NewIndent != NULL) { $Indent = $NewIndent; }
376 
377  # print string
378  print(substr(" ",
379  0, ($Indent * $IndentSize)).$String."\n");
380 
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))
385  {
386  $Indent++;
387  }
388  }
389 }
AddItemAuthor($Email)
Definition: RSS.php:80
SetSkipTimes($Days, $Hours)
Definition: RSS.php:62
RSS()
Definition: RSS.php:19
AddItem($Title=NULL, $Link=NULL, $Description=NULL, $Date=NULL)
Definition: RSS.php:72
PrintRSS()
Definition: RSS.php:102
SetTextInput($Title, $Description, $Name)
Definition: RSS.php:56
AddChannel($Title, $Link, $Description, $RssLink)
Definition: RSS.php:28
SetCopyright($Value)
Definition: RSS.php:49
SetCloud($Domain, $Port, $Path, $Procedure, $Protocol)
Definition: RSS.php:66
SetPublicationDate($Value)
Definition: RSS.php:54
SetLanguage($Value)
Definition: RSS.php:48
SetWebmaster($Value)
Definition: RSS.php:51
AddItemComments($Url)
Definition: RSS.php:90
AddCategory($Value)
Definition: RSS.php:52
SetLastChangeDate($Value)
Definition: RSS.php:55
SetEncoding($Value)
Definition: RSS.php:47
AddItemCategory($Category, $Url=NULL)
Definition: RSS.php:84
SetPicsRating($Value)
Definition: RSS.php:53
SetImage($Url, $Height=NULL, $Width=NULL, $Description=NULL)
Definition: RSS.php:38
AddItemEnclosure($Url, $Length, $Type)
Definition: RSS.php:94
Definition: RSS.php:15
SetManagingEditor($Value)
Definition: RSS.php:50