source: cpc/trunk/project/plugins/sfFeed2Plugin/lib/sfAtom1Feed.class.php @ 367

Last change on this file since 367 was 367, checked in by teymour, 12 years ago

Du rss pour suivre l'activité d'un député

File size: 9.6 KB
Line 
1<?php
2
3/*
4 * This file is part of the sfFeed2 package.
5 * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
6 * (c) 2004-2007 Francois Zaninotto <francois.zaninotto@symfony-project.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12/**
13 * sfAtom1Feed.
14 *
15 * Specification: http://www.ietf.org/rfc/rfc4287.txt
16 *
17 * @package    sfFeed2
18 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
19 * @author     Francois Zaninotto <francois.zaninotto@symfony-project.com>
20 * @author     Stefan Koopmanschap <stefan.koopmanschap@symfony-project.com>
21 */
22class sfAtom1Feed extends sfFeed
23{
24  protected
25    $context;
26
27  protected function initContext()
28  {
29    if(!$this->context)
30    {
31      $this->context = sfContext::getInstance();
32    }
33  }
34
35  /**
36   * Populate the feed object from a XML feed string.
37   *
38   * @param string A XML feed (Atom 1.0 format)
39   *
40   * @return sfAtom1Feed The current object
41   *
42   * @throws Exception If the argument is not a well-formatted Atom feed
43   */
44  public function fromXml($feedXml)
45  {
46    preg_match('/^<\?xml\s*version="1\.0"\s*encoding="(.*?)".*?\?>$/mi', $feedXml, $matches);
47    if(isset($matches[1]))
48    {
49      $this->setEncoding($matches[1]);
50    }
51    $feedXml = simplexml_load_string($feedXml);
52    if(!$feedXml)
53    {
54      throw new Exception('Error creating feed from XML: string is not well-formatted XML');
55    }
56
57    $attributes = $feedXml->attributes('http://www.w3.org/XML/1998/namespace');
58
59    $this->setLanguage((string) $attributes['lang']);
60    $this->setTitle((string) $feedXml->title);
61    $feedXml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom');
62    if($titles = $feedXml->xpath('atom:link[@rel="alternate"]'))
63    {
64       $this->setLink((string) $titles[0]['href']);
65    }
66    if($titles = $feedXml->xpath('atom:link[@rel="self"]'))
67    {
68       $this->setFeedUrl((string) $titles[0]['href']);
69    }
70    $this->setSubtitle((string) $feedXml->subtitle);
71    $this->setAuthorName((string) $feedXml->author->name);
72    $this->setAuthorEmail((string) $feedXml->author->email);
73    $this->setAuthorLink((string) $feedXml->author->uri);
74
75    $image = new sfFeedImage(array(
76      "favicon"  => (string)$feedXml->icon,
77      "image"    => (string)$feedXml->logo,
78    ));
79    $this->setImage($image);
80
81    $categories = array();
82    foreach($feedXml->category as $category)
83    {
84      $categories[] = (string) $category['term'];
85    }
86    $this->setCategories($categories);
87
88    foreach($feedXml->entry as $itemXml)
89    {
90      $categories = array();
91      foreach($itemXml->category as $category)
92      {
93        $categories[] = (string) $category['term'];
94      }
95      $url = (string) $itemXml->link['href'];
96      $pubdate = strtotime((string) $itemXml->published);
97      if(!$pubdate)
98      {
99        if((string) $itemXml->updated)
100        {
101          $pubdate = strtotime((string) $itemXml->updated);
102        }
103        else if((string) $itemXml->modified)
104        {
105          $pubdate = strtotime((string) $itemXml->modified);
106        }
107        else if(preg_match('/\d{4}\/\d{2}\/\d{2}/', $url, $matches))
108        {
109          $pubdate = strtotime($matches[0]);
110        }
111        else
112        {
113          $pubdate = 0;
114        }
115      }
116      $itemXml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom');
117      if($enclosures = $itemXml->xpath('atom:link[@rel="enclosure"]'))
118      {
119        $enclosure = new sfFeedEnclosure();
120        $enclosure->setUrl((string) $enclosures[0]['href']);
121        $enclosure->setLength((string) $enclosures[0]['length']);
122        $enclosure->setMimeType((string) $enclosures[0]['type']);
123      }
124      else
125      {
126        $enclosure = null;
127      }
128
129      $content = (string) $itemXml->content;
130
131      if (!$content)
132      {
133        $content = preg_replace('/<\/?content[^>]*>/iU', '', $itemXml->content->asXml());
134      }
135
136      $this->addItemFromArray(array(
137        'title'       => (string) $itemXml->title,
138        'link'        => $url,
139        'authorName'  => (string) $itemXml->author->name,
140        'authorEmail' => (string) $itemXml->author->email,
141        'authorLink'  => (string) $itemXml->author->uri,
142        'pubDate'     => $pubdate,
143        'description' => (string) $itemXml->summary,
144        'content'     => $content,
145        'uniqueId'    => (string) $itemXml->id,
146        'enclosure'   => $enclosure,
147        'categories'  => $categories,
148        'feed'        => $this
149      ));
150    }
151
152    return $this;
153  }
154
155  /**
156   * Returns the the current object as a valid Atom 1.0 XML feed and sets the response content type accordingly.
157   *
158   * @return string An Atom 1.0 XML string
159   */
160  public function asXml()
161  {
162    $this->initContext();
163    $this->context->getResponse()->setContentType('application/atom+xml; charset='.$this->getEncoding());
164
165    return $this->toXml();
166  }
167
168  /**
169   * Returns the the current object as a valid Atom 1.0 XML feed.
170   *
171   * @return string An Atom 1.0 XML string
172   */
173  public function toXml()
174  {
175    $this->initContext();
176    $controller = $this->context->getController();
177
178    $xml = array();
179    $xml[] = '<?xml version="1.0" encoding="'.$this->getEncoding().'" ?>';
180
181    if ($this->getLanguage())
182    {
183      $xml[] = sprintf('<feed xmlns="%s" xml:lang="%s">', 'http://www.w3.org/2005/Atom', $this->getLanguage());
184    }
185    else
186    {
187      $xml[] = sprintf('<feed xmlns="%s">', 'http://www.w3.org/2005/Atom');
188    }
189
190    $xml[] = '  <title>'.$this->getTitle().'</title>';
191    $xml[] = '  <link rel="alternate" href="'.$controller->genUrl($this->getLink(), true).'"></link>';
192    if ($this->getFeedUrl())
193    {
194      $xml[] = '  <link rel="self" href="'.$controller->genUrl($this->getFeedUrl(), true).'"></link>';
195    }
196    $xml[] = '  <id>'.$controller->genUrl($this->getLink(), true).'</id>';
197    $xml[] = '  <updated>'.gmstrftime('%Y-%m-%dT%H:%M:%SZ', $this->getLatestPostDate()).'</updated>';
198
199    if ($this->getAuthorName())
200    {
201      $xml[] = '  <author>';
202      $xml[] = '    <name>'.$this->getAuthorName().'</name>';
203      if ($this->getAuthorEmail())
204      {
205        $xml[] = '    <email>'.$this->getAuthorEmail().'</email>';
206      }
207      if ($this->getAuthorLink())
208      {
209        $xml[] = '    <uri>'.$controller->genUrl($this->getAuthorLink(), true).'</uri>';
210      }
211      $xml[] = '  </author>';
212    }
213
214    if ($this->getSubtitle())
215    {
216      $xml[] = '  <subtitle>'.$this->getSubtitle().'</subtitle>';
217    }
218
219    if ($this->getImage())
220    {
221      $xml[] = '  <icon>'.$this->getImage()->getFavicon().'</icon>';
222      $xml[] = '  <logo>'.$this->getImage()->getImage().'</logo>';
223    }
224
225    if(is_array($this->getCategories()))
226    {
227      foreach ($this->getCategories() as $category)
228      {
229        $xml[] = '  <category term="'.$category.'"></category>';
230      }
231    }
232
233    $xml[] = $this->getFeedElements();
234
235    $xml[] = '</feed>';
236
237    return implode("\n", $xml);
238  }
239
240  /**
241   * Returns an array of <entry> tags corresponding to the feed's items.
242   *
243   * @return string A list of <entry> elements
244   */
245  private function getFeedElements()
246  {
247    $controller = $this->context->getController();
248    $xml = array();
249
250    foreach ($this->getItems() as $item)
251    {
252      $xml[] = '<entry>';
253      $xml[] = '  <title>'.htmlspecialchars($item->getTitle()).'</title>';
254      $xml[] = '  <link rel="alternate" href="'.$controller->genUrl($item->getLink(), true).'"></link>';
255      if ($item->getPubdate())
256      {
257        $xml[] = '  <updated>'.gmstrftime('%Y-%m-%dT%H:%M:%SZ', $item->getPubdate()).'</updated>';
258      }
259
260      // author information
261      if ($item->getAuthorName())
262      {
263        $xml[] = '  <author>';
264        $xml[] = '    <name>'.$item->getAuthorName().'</name>';
265        if ($item->getAuthorEmail())
266        {
267          $xml[] = '    <email>'.$item->getAuthorEmail().'</email>';
268        }
269        if ($item->getAuthorLink())
270        {
271          $xml[] = '    <uri>'.$controller->genUrl($item->getAuthorLink(), true).'</uri>';
272        }
273        $xml[] = '  </author>';
274      }
275
276      // unique id
277      if ($item->getUniqueId())
278      {
279        $uniqueId = $item->getUniqueId();
280      }
281      else
282      {
283        $uniqueId = $this->getTagUri($item->getLink(), $item->getPubdate());
284      }
285      $xml[] = '  <id>'.$uniqueId.'</id>';
286
287      // summary
288      if ($item->getDescription())
289      {
290        $xml[] = sprintf('  <summary type="text">%s</summary>', htmlspecialchars($item->getDescription()));
291      }
292
293      // content
294      if ($item->getContent())
295      {
296        $xml[] = sprintf('  <content type="text/html"><![CDATA[%s]]></content>', $item->getContent());
297      }
298
299      // enclosure
300      if ($enclosure = $item->getEnclosure())
301      {
302        $xml[] = sprintf('  <link rel="enclosure" href="%s" length="%s" type="%s"></link>', $enclosure->getUrl(), $enclosure->getLength(), $enclosure->getMimeType());
303      }
304
305      // categories
306      if(is_array($item->getCategories()))
307      {
308        foreach ($item->getCategories() as $category)
309        {
310          $xml[] = '  <category term="'.$category.'"></category>';
311        }
312      }
313
314      $xml[] = '</entry>';
315    }
316
317    return implode("\n", $xml);
318  }
319
320  /**
321   * Creates a TagURI.
322   * See http://diveintomark.org/archives/2004/05/28/howto-atom-id
323   *
324   * @param string An URI to the Feed Element
325   * @param datetime A publication date
326   *
327   * @return string A valid TagURI
328   */
329  private function getTagUri($url, $date)
330  {
331    $tag = preg_replace('#^http\://#', '', $url);
332    if ($date)
333    {
334      $tag = preg_replace('#/#', ','.strftime('%Y-%m-%d', $date).':/', $tag, 1);
335    }
336    $tag = preg_replace('/#/', '/', $tag);
337
338    return 'tag:'.$tag;
339  }
340
341}
Note: See TracBrowser for help on using the repository browser.