فهرست منبع

Added support for Atom specific relative URI parsing for all link elements.

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@18654 44c647ce-9c0f-0410-b52a-842ac1e357ba
padraic 16 سال پیش
والد
کامیت
fc450fb53d

+ 53 - 1
library/Zend/Feed/Reader/Extension/Atom/Entry.php

@@ -35,6 +35,11 @@ require_once 'Zend/Feed/Reader/Extension/EntryAbstract.php';
 require_once 'Zend/Date.php';
 
 /**
+ * @see Zend_Uri
+ */
+require_once 'Zend/Uri.php';
+
+/**
  * @category   Zend
  * @package    Zend_Feed_Reader
  * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
@@ -263,6 +268,34 @@ class Zend_Feed_Reader_Extension_Atom_Entry
 
         return $this->_data['id'];
     }
+    
+    /**
+     * Get the base URI of the feed (if set).
+     *
+     * @return string|null
+     */
+    public function getBaseUrl()
+    {
+        if (array_key_exists('baseUrl', $this->_data)) {
+            return $this->_data['baseUrl'];
+        }
+        
+        $baseUrl = $this->_xpath->evaluate('string('
+            . $this->getXpathPrefix() . '/@xml:base[1]'
+        . ')');
+        
+        if (!$baseUrl) {
+            $baseUrl = $this->_xpath->evaluate('string(//@xml:base[1])');
+        }
+
+        if (!$baseUrl) {
+            $baseUrl = null;
+        }
+        
+        $this->_data['baseUrl'] = $baseUrl;
+
+        return $this->_data['baseUrl'];
+    }
 
     /**
      * Get a specific link
@@ -303,7 +336,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
 
         if ($list->length) {
             foreach ($list as $link) {
-                $links[] = $link->value;
+                $links[] = $this->_absolutiseUri($link->value);
             }
         }
 
@@ -392,6 +425,7 @@ class Zend_Feed_Reader_Extension_Atom_Entry
 
         if ($list->length) {
             $link = $list->item(0)->value;
+            $link = $this->_absolutiseUri($link);
         }
 
         $this->_data['commentlink'] = $link;
@@ -418,12 +452,30 @@ class Zend_Feed_Reader_Extension_Atom_Entry
 
         if ($list->length) {
             $link = $list->item(0)->value;
+            $link = $this->_absolutiseUri($link);
         }
 
         $this->_data['commentfeedlink'] = $link;
 
         return $this->_data['commentfeedlink'];
     }
+    
+    /**
+     *  Attempt to absolutise the URI, i.e. if a relative URI apply the
+     *  xml:base value as a prefix to turn into an absolute URI.
+     */
+    protected function _absolutiseUri($link)
+    {
+        if (!Zend_Uri::check($link)) {
+            if (!is_null($this->getBaseUrl())) {
+                $link = $this->getBaseUrl() . $link;
+                if (!Zend_Uri::check($link)) {
+                    $link = null;
+                }
+            }
+        }
+        return $link;
+    }
 
     /**
      * Get an author entry

+ 55 - 8
library/Zend/Feed/Reader/Extension/Atom/Feed.php

@@ -30,6 +30,11 @@ require_once 'Zend/Feed/Reader/Extension/FeedAbstract.php';
 require_once 'Zend/Date.php';
 
 /**
+ * @see Zend_Uri
+ */
+require_once 'Zend/Uri.php';
+
+/**
  * @category   Zend
  * @package    Zend_Feed_Reader
  * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
@@ -293,6 +298,27 @@ class Zend_Feed_Reader_Extension_Atom_Feed
 
         return $this->_data['language'];
     }
+    
+    /**
+     * Get the base URI of the feed (if set).
+     *
+     * @return string|null
+     */
+    public function getBaseUrl()
+    {
+        if (array_key_exists('baseUrl', $this->_data)) {
+            return $this->_data['baseUrl'];
+        }
+
+        $baseUrl = $this->_xpath->evaluate('string(//@xml:base[1])');
+
+        if (!$baseUrl) {
+            $baseUrl = null;
+        }
+        $this->_data['baseUrl'] = $baseUrl;
+
+        return $this->_data['baseUrl'];
+    }
 
     /**
      * Get a link to the source website
@@ -305,10 +331,16 @@ class Zend_Feed_Reader_Extension_Atom_Feed
             return $this->_data['link'];
         }
 
-        $link = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:link/@href)');
-
-        if (!$link) {
-            $link = null;
+        $link = null;
+        
+        $list = $this->_xpath->query(
+            $this->getXpathPrefix() . '/atom:link[@rel="alternate"]/@href' . '|' .
+            $this->getXpathPrefix() . '/atom:link[not(@rel)]/@href'
+        );
+        
+        if ($list->length) {
+            $link = $list->item(0)->nodeValue;
+            $link = $this->_absolutiseUri($link);
         }
 
         $this->_data['link'] = $link;
@@ -329,9 +361,7 @@ class Zend_Feed_Reader_Extension_Atom_Feed
 
         $link = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:link[@rel="self"]/@href)');
 
-        if (!$link) {
-            $link = null;
-        }
+        $link = $this->_absolutiseUri($link);
 
         $this->_data['feedlink'] = $link;
 
@@ -354,7 +384,7 @@ class Zend_Feed_Reader_Extension_Atom_Feed
 
         if ($list->length) {
             foreach ($list as $uri) {
-                $hubs[] = $uri->nodeValue;
+                $hubs[] = $this->_absolutiseUri($uri->nodeValue);
             }
         } else {
             $hubs = null;
@@ -425,6 +455,23 @@ class Zend_Feed_Reader_Extension_Atom_Feed
 
         return null;
     }
+    
+    /**
+     *  Attempt to absolutise the URI, i.e. if a relative URI apply the
+     *  xml:base value as a prefix to turn into an absolute URI.
+     */
+    protected function _absolutiseUri($link)
+    {
+        if (!Zend_Uri::check($link)) {
+            if (!is_null($this->getBaseUrl())) {
+                $link = $this->getBaseUrl() . $link;
+                if (!Zend_Uri::check($link)) {
+                    $link = null;
+                }
+            }
+        }
+        return $link;
+    }
 
     /**
      * Register the default namespaces for the current feed format

+ 18 - 0
library/Zend/Feed/Reader/Feed/Atom.php

@@ -239,6 +239,24 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
 
         return $this->_data['language'];
     }
+    
+    /**
+     * Get a link to the source website
+     *
+     * @return string|null
+     */
+    public function getBaseUrl()
+    {
+        if (array_key_exists('baseUrl', $this->_data)) {
+            return $this->_data['baseUrl'];
+        }
+
+        $baseUrl = $this->getExtension('Atom')->getBaseUrl();
+
+        $this->_data['baseUrl'] = $baseUrl;
+
+        return $this->_data['baseUrl'];
+    }
 
     /**
      * Get a link to the source website

+ 69 - 0
tests/Zend/Feed/Reader/Entry/AtomTest.php

@@ -289,4 +289,73 @@ class Zend_Feed_Reader_Entry_AtomTest extends PHPUnit_Framework_TestCase
         $entry = $feed->current();
         $this->assertEquals('http://www.example.com/entry', $entry->getLink());
     }
+    
+    public function testGetsLinkFromAtom10_WithNoRelAttribute()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath . '/link/plain/atom10-norel.xml')
+        );
+        $entry = $feed->current();
+        $this->assertEquals('http://www.example.com/entry', $entry->getLink());
+    }
+    
+    public function testGetsLinkFromAtom10_WithRelativeUrl()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath . '/link/plain/atom10-relative.xml')
+        );
+        $entry = $feed->current();
+        $this->assertEquals('http://www.example.com/entry', $entry->getLink());
+    }
+    
+    /**
+     * Get Base Uri
+     */
+    public function testGetsBaseUriFromAtom10_FromFeedElement()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath . '/baseurl/plain/atom10-feedlevel.xml')
+        );
+        $entry = $feed->current();
+        $this->assertEquals('http://www.example.com', $entry->getBaseUrl());
+    }
+    
+    public function testGetsBaseUriFromAtom10_FromEntryElement()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath . '/baseurl/plain/atom10-entrylevel.xml')
+        );
+        $entry = $feed->current();
+        $this->assertEquals('http://www.example.com/', $entry->getBaseUrl());
+    }
+    
+    /**
+     * Get Comment HTML Link
+     */
+    public function testGetsCommentLinkFromAtom03()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath . '/commentlink/plain/atom03.xml')
+        );
+        $entry = $feed->current();
+        $this->assertEquals('http://www.example.com/entry/comments', $entry->getCommentLink());
+    }
+    
+    public function testGetsCommentLinkFromAtom10()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath . '/commentlink/plain/atom10.xml')
+        );
+        $entry = $feed->current();
+        $this->assertEquals('http://www.example.com/entry/comments', $entry->getCommentLink());
+    }
+    
+    public function testGetsCommentLinkFromAtom10_RelativeLinks()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath . '/commentlink/plain/atom10-relative.xml')
+        );
+        $entry = $feed->current();
+        $this->assertEquals('http://www.example.com/entry/comments', $entry->getCommentLink());
+    }
 }

+ 6 - 0
tests/Zend/Feed/Reader/Entry/_files/Atom/baseurl/plain/atom10-entrylevel.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <entry xml:base="http://www.example.com/">
+        <link href="http://www.example.com/entry"/>
+    </entry>
+</feed>

+ 7 - 0
tests/Zend/Feed/Reader/Entry/_files/Atom/baseurl/plain/atom10-feedlevel.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom"
+    xml:base="http://www.example.com">
+    <entry>
+        <link href="http://www.example.com/entry"/>
+    </entry>
+</feed>

+ 6 - 0
tests/Zend/Feed/Reader/Entry/_files/Atom/commentlink/plain/atom03.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed version="0.3" xmlns="http://purl.org/atom/ns#">
+    <entry>
+        <link rel="replies" type="text/html" href="http://www.example.com/entry/comments"/>
+    </entry>
+</feed>

+ 6 - 0
tests/Zend/Feed/Reader/Entry/_files/Atom/commentlink/plain/atom10-relative.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <entry xml:base="http://www.example.com/">
+        <link href="entry/comments" type="text/html" rel="replies"/>
+    </entry>
+</feed>

+ 6 - 0
tests/Zend/Feed/Reader/Entry/_files/Atom/commentlink/plain/atom10.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <entry>
+        <link href="http://www.example.com/entry/comments" rel="replies" type="text/html"/>
+    </entry>
+</feed>

+ 6 - 0
tests/Zend/Feed/Reader/Entry/_files/Atom/link/plain/atom10-norel.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <entry>
+        <link href="http://www.example.com/entry"/>
+    </entry>
+</feed>

+ 6 - 0
tests/Zend/Feed/Reader/Entry/_files/Atom/link/plain/atom10-relative.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <entry xml:base="http://www.example.com/">
+        <link href="entry"/>
+    </entry>
+</feed>

+ 2 - 2
tests/Zend/Feed/Reader/Entry/_files/Atom/link/plain/atom10.xml

@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <feed xmlns="http://www.w3.org/2005/Atom">
     <entry>
-        <link href="http://www.example.com/entry"/>
+        <link href="http://www.example.com/entry" rel="alternate"/>
     </entry>
-</feed>
+</feed>

+ 35 - 0
tests/Zend/Feed/Reader/Feed/AtomTest.php

@@ -282,6 +282,33 @@ class Zend_Feed_Reader_Feed_AtomTest extends PHPUnit_Framework_TestCase
         );
         $this->assertEquals('http://www.example.com', $feed->getLink());
     }
+    
+    public function testGetsLinkFromAtom10WithNoRelAttribute()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/link/plain/atom10-norel.xml')
+        );
+        $this->assertEquals('http://www.example.com', $feed->getLink());
+    }
+    
+    public function testGetsLinkFromAtom10WithRelativeUrl()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/link/plain/atom10-relative.xml')
+        );
+        $this->assertEquals('http://www.example.com', $feed->getLink());
+    }
+    
+    /**
+     * Get Base Uri
+     */
+    public function testGetsBaseUriFromAtom10()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/feedlink/plain/atom10-relative.xml')
+        );
+        $this->assertEquals('http://www.example.com/', $feed->getBaseUrl());
+    }
 
     /**
      * Get Feed Link (Unencoded Text)
@@ -301,6 +328,14 @@ class Zend_Feed_Reader_Feed_AtomTest extends PHPUnit_Framework_TestCase
         );
         $this->assertEquals('http://www.example.com/feed/atom', $feed->getFeedLink());
     }
+    
+    public function testGetsFeedLinkFromAtom10IfRelativeUri()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/feedlink/plain/atom10-relative.xml')
+        );
+        $this->assertEquals('http://www.example.com/feed/atom', $feed->getFeedLink());
+    }
 
     /**
      * Get Pubsubhubbub Hubs

+ 5 - 0
tests/Zend/Feed/Reader/Feed/_files/Atom/feedlink/plain/atom10-relative.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom"
+     xml:base='http://www.example.com/'>
+    <link rel="self" type="application/atom+xml" href="feed/atom"/>
+</feed>

+ 4 - 0
tests/Zend/Feed/Reader/Feed/_files/Atom/link/plain/atom10-norel.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <link href="http://www.example.com"/>
+</feed>

+ 5 - 0
tests/Zend/Feed/Reader/Feed/_files/Atom/link/plain/atom10-relative.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom"
+    xml:base="http://www.example.com">
+    <link href="" rel="alternate"/>
+</feed>

+ 2 - 2
tests/Zend/Feed/Reader/Feed/_files/Atom/link/plain/atom10.xml

@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <feed xmlns="http://www.w3.org/2005/Atom">
-    <link href="http://www.example.com"/>
-</feed>
+    <link href="http://www.example.com" rel="alternate"/>
+</feed>