Просмотр исходного кода

Adding support for parsing/writing feed level logos/images - implements ZF-9596

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@22097 44c647ce-9c0f-0410-b52a-842ac1e357ba
padraic 15 лет назад
Родитель
Сommit
17975eaffa
28 измененных файлов с 721 добавлено и 2 удалено
  1. 24 0
      library/Zend/Feed/Reader/Extension/Atom/Feed.php
  2. 18 0
      library/Zend/Feed/Reader/Feed/Atom.php
  3. 54 0
      library/Zend/Feed/Reader/Feed/Rss.php
  4. 34 2
      library/Zend/Feed/Writer/Feed/FeedAbstract.php
  5. 1 0
      library/Zend/Feed/Writer/Renderer/Feed/Atom.php
  6. 19 0
      library/Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php
  7. 109 0
      library/Zend/Feed/Writer/Renderer/Feed/Rss.php
  8. 38 0
      tests/Zend/Feed/Reader/Feed/AtomTest.php
  9. 167 0
      tests/Zend/Feed/Reader/Feed/RssTest.php
  10. 4 0
      tests/Zend/Feed/Reader/Feed/_files/Atom/image/plain/atom03.xml
  11. 4 0
      tests/Zend/Feed/Reader/Feed/_files/Atom/image/plain/atom10.xml
  12. 3 0
      tests/Zend/Feed/Reader/Feed/_files/Atom/image/plain/none/atom03.xml
  13. 3 0
      tests/Zend/Feed/Reader/Feed/_files/Atom/image/plain/none/atom10.xml
  14. 7 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss090.xml
  15. 5 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss091.xml
  16. 5 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss092.xml
  17. 5 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss093.xml
  18. 5 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss094.xml
  19. 7 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss10.xml
  20. 5 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss20.xml
  21. 15 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss090.xml
  22. 13 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss091.xml
  23. 13 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss092.xml
  24. 13 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss093.xml
  25. 13 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss094.xml
  26. 15 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss10.xml
  27. 13 0
      tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss20.xml
  28. 109 0
      tests/Zend/Feed/Writer/FeedTest.php

+ 24 - 0
library/Zend/Feed/Reader/Extension/Atom/Feed.php

@@ -295,6 +295,30 @@ class Zend_Feed_Reader_Extension_Atom_Feed
     }
 
     /**
+     * Get the feed image
+     *
+     * @return array|null
+     */
+    public function getImage()
+    {
+        if (array_key_exists('image', $this->_data)) {
+            return $this->_data['image'];
+        }
+
+        $imageUrl = $this->_xpath->evaluate('string(' . $this->getXpathPrefix() . '/atom:logo)');
+
+        if (!$imageUrl) {
+            $image = null;
+        } else {
+            $image = array('uri'=>$imageUrl);
+        }
+
+        $this->_data['image'] = $image;
+
+        return $this->_data['image'];
+    }
+
+    /**
      * Get the base URI of the feed (if set).
      *
      * @return string|null

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

@@ -278,6 +278,24 @@ class Zend_Feed_Reader_Feed_Atom extends Zend_Feed_Reader_FeedAbstract
     }
 
     /**
+     * Get feed image data
+     *
+     * @return array|null
+     */
+    public function getImage()
+    {
+        if (array_key_exists('image', $this->_data)) {
+            return $this->_data['image'];
+        }
+
+        $link = $this->getExtension('Atom')->getImage();
+
+        $this->_data['image'] = $link;
+
+        return $this->_data['image'];
+    }
+
+    /**
      * Get a link to the feed's XML Url
      *
      * @return string|null

+ 54 - 0
library/Zend/Feed/Reader/Feed/Rss.php

@@ -349,6 +349,60 @@ class Zend_Feed_Reader_Feed_Rss extends Zend_Feed_Reader_FeedAbstract
     }
 
     /**
+     * Get the feed image data
+     *
+     * @return array|null
+     */
+    public function getImage()
+    {
+        if (array_key_exists('image', $this->_data)) {
+            return $this->_data['image'];
+        }
+
+        if ($this->getType() !== Zend_Feed_Reader::TYPE_RSS_10 &&
+            $this->getType() !== Zend_Feed_Reader::TYPE_RSS_090) {
+            $list = $this->_xpath->query('/rss/channel/image');
+            $prefix = '/rss/channel/image[1]';
+        } else {
+            $list = $this->_xpath->query('/rdf:RDF/rss:channel/rss:image');
+            $prefix = '/rdf:RDF/rss:channel/rss:image[1]';
+        }
+        if ($list->length > 0) {
+            $image = array();
+            $value = $this->_xpath->evaluate('string(' . $prefix . '/url)');
+            if ($value) {
+                $image['uri'] = $value;
+            }
+            $value = $this->_xpath->evaluate('string(' . $prefix . '/link)');
+            if ($value) {
+                $image['link'] = $value;
+            }
+            $value = $this->_xpath->evaluate('string(' . $prefix . '/title)');
+            if ($value) {
+                $image['title'] = $value;
+            }
+            $value = $this->_xpath->evaluate('string(' . $prefix . '/height)');
+            if ($value) {
+                $image['height'] = $value;
+            }
+            $value = $this->_xpath->evaluate('string(' . $prefix . '/width)');
+            if ($value) {
+                $image['width'] = $value;
+            }
+            $value = $this->_xpath->evaluate('string(' . $prefix . '/description)');
+            if ($value) {
+                $image['description'] = $value;
+            }
+        } else {
+            $image = null;
+        }
+
+        $this->_data['image'] = $image;
+
+        return $this->_data['image'];
+    }
+
+    /**
      * Get the feed language
      *
      * @return string|null

+ 34 - 2
library/Zend/Feed/Writer/Feed/FeedAbstract.php

@@ -274,7 +274,7 @@ class Zend_Feed_Writer_Feed_FeedAbstract
     /**
      * Set the feed ID - URI or URN (via PCRE pattern) supported
      *
-     * @return string|null
+     * @param string $id
      */
     public function setId($id)
     {
@@ -287,6 +287,25 @@ class Zend_Feed_Writer_Feed_FeedAbstract
     }
 
     /**
+     * Set a feed image (URI at minimum). Parameter is a single array with the
+     * required key 'uri'. When rendering as RSS, the required keys are 'uri',
+     * 'title' and 'link'. RSS also specifies three optional parameters 'width',
+     * 'height' and 'description'. Only 'uri' is required and used for Atom rendering.
+     *
+     * @param array $data
+     */
+    public function setImage(array $data)
+    {
+        if (empty($data['uri']) || !is_string($data['uri'])
+        || !Zend_Uri::check($data['uri'])) {
+            require_once 'Zend/Feed/Exception.php';
+            throw new Zend_Feed_Exception('Invalid parameter: parameter \'uri\''
+            . ' must be a non-empty string and valid URI/IRI');
+        }
+        $this->_data['image'] = $data;  
+    }
+
+    /**
      * Set the feed language
      *
      * @return string|null
@@ -303,7 +322,7 @@ class Zend_Feed_Writer_Feed_FeedAbstract
     /**
      * Set a link to the HTML source
      *
-     * @return string|null
+     * @param string $link
      */
     public function setLink($link)
     {
@@ -553,6 +572,19 @@ class Zend_Feed_Writer_Feed_FeedAbstract
     }
 
     /**
+     * Get the feed image URI
+     *
+     * @return array
+     */
+    public function getImage()
+    {
+        if (!array_key_exists('image', $this->_data)) {
+            return null;
+        }
+        return $this->_data['image'];
+    }
+
+    /**
      * Get the feed language
      *
      * @return string|null

+ 1 - 0
library/Zend/Feed/Writer/Renderer/Feed/Atom.php

@@ -81,6 +81,7 @@ class Zend_Feed_Writer_Renderer_Feed_Atom
         $this->_setBaseUrl($this->_dom, $root);
         $this->_setTitle($this->_dom, $root);
         $this->_setDescription($this->_dom, $root);
+        $this->_setImage($this->_dom, $root);
         $this->_setDateCreated($this->_dom, $root);
         $this->_setDateModified($this->_dom, $root);
         $this->_setGenerator($this->_dom, $root);

+ 19 - 0
library/Zend/Feed/Writer/Renderer/Feed/Atom/AtomAbstract.php

@@ -321,6 +321,25 @@ class Zend_Feed_Writer_Renderer_Feed_Atom_AtomAbstract
         $text = $dom->createTextNode($copyright);
         $copy->appendChild($text);
     }
+
+    /**
+     * Set feed level logo (image)
+     * 
+     * @param DOMDocument $dom 
+     * @param DOMElement $root 
+     * @return void
+     */
+    protected function _setImage(DOMDocument $dom, DOMElement $root)
+    {
+        $image = $this->getDataContainer()->getImage();
+        if (!$image) {
+            return;
+        }
+        $img = $dom->createElement('logo');
+        $root->appendChild($image);
+        $text = $img->createTextNode($image['uri']);
+        $img->appendChild($text);
+    }
     
     /**
      * Set date feed was created 

+ 109 - 0
library/Zend/Feed/Writer/Renderer/Feed/Rss.php

@@ -79,6 +79,7 @@ class Zend_Feed_Writer_Renderer_Feed_Rss
         $this->_setBaseUrl($this->_dom, $channel);
         $this->_setTitle($this->_dom, $channel);
         $this->_setDescription($this->_dom, $channel);
+        $this->_setImage($this->_dom, $channel);
         $this->_setDateCreated($this->_dom, $channel);
         $this->_setDateModified($this->_dom, $channel);
         $this->_setGenerator($this->_dom, $channel);
@@ -312,6 +313,114 @@ class Zend_Feed_Writer_Renderer_Feed_Rss
         $text = $dom->createTextNode($copyright);
         $copy->appendChild($text);
     }
+
+    /**
+     * Set feed channel image
+     * 
+     * @param DOMDocument $dom 
+     * @param DOMElement $root 
+     * @return void
+     */
+    protected function _setImage(DOMDocument $dom, DOMElement $root)
+    {
+        $image = $this->getDataContainer()->getImage();
+        if (!$image) {
+            return;
+        }
+        if (!isset($image['title']) || empty($image['title'])
+        || !is_string($image['title'])) {
+            require_once 'Zend/Feed/Exception.php';
+            $message = 'RSS 2.0 feed images must include a title';
+            $exception = new Zend_Feed_Exception($message);
+            if (!$this->_ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->_exceptions[] = $exception;
+                return;
+            }
+        }
+        if (empty($data['link']) || !is_string($data['link'])
+        || !Zend_Uri::check($data['link'])) {
+            require_once 'Zend/Feed/Exception.php';
+            $message = 'Invalid parameter: parameter \'link\''
+            . 'must be a non-empty string and valid URI/IRI';
+            $exception = new Zend_Feed_Exception($message);
+            if (!$this->_ignoreExceptions) {
+                throw $exception;
+            } else {
+                $this->_exceptions[] = $exception;
+                return;
+            }
+        }
+        $img = $dom->createElement('image');
+        $root->appendChild($image);
+        $url = $dom->createElement('url');
+        $text = $url->createTextNode($image['uri']);
+        $url->appendChild($text);
+        $title = $dom->createElement('title');
+        $text = $title->createTextNode($image['title']);
+        $title->appendChild($text);
+        $link = $dom->createElement('link');
+        $text = $link->createTextNode($image['link']);
+        $link->appendChild($text);
+        $img->appendChild($url);
+        $img->appendChild($title);
+        $img->appendChild($link);
+        if (isset($image['height']) && is_numeric($image['height'])) {
+            if ($image['height'] > 400) {
+                require_once 'Zend/Feed/Exception.php';
+                $message = 'Invalid parameter: parameter \'height\''
+                . ' must be an integer not exceeding 400';
+                $exception = new Zend_Feed_Exception($message);
+                if (!$this->_ignoreExceptions) {
+                    throw $exception;
+                } else {
+                    $this->_exceptions[] = $exception;
+                    return;
+                }
+            }
+            $height = $dom->createElement('height');
+            $text = $height->createTextNode($image['height']);
+            $height->appendChild($text);
+            $img->appendChild($height);
+        }
+        if (isset($image['width']) && is_numeric($image['width'])) {
+            if ($image['width'] > 144) {
+                require_once 'Zend/Feed/Exception.php';
+                $message = 'Invalid parameter: parameter \'width\''
+                . ' must be an integer not exceeding 144';
+                $exception = new Zend_Feed_Exception($message);
+                if (!$this->_ignoreExceptions) {
+                    throw $exception;
+                } else {
+                    $this->_exceptions[] = $exception;
+                    return;
+                }
+            }
+            $width = $dom->createElement('width');
+            $text = $width->createTextNode($image['width']);
+            $width->appendChild($text);
+            $img->appendChild($width);
+        }
+        if (isset($image['description'])) {
+            if (empty($image['description']) || !is_string($image['description'])) {
+                require_once 'Zend/Feed/Exception.php';
+                $message = 'Invalid parameter: parameter \'description\''
+                . ' must be a non-empty string';
+                $exception = new Zend_Feed_Exception($message);
+                if (!$this->_ignoreExceptions) {
+                    throw $exception;
+                } else {
+                    $this->_exceptions[] = $exception;
+                    return;
+                }
+            }
+            $desc = $dom->createElement('description');
+            $text = $desc->createTextNode($image['description']);
+            $desc->appendChild($text);
+            $img->appendChild($desc);
+        }
+    }
     
     /**
      * Set date feed was created

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

@@ -500,4 +500,42 @@ class Zend_Feed_Reader_Feed_AtomTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(array(), (array) $feed->getCategories());
         $this->assertEquals(array(), array_values($feed->getCategories()->getValues()));
     }
+
+    /**
+     * Get Image (Unencoded Text)
+     */
+    public function testGetsImageFromAtom03()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/atom03.xml')
+        );
+        $this->assertEquals(array('uri'=>'http://www.example.com/logo.gif'), $feed->getImage());
+    }
+
+    public function testGetsImageFromAtom10()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/atom10.xml')
+        );
+        $this->assertEquals(array('uri'=>'http://www.example.com/logo.gif'), $feed->getImage());
+    }
+
+    /**
+     * Get Image (Unencoded Text) When Missing
+     */
+    public function testGetsImageFromAtom03_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/atom03.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
+    public function testGetsImageFromAtom10_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/atom10.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
 }

+ 167 - 0
tests/Zend/Feed/Reader/Feed/RssTest.php

@@ -2789,4 +2789,171 @@ class Zend_Feed_Reader_Feed_RssTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(array(), array_values($feed->getCategories()->getValues()));
     }
 
+    /**
+     * Get Image data (Unencoded Text)
+     */
+    public function testGetsImageFromRss20()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/rss20.xml')
+        );
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/image.gif',
+            'link' => 'http://www.example.com',
+            'title' => 'Image title',
+            'height' => '55',
+            'width' => '50',
+            'description' => 'Image description'
+        ), $feed->getImage());
+    }
+
+    public function testGetsImageFromRss094()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/rss094.xml')
+        );
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/image.gif',
+            'link' => 'http://www.example.com',
+            'title' => 'Image title',
+            'height' => '55',
+            'width' => '50',
+            'description' => 'Image description'
+        ), $feed->getImage());
+    }
+
+    public function testGetsImageFromRss093()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/rss093.xml')
+        );
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/image.gif',
+            'link' => 'http://www.example.com',
+            'title' => 'Image title',
+            'height' => '55',
+            'width' => '50',
+            'description' => 'Image description'
+        ), $feed->getImage());
+    }
+
+    public function testGetsImageFromRss092()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/rss092.xml')
+        );
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/image.gif',
+            'link' => 'http://www.example.com',
+            'title' => 'Image title',
+            'height' => '55',
+            'width' => '50',
+            'description' => 'Image description'
+        ), $feed->getImage());
+    }
+
+    public function testGetsImageFromRss091()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/rss091.xml')
+        );
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/image.gif',
+            'link' => 'http://www.example.com',
+            'title' => 'Image title',
+            'height' => '55',
+            'width' => '50',
+            'description' => 'Image description'
+        ), $feed->getImage());
+    }
+
+    public function testGetsImageFromRss10()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/rss10.xml')
+        );
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/image.gif',
+            'link' => 'http://www.example.com',
+            'title' => 'Image title',
+            'height' => '55',
+            'width' => '50',
+            'description' => 'Image description'
+        ), $feed->getImage());
+    }
+
+    public function testGetsImageFromRss090()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/rss090.xml')
+        );
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/image.gif',
+            'link' => 'http://www.example.com',
+            'title' => 'Image title',
+            'height' => '55',
+            'width' => '50',
+            'description' => 'Image description'
+        ), $feed->getImage());
+    }
+
+    /**
+     * Get Image data (Unencoded Text) Missing
+     */
+    public function testGetsImageFromRss20_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/rss20.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
+    public function testGetsImageFromRss094_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/rss094.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
+    public function testGetsImageFromRss093_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/rss093.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
+    public function testGetsImageFromRss092_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/rss092.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
+    public function testGetsImageFromRss091_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/rss091.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
+    public function testGetsImageFromRss10_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/rss10.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
+    public function testGetsImageFromRss090_None()
+    {
+        $feed = Zend_Feed_Reader::importString(
+            file_get_contents($this->_feedSamplePath.'/image/plain/none/rss090.xml')
+        );
+        $this->assertEquals(null, $feed->getImage());
+    }
+
 }

+ 4 - 0
tests/Zend/Feed/Reader/Feed/_files/Atom/image/plain/atom03.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<feed version="0.3" xmlns="http://purl.org/atom/ns#">
+    <logo>http://www.example.com/logo.gif</logo>
+</feed>

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

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

+ 3 - 0
tests/Zend/Feed/Reader/Feed/_files/Atom/image/plain/none/atom03.xml

@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<feed version="0.3" xmlns="http://purl.org/atom/ns#">
+</feed>

+ 3 - 0
tests/Zend/Feed/Reader/Feed/_files/Atom/image/plain/none/atom10.xml

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

+ 7 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss090.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rdf:RDF
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns="http://my.netscape.com/rdf/simple/0.9/">
+    <channel>
+    </channel>
+</rdf:RDF>

+ 5 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss091.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.91">
+    <channel>
+    </channel>
+</rss>

+ 5 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss092.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.92">
+    <channel>
+    </channel>
+</rss>

+ 5 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss093.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.93">
+    <channel>
+    </channel>
+</rss>

+ 5 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss094.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.94">
+    <channel>
+    </channel>
+</rss>

+ 7 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss10.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rdf:RDF
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns="http://purl.org/rss/1.0/">
+    <channel>
+    </channel>
+</rdf:RDF>

+ 5 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/none/rss20.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="2.0">
+    <channel>
+    </channel>
+</rss>

+ 15 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss090.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rdf:RDF
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns="http://my.netscape.com/rdf/simple/0.9/">
+    <channel>
+        <image>
+            <url>http://www.example.com/image.gif</url>
+            <link>http://www.example.com</link>
+            <title>Image title</title>
+            <width>50</width>
+            <height>55</height>
+            <description>Image description</description>
+        </image>
+    </channel>
+</rdf:RDF>

+ 13 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss091.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.91">
+    <channel>
+        <image>
+            <url>http://www.example.com/image.gif</url>
+            <link>http://www.example.com</link>
+            <title>Image title</title>
+            <width>50</width>
+            <height>55</height>
+            <description>Image description</description>
+        </image>
+    </channel>
+</rss>

+ 13 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss092.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.92">
+    <channel>
+        <image>
+            <url>http://www.example.com/image.gif</url>
+            <link>http://www.example.com</link>
+            <title>Image title</title>
+            <width>50</width>
+            <height>55</height>
+            <description>Image description</description>
+        </image>
+    </channel>
+</rss>

+ 13 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss093.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.93">
+    <channel>
+        <image>
+            <url>http://www.example.com/image.gif</url>
+            <link>http://www.example.com</link>
+            <title>Image title</title>
+            <width>50</width>
+            <height>55</height>
+            <description>Image description</description>
+        </image>
+    </channel>
+</rss>

+ 13 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss094.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="0.94">
+    <channel>
+        <image>
+            <url>http://www.example.com/image.gif</url>
+            <link>http://www.example.com</link>
+            <title>Image title</title>
+            <width>50</width>
+            <height>55</height>
+            <description>Image description</description>
+        </image>
+    </channel>
+</rss>

+ 15 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss10.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rdf:RDF
+    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+    xmlns="http://purl.org/rss/1.0/">
+    <channel>
+        <image>
+            <url>http://www.example.com/image.gif</url>
+            <link>http://www.example.com</link>
+            <title>Image title</title>
+            <width>50</width>
+            <height>55</height>
+            <description>Image description</description>
+        </image>
+    </channel>
+</rdf:RDF>

+ 13 - 0
tests/Zend/Feed/Reader/Feed/_files/Rss/image/plain/rss20.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<rss version="2.0">
+    <channel>
+        <image>
+            <url>http://www.example.com/image.gif</url>
+            <link>http://www.example.com</link>
+            <title>Image title</title>
+            <width>50</width>
+            <height>55</height>
+            <description>Image description</description>
+        </image>
+    </channel>
+</rss>

+ 109 - 0
tests/Zend/Feed/Writer/FeedTest.php

@@ -686,6 +686,115 @@ class Zend_Feed_Writer_FeedTest extends PHPUnit_Framework_TestCase
         }
     }
 
+    // Image Tests
+
+    public function testSetsImageUri()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => 'http://www.example.com/logo.gif'
+        ));
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/logo.gif'
+        ), $writer->getImage());
+    }
+
+    /**
+     * @expectedException Zend_Feed_Exception
+     */
+    public function testSetsImageUriThrowsExceptionOnEmptyUri()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => ''
+        ));
+    }
+
+    /**
+     * @expectedException Zend_Feed_Exception
+     */
+    public function testSetsImageUriThrowsExceptionOnMissingUri()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array());
+    }
+
+    /**
+     * @expectedException Zend_Feed_Exception
+     */
+    public function testSetsImageUriThrowsExceptionOnInvalidUri()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => 'http://'
+        ));
+    }
+
+    public function testSetsImageLink()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'link' => 'http://www.example.com'
+        ));
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'link' => 'http://www.example.com'
+        ), $writer->getImage());
+    }
+
+    public function testSetsImageTitle()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'title' => 'Image title'
+        ));
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'title' => 'Image title'
+        ), $writer->getImage());
+    }
+
+    public function testSetsImageHeight()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'height' => '88'
+        ));
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'height' => '88'
+        ), $writer->getImage());
+    }
+
+    public function testSetsImageWidth()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'width' => '88'
+        ));
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'width' => '88'
+        ), $writer->getImage());
+    }
+    
+    public function testSetsImageDescription()
+    {
+        $writer = new Zend_Feed_Writer_Feed;
+        $writer->setImage(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'description' => 'Image description'
+        ));
+        $this->assertEquals(array(
+            'uri' => 'http://www.example.com/logo.gif',
+            'description' => 'Image description'
+        ), $writer->getImage());
+    }
+
     public function testGetCategoriesReturnsNullIfNotSet()
     {
         $writer = new Zend_Feed_Writer_Feed;