1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Feed
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die();
11
12 /**
13 * Class to encapsulate a feed for the Joomla Platform.
14 *
15 * @property JFeedPerson $author Person responsible for feed content.
16 * @property array $categories Categories to which the feed belongs.
17 * @property array $contributors People who contributed to the feed content.
18 * @property string $copyright Information about rights, e.g. copyrights, held in and over the feed.
19 * @property string $description A phrase or sentence describing the feed.
20 * @property string $generator A string indicating the program used to generate the feed.
21 * @property string $image Specifies a GIF, JPEG or PNG image that should be displayed with the feed.
22 * @property JDate $publishedDate The publication date for the feed content.
23 * @property string $title A human readable title for the feed.
24 * @property JDate $updatedDate The last time the content of the feed changed.
25 * @property string $uri Universal, permanent identifier for the feed.
26 *
27 * @since 12.3
28 */
29 class JFeed implements ArrayAccess, Countable
30 {
31 /**
32 * @var array The entry properties.
33 * @since 12.3
34 */
35 protected $properties = array(
36 'uri' => '',
37 'title' => '',
38 'updatedDate' => '',
39 'description' => '',
40 'categories' => array(),
41 'contributors' => array(),
42 );
43
44 /**
45 * @var array The list of feed entry objects.
46 * @since 12.3
47 */
48 protected $entries = array();
49
50 /**
51 * Magic method to return values for feed properties.
52 *
53 * @param string $name The name of the property.
54 *
55 * @return mixed
56 *
57 * @since 12.3
58 */
59 public function __get($name)
60 {
61 return isset($this->properties[$name]) ? $this->properties[$name] : null;
62 }
63
64 /**
65 * Magic method to set values for feed properties.
66 *
67 * @param string $name The name of the property.
68 * @param mixed $value The value to set for the property.
69 *
70 * @return void
71 *
72 * @since 12.3
73 */
74 public function __set($name, $value)
75 {
76 // Ensure that setting a date always sets a JDate instance.
77 if ((($name == 'updatedDate') || ($name == 'publishedDate')) && !($value instanceof JDate))
78 {
79 $value = new JDate($value);
80 }
81
82 // Validate that any authors that are set are instances of JFeedPerson or null.
83 if (($name == 'author') && (!($value instanceof JFeedPerson) || ($value === null)))
84 {
85 throw new InvalidArgumentException('JFeed "author" must be of type JFeedPerson. ' . gettype($value) . 'given.');
86 }
87
88 // Disallow setting categories or contributors directly.
89 if (($name == 'categories') || ($name == 'contributors'))
90 {
91 throw new InvalidArgumentException('Cannot directly set JFeed property "' . $name . '".');
92 }
93
94 $this->properties[$name] = $value;
95 }
96
97 /**
98 * Method to add a category to the feed object.
99 *
100 * @param string $name The name of the category to add.
101 * @param string $uri The optional URI for the category to add.
102 *
103 * @return JFeed
104 *
105 * @since 12.3
106 */
107 public function addCategory($name, $uri = '')
108 {
109 $this->properties['categories'][$name] = $uri;
110
111 return $this;
112 }
113
114 /**
115 * Method to add a contributor to the feed object.
116 *
117 * @param string $name The full name of the person to add.
118 * @param string $email The email address of the person to add.
119 * @param string $uri The optional URI for the person to add.
120 * @param string $type The optional type of person to add.
121 *
122 * @return JFeed
123 *
124 * @since 12.3
125 */
126 public function addContributor($name, $email, $uri = null, $type = null)
127 {
128 $contributor = new JFeedPerson($name, $email, $uri, $type);
129
130 // If the new contributor already exists then there is nothing to do, so just return.
131 foreach ($this->properties['contributors'] as $c)
132 {
133 if ($c == $contributor)
134 {
135 return $this;
136 }
137 }
138
139 // Add the new contributor.
140 $this->properties['contributors'][] = $contributor;
141
142 return $this;
143 }
144
145 /**
146 * Method to add an entry to the feed object.
147 *
148 * @param JFeedEntry $entry The entry object to add.
149 *
150 * @return JFeed
151 *
152 * @since 12.3
153 */
154 public function addEntry(JFeedEntry $entry)
155 {
156 // If the new entry already exists then there is nothing to do, so just return.
157 foreach ($this->entries as $e)
158 {
159 if ($e == $entry)
160 {
161 return $this;
162 }
163 }
164
165 // Add the new entry.
166 $this->entries[] = $entry;
167
168 return $this;
169 }
170
171 /**
172 * Returns a count of the number of entries in the feed.
173 *
174 * This method is here to implement the Countable interface.
175 * You can call it by doing count($feed) rather than $feed->count();
176 *
177 * @return integer number of entries in the feed.
178 */
179 public function count()
180 {
181 return count($this->entries);
182 }
183
184 /**
185 * Whether or not an offset exists. This method is executed when using isset() or empty() on
186 * objects implementing ArrayAccess.
187 *
188 * @param mixed $offset An offset to check for.
189 *
190 * @return boolean
191 *
192 * @see ArrayAccess::offsetExists()
193 * @since 12.3
194 */
195 public function offsetExists($offset)
196 {
197 return isset($this->entries[$offset]);
198 }
199
200 /**
201 * Returns the value at specified offset.
202 *
203 * @param mixed $offset The offset to retrieve.
204 *
205 * @return mixed The value at the offset.
206 *
207 * @see ArrayAccess::offsetGet()
208 * @since 12.3
209 */
210 public function offsetGet($offset)
211 {
212 return $this->entries[$offset];
213 }
214
215 /**
216 * Assigns a value to the specified offset.
217 *
218 * @param mixed $offset The offset to assign the value to.
219 * @param JFeedEntry $value The JFeedEntry to set.
220 *
221 * @return boolean
222 *
223 * @see ArrayAccess::offsetSet()
224 * @since 12.3
225 * @throws InvalidArgumentException
226 */
227 public function offsetSet($offset, $value)
228 {
229 if (!($value instanceof JFeedEntry))
230 {
231 throw new InvalidArgumentException('Cannot set value of type "' . gettype($value) . '".');
232 }
233
234 $this->entries[$offset] = $value;
235
236 return true;
237 }
238
239 /**
240 * Unsets an offset.
241 *
242 * @param mixed $offset The offset to unset.
243 *
244 * @return void
245 *
246 * @see ArrayAccess::offsetUnset()
247 * @since 12.3
248 */
249 public function offsetUnset($offset)
250 {
251 unset($this->entries[$offset]);
252 }
253
254 /**
255 * Method to remove a category from the feed object.
256 *
257 * @param string $name The name of the category to remove.
258 *
259 * @return JFeed
260 *
261 * @since 12.3
262 */
263 public function removeCategory($name)
264 {
265 unset($this->properties['categories'][$name]);
266
267 return $this;
268 }
269
270 /**
271 * Method to remove a contributor from the feed object.
272 *
273 * @param JFeedPerson $contributor The person object to remove.
274 *
275 * @return JFeed
276 *
277 * @since 12.3
278 */
279 public function removeContributor(JFeedPerson $contributor)
280 {
281 // If the contributor exists remove it.
282 foreach ($this->properties['contributors'] as $k => $c)
283 {
284 if ($c == $contributor)
285 {
286 unset($this->properties['contributors'][$k]);
287 $this->properties['contributors'] = array_values($this->properties['contributors']);
288
289 return $this;
290 }
291 }
292
293 return $this;
294 }
295
296 /**
297 * Method to remove an entry from the feed object.
298 *
299 * @param JFeedEntry $entry The entry object to remove.
300 *
301 * @return JFeed
302 *
303 * @since 12.3
304 */
305 public function removeEntry(JFeedEntry $entry)
306 {
307 // If the entry exists remove it.
308 foreach ($this->entries as $k => $e)
309 {
310 if ($e == $entry)
311 {
312 unset($this->entries[$k]);
313 $this->entries = array_values($this->entries);
314
315 return $this;
316 }
317 }
318
319 return $this;
320 }
321
322 /**
323 * Shortcut method to set the author for the feed object.
324 *
325 * @param string $name The full name of the person to set.
326 * @param string $email The email address of the person to set.
327 * @param string $uri The optional URI for the person to set.
328 * @param string $type The optional type of person to set.
329 *
330 * @return JFeed
331 *
332 * @since 12.3
333 */
334 public function setAuthor($name, $email, $uri = null, $type = null)
335 {
336 $author = new JFeedPerson($name, $email, $uri, $type);
337
338 $this->properties['author'] = $author;
339
340 return $this;
341 }
342
343 /**
344 * Method to reverse the items if display is set to 'oldest first'
345 *
346 * @return JFeed
347 *
348 * @since 12.3
349 */
350 public function reverseItems()
351 {
352 if (is_array($this->entries) && !empty($this->entries))
353 {
354 $this->entries = array_reverse($this->entries);
355 }
356
357 return $this;
358 }
359 }
360