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  * ATOM Feed Parser class.
 14  *
 15  * @link   http://www.atomenabled.org/developers/syndication/
 16  * @since  12.3
 17  */
 18 class JFeedParserAtom extends JFeedParser
 19 {
 20     /**
 21      * @var    string  The feed format version.
 22      * @since  12.3
 23      */
 24     protected $version;
 25 
 26     /**
 27      * Method to handle the `<author>` element for the feed.
 28      *
 29      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
 30      * @param   SimpleXMLElement  $el    The current XML element object to handle.
 31      *
 32      * @return  void
 33      *
 34      * @since   12.3
 35      */
 36     protected function handleAuthor(JFeed $feed, SimpleXMLElement $el)
 37     {
 38         // Set the author information from the XML element.
 39         $feed->setAuthor((string) $el->name, (string) $el->email, (string) $el->uri);
 40     }
 41 
 42     /**
 43      * Method to handle the `<contributor>` element for the feed.
 44      *
 45      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
 46      * @param   SimpleXMLElement  $el    The current XML element object to handle.
 47      *
 48      * @return  void
 49      *
 50      * @since   12.3
 51      */
 52     protected function handleContributor(JFeed $feed, SimpleXMLElement $el)
 53     {
 54         $feed->addContributor((string) $el->name, (string) $el->email, (string) $el->uri);
 55     }
 56 
 57     /**
 58      * Method to handle the `<generator>` element for the feed.
 59      *
 60      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
 61      * @param   SimpleXMLElement  $el    The current XML element object to handle.
 62      *
 63      * @return  void
 64      *
 65      * @since   12.3
 66      */
 67     protected function handleGenerator(JFeed $feed, SimpleXMLElement $el)
 68     {
 69         $feed->generator = (string) $el;
 70     }
 71 
 72     /**
 73      * Method to handle the `<id>` element for the feed.
 74      *
 75      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
 76      * @param   SimpleXMLElement  $el    The current XML element object to handle.
 77      *
 78      * @return  void
 79      *
 80      * @since   12.3
 81      */
 82     protected function handleId(JFeed $feed, SimpleXMLElement $el)
 83     {
 84         $feed->uri = (string) $el;
 85     }
 86 
 87     /**
 88      * Method to handle the `<link>` element for the feed.
 89      *
 90      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
 91      * @param   SimpleXMLElement  $el    The current XML element object to handle.
 92      *
 93      * @return  void
 94      *
 95      * @since   12.3
 96      */
 97     protected function handleLink(JFeed $feed, SimpleXMLElement $el)
 98     {
 99         $link = new JFeedLink;
100         $link->uri      = (string) $el['href'];
101         $link->language = (string) $el['hreflang'];
102         $link->length   = (int) $el['length'];
103         $link->relation = (string) $el['rel'];
104         $link->title    = (string) $el['title'];
105         $link->type     = (string) $el['type'];
106 
107         $feed->link = $link;
108     }
109 
110     /**
111      * Method to handle the `<rights>` element for the feed.
112      *
113      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
114      * @param   SimpleXMLElement  $el    The current XML element object to handle.
115      *
116      * @return  void
117      *
118      * @since   12.3
119      */
120     protected function handleRights(JFeed $feed, SimpleXMLElement $el)
121     {
122         $feed->copyright = (string) $el;
123     }
124 
125     /**
126      * Method to handle the `<subtitle>` element for the feed.
127      *
128      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
129      * @param   SimpleXMLElement  $el    The current XML element object to handle.
130      *
131      * @return  void
132      *
133      * @since   12.3
134      */
135     protected function handleSubtitle(JFeed $feed, SimpleXMLElement $el)
136     {
137         $feed->description = (string) $el;
138     }
139 
140     /**
141      * Method to handle the `<title>` element for the feed.
142      *
143      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
144      * @param   SimpleXMLElement  $el    The current XML element object to handle.
145      *
146      * @return  void
147      *
148      * @since   12.3
149      */
150     protected function handleTitle(JFeed $feed, SimpleXMLElement $el)
151     {
152         $feed->title = (string) $el;
153     }
154 
155     /**
156      * Method to handle the `<updated>` element for the feed.
157      *
158      * @param   JFeed             $feed  The JFeed object being built from the parsed feed.
159      * @param   SimpleXMLElement  $el    The current XML element object to handle.
160      *
161      * @return  void
162      *
163      * @since   12.3
164      */
165     protected function handleUpdated(JFeed $feed, SimpleXMLElement $el)
166     {
167         $feed->updatedDate = (string) $el;
168     }
169 
170     /**
171      * Method to initialise the feed for parsing.  Here we detect the version and advance the stream
172      * reader so that it is ready to parse feed elements.
173      *
174      * @return  void
175      *
176      * @since   12.3
177      */
178     protected function initialise()
179     {
180         // Read the version attribute.
181         $this->version = ($this->stream->getAttribute('version') == '0.3') ? '0.3' : '1.0';
182 
183         // We want to move forward to the first element after the root element.
184         $this->moveToNextElement();
185     }
186 
187     /**
188      * Method to handle a `<entry>` element for the feed.
189      *
190      * @param   JFeedEntry        $entry  The JFeedEntry object being built from the parsed feed entry.
191      * @param   SimpleXMLElement  $el     The current XML element object to handle.
192      *
193      * @return  void
194      *
195      * @since   12.3
196      */
197     protected function processFeedEntry(JFeedEntry $entry, SimpleXMLElement $el)
198     {
199         $entry->uri         = (string) $el->id;
200         $entry->title       = (string) $el->title;
201         $entry->updatedDate = (string) $el->updated;
202         $entry->content     = (string) $el->summary;
203 
204         if (!$entry->content)
205         {
206             $entry->content = (string) $el->content;
207         }
208 
209         if (filter_var($entry->uri, FILTER_VALIDATE_URL) === false && !is_null($el->link) && $el->link)
210         {
211             $link = $el->link;
212             if (is_array($link))
213             {
214                 $link = $this->bestLinkForUri($link);
215             }
216             $uri = (string) $link['href'];
217             if ($uri)
218             {
219                 $entry->uri = $uri;
220             }
221         }
222     }
223 
224     /**
225      * If there is more than one <link> in the feed entry, find the most appropriate one and return it.
226      *
227      * @param   array  $links  Array of <link> elements from the feed entry.
228      *
229      * @return  SimpleXMLElement
230      */
231     private function bestLinkForUri(array $links)
232     {
233         $linkPrefs = array('', 'self', 'alternate');
234         foreach ($linkPrefs as $pref)
235         {
236             foreach ($links as $link)
237             {
238                 $rel = (string) $link['rel'];
239                 if ($rel === $pref)
240                 {
241                     return $link;
242                 }
243             }
244         }
245         return array_shift($links);
246     }
247 }
248