Skip to content
This repository has been archived by the owner on Jan 30, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/77-itunes-image' into develop
Browse files Browse the repository at this point in the history
Close #77
Fixes #76
  • Loading branch information
weierophinney committed May 24, 2018
2 parents a095333 + 7333501 commit b957642
Show file tree
Hide file tree
Showing 10 changed files with 199 additions and 18 deletions.
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ All notable changes to this project will be documented in this file, in reverse

### Added

- Nothing.
- [#77](https://github.com/zendframework/zend-feed/pull/77) adds support for `itunes:image` for each of:
- `Zend\Feed\Reader\Extension\Podcast\Entry`, via `getItunesImage()`; previously only the `Feed` supported it.
- `Zend\Feed\Writer\Extension\ITunes\Entry`, via `setItunesImage()`; previously only the `Feed` supported it.
- `Zend\Feed\Writer\Extension\ITunes\Renderer\Entry`; previously on the `Feed` supported it.

### Changed

- Nothing.
- [#77](https://github.com/zendframework/zend-feed/pull/77) updates URI validation for `Zend\Feed\Writer\Extension\ITunes\Feed::setItunesImage()` to
first check that we have received a string value before proceeding.

### Deprecated

Expand Down
32 changes: 25 additions & 7 deletions src/Reader/Extension/Podcast/Entry.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @see https://github.com/zendframework/zend-feed for the canonical source repository
* @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-feed/blob/master/LICENSE.md New BSD License
*/

namespace Zend\Feed\Reader\Extension\Podcast;

use Zend\Feed\Reader\Extension;

/**
*/
class Entry extends Extension\AbstractEntry
{
/**
Expand Down Expand Up @@ -169,6 +165,28 @@ public function getSummary()
return $this->data['summary'];
}

/**
* Get the entry image
*
* @return string
*/
public function getItunesImage()
{
if (isset($this->data['image'])) {
return $this->data['image'];
}

$image = $this->xpath->evaluate('string(' . $this->getXpathPrefix() . '/itunes:image/@href)');

if (! $image) {
$image = null;
}

$this->data['image'] = $image;

return $this->data['image'];
}

/**
* Register iTunes namespace
*
Expand Down
12 changes: 4 additions & 8 deletions src/Reader/Extension/Podcast/Feed.php
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @see https://github.com/zendframework/zend-feed for the canonical source repository
* @copyright Copyright (c) 2005-2018 Zend Technologies USA Inc. (https://www.zend.com)
* @license https://github.com/zendframework/zend-feed/blob/master/LICENSE.md New BSD License
*/

namespace Zend\Feed\Reader\Extension\Podcast;

use DOMText;
use Zend\Feed\Reader\Extension;

/**
*/
class Feed extends Extension\AbstractFeed
{
/**
Expand Down Expand Up @@ -125,7 +121,7 @@ public function getExplicit()
}

/**
* Get the entry image
* Get the feed/podcast image
*
* @return string
*/
Expand Down
28 changes: 28 additions & 0 deletions src/Writer/Extension/ITunes/Entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace Zend\Feed\Writer\Extension\ITunes;

use Zend\Feed\Uri;
use Zend\Feed\Writer;
use Zend\Stdlib\StringUtils;
use Zend\Stdlib\StringWrapper\StringWrapperInterface;
Expand Down Expand Up @@ -217,6 +218,33 @@ public function setItunesSummary($value)
return $this;
}

/**
* Set entry image (icon)
*
* @param string $value
* @return Feed
* @throws Writer\Exception\InvalidArgumentException
*/
public function setItunesImage($value)
{
if (! is_string($value) || ! Uri::factory($value)->isValid()) {
throw new Writer\Exception\InvalidArgumentException(
'invalid parameter: "image" may only be a valid URI/IRI'
);
}

if (! in_array(substr($value, -3), ['jpg', 'png'])) {
throw new Writer\Exception\InvalidArgumentException(
'invalid parameter: "image" may only use file extension "jpg"'
. ' or "png" which must be the last three characters of the URI'
. ' (i.e. no query string or fragment)'
);
}

$this->data['image'] = $value;
return $this;
}

/**
* Overloading to itunes specific setters
*
Expand Down
2 changes: 1 addition & 1 deletion src/Writer/Extension/ITunes/Feed.php
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ public function setItunesCategories(array $values)
*/
public function setItunesImage($value)
{
if (! Uri::factory($value)->isValid()) {
if (! is_string($value) || ! Uri::factory($value)->isValid()) {
throw new Writer\Exception\InvalidArgumentException('invalid parameter: "image" may only'
. ' be a valid URI/IRI');
}
Expand Down
22 changes: 22 additions & 0 deletions src/Writer/Extension/ITunes/Renderer/Entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function render()
$this->_setAuthors($this->dom, $this->base);
$this->_setBlock($this->dom, $this->base);
$this->_setDuration($this->dom, $this->base);
$this->_setImage($this->dom, $this->base);
$this->_setExplicit($this->dom, $this->base);
$this->_setKeywords($this->dom, $this->base);
$this->_setSubtitle($this->dom, $this->base);
Expand Down Expand Up @@ -128,6 +129,27 @@ protected function _setDuration(DOMDocument $dom, DOMElement $root)
$this->called = true;
}

/**
* Set feed image (icon)
*
* @param DOMDocument $dom
* @param DOMElement $root
* @return void
*/
// @codingStandardsIgnoreStart
protected function _setImage(DOMDocument $dom, DOMElement $root)
{
// @codingStandardsIgnoreEnd
$image = $this->getDataContainer()->getItunesImage();
if (! $image) {
return;
}
$el = $dom->createElement('itunes:image');
$el->setAttribute('href', $image);
$root->appendChild($el);
$this->called = true;
}

/**
* Set explicit flag
*
Expand Down
12 changes: 12 additions & 0 deletions test/Reader/Integration/PodcastRss2Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,16 @@ public function testGetsEnclosure()

$this->assertEquals($expected, $entry->getEnclosure());
}

public function testCanRetrieveEntryImage()
{
$feed = Reader\Reader::importString(
file_get_contents($this->feedSamplePath)
);
$entry = $feed->current();
$this->assertEquals(
'https://www.example.com/podcasts/everything/episode.png',
$entry->getItunesImage()
);
}
}
1 change: 1 addition & 0 deletions test/Reader/Integration/_files/podcast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
<itunes:duration>7:04</itunes:duration>
<itunes:keywords>salt, pepper, shaker, exciting
</itunes:keywords>
<itunes:image href="https://www.example.com/podcasts/everything/episode.png" />
</item>

<item>
Expand Down
50 changes: 50 additions & 0 deletions test/Writer/Extension/ITunes/EntryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,54 @@ public function testSetSummaryThrowsExceptionWhenValueExceeds255Chars()
$entry = new Writer\Entry;
$entry->setItunesSummary(str_repeat('a', 4001));
}

public function invalidImageUrls()
{
return [
'null' => [null],
'true' => [true],
'false' => [false],
'zero' => [0],
'int' => [1],
'zero-float' => [0.0],
'float' => [1.1],
'string' => ['scheme:/host.path'],
'invalid-extension-gif' => ['https://example.com/image.gif', 'file extension'],
'invalid-extension-uc' => ['https://example.com/image.PNG', 'file extension'],
'array' => [['https://example.com/image.png']],
'object' => [(object) ['image' => 'https://example.com/image.png']],
];
}

/**
* @dataProvider invalidImageUrls
* @param mixed $url
* @param string $expectedMessage
*/
public function testSetItunesImageRaisesExceptionForInvalidUrl($url, $expectedMessage = 'valid URI')
{
$entry = new Writer\Entry();
$this->expectException(ExceptionInterface::class);
$this->expectExceptionMessage($expectedMessage);
$entry->setItunesImage($url);
}

public function validImageUrls()
{
return [
'jpg' => ['https://example.com/image.jpg'],
'png' => ['https://example.com/image.png'],
];
}

/**
* @dataProvider validImageUrls
* @param string $url
*/
public function testSetItunesImageSetsInternalDataWithValidUrl($url)
{
$entry = new Writer\Entry();
$entry->setItunesImage($url);
$this->assertEquals($url, $entry->getItunesImage());
}
}
50 changes: 50 additions & 0 deletions test/Writer/Extension/ITunes/FeedTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,54 @@ public function testSetSummaryThrowsExceptionWhenValueExceeds4000Chars()
$feed = new Writer\Feed;
$feed->setItunesSummary(str_repeat('a', 4001));
}

public function invalidImageUrls()
{
return [
'null' => [null],
'true' => [true],
'false' => [false],
'zero' => [0],
'int' => [1],
'zero-float' => [0.0],
'float' => [1.1],
'string' => ['scheme:/host.path'],
'invalid-extension-gif' => ['https://example.com/image.gif', 'file extension'],
'invalid-extension-uc' => ['https://example.com/image.PNG', 'file extension'],
'array' => [['https://example.com/image.png']],
'object' => [(object) ['image' => 'https://example.com/image.png']],
];
}

/**
* @dataProvider invalidImageUrls
* @param mixed $url
* @param string $expectedMessage
*/
public function testSetItunesImageRaisesExceptionForInvalidUrl($url, $expectedMessage = 'valid URI')
{
$feed = new Writer\Feed();
$this->expectException(ExceptionInterface::class);
$this->expectExceptionMessage($expectedMessage);
$feed->setItunesImage($url);
}

public function validImageUrls()
{
return [
'jpg' => ['https://example.com/image.jpg'],
'png' => ['https://example.com/image.png'],
];
}

/**
* @dataProvider validImageUrls
* @param string $url
*/
public function testSetItunesImageSetsInternalDataWithValidUrl($url)
{
$feed = new Writer\Feed();
$feed->setItunesImage($url);
$this->assertEquals($url, $feed->getItunesImage());
}
}

0 comments on commit b957642

Please sign in to comment.