/libraries/src/Feed/Feed.php

https://github.com/fastslack/joomla-cms · PHP · 362 lines · 136 code · 39 blank · 187 comment · 24 complexity · 214d7d2094173541e8180d1962a17cf6 MD5 · raw file

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