Skip to content

Commit cc52252

Browse files
MAGETWO-70886: Zend feed refactoring #9347
2 parents 4cf1a32 + fd178e8 commit cc52252

File tree

9 files changed

+257
-17
lines changed

9 files changed

+257
-17
lines changed

app/code/Magento/Rss/Model/Rss.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Magento\Framework\App\ObjectManager;
99
use Magento\Framework\App\Rss\DataProviderInterface;
1010
use Magento\Framework\Serialize\SerializerInterface;
11-
use Zend\Feed\Writer\FeedFactory;
11+
use Magento\Framework\App\FeedFactoryInterface;
1212

1313
/**
1414
* Provides functionality to work with RSS feeds
@@ -28,6 +28,11 @@ class Rss
2828
*/
2929
protected $cache;
3030

31+
/**
32+
* @var \Magento\Framework\App\FeedFactoryInterface
33+
*/
34+
private $feedFactory;
35+
3136
/**
3237
* @var SerializerInterface
3338
*/
@@ -38,13 +43,16 @@ class Rss
3843
*
3944
* @param \Magento\Framework\App\CacheInterface $cache
4045
* @param SerializerInterface|null $serializer
46+
* @param FeedFactoryInterface|null $feedFactory
4147
*/
4248
public function __construct(
4349
\Magento\Framework\App\CacheInterface $cache,
44-
SerializerInterface $serializer = null
50+
SerializerInterface $serializer = null,
51+
FeedFactoryInterface $feedFactory = null
4552
) {
4653
$this->cache = $cache;
4754
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
55+
$this->feedFactory = $feedFactory ?: ObjectManager::getInstance()->get(FeedFactoryInterface::class);
4856
}
4957

5058
/**
@@ -90,10 +98,12 @@ public function setDataProvider(DataProviderInterface $dataProvider)
9098

9199
/**
92100
* @return string
101+
* @throws \Magento\Framework\Exception\InputException
102+
* @throws \Magento\Framework\Exception\RuntimeException
93103
*/
94104
public function createRssXml()
95105
{
96-
$feed = FeedFactory::factory($this->getFeeds());
97-
return $feed->export('rss');
106+
$feed = $this->feedFactory->create($this->getFeeds(), FeedFactoryInterface::FORMAT_RSS);
107+
return $feed->getFormattedContent();
98108
}
99109
}

app/code/Magento/Rss/Test/Unit/Controller/Adminhtml/Feed/IndexTest.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,22 @@ public function testExecuteWithException()
104104
$dataProvider = $this->createMock(\Magento\Framework\App\Rss\DataProviderInterface::class);
105105
$dataProvider->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
106106

107-
$rssModel = $this->createPartialMock(\Magento\Rss\Model\Rss::class, ['setDataProvider']);
107+
$rssModel = $this->createPartialMock(\Magento\Rss\Model\Rss::class, ['setDataProvider', 'createRssXml']);
108108
$rssModel->expects($this->once())->method('setDataProvider')->will($this->returnSelf());
109109

110+
$exceptionMock = new \Magento\Framework\Exception\RuntimeException(
111+
new \Magento\Framework\Phrase('Any message')
112+
);
113+
114+
$rssModel->expects($this->once())->method('createRssXml')->will(
115+
$this->throwException($exceptionMock)
116+
);
117+
110118
$this->response->expects($this->once())->method('setHeader')->will($this->returnSelf());
111119
$this->rssFactory->expects($this->once())->method('create')->will($this->returnValue($rssModel));
112120
$this->rssManager->expects($this->once())->method('getProvider')->will($this->returnValue($dataProvider));
113121

114-
$this->expectException(InvalidArgumentException::class);
122+
$this->expectException(\Magento\Framework\Exception\RuntimeException::class);
115123
$this->controller->execute();
116124
}
117125
}

app/code/Magento/Rss/Test/Unit/Controller/Feed/IndexTest.php

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ protected function setUp()
5353
->disableOriginalConstructor()->getMock();
5454

5555
$objectManagerHelper = new ObjectManagerHelper($this);
56+
5657
$this->controller = $objectManagerHelper->getObject(
5758
\Magento\Rss\Controller\Feed\Index::class,
5859
[
@@ -91,14 +92,22 @@ public function testExecuteWithException()
9192
$dataProvider = $this->createMock(\Magento\Framework\App\Rss\DataProviderInterface::class);
9293
$dataProvider->expects($this->once())->method('isAllowed')->will($this->returnValue(true));
9394

94-
$rssModel = $this->createPartialMock(\Magento\Rss\Model\Rss::class, ['setDataProvider']);
95+
$rssModel = $this->createPartialMock(\Magento\Rss\Model\Rss::class, ['setDataProvider', 'createRssXml']);
9596
$rssModel->expects($this->once())->method('setDataProvider')->will($this->returnSelf());
9697

98+
$exceptionMock = new \Magento\Framework\Exception\RuntimeException(
99+
new \Magento\Framework\Phrase('Any message')
100+
);
101+
102+
$rssModel->expects($this->once())->method('createRssXml')->will(
103+
$this->throwException($exceptionMock)
104+
);
105+
97106
$this->response->expects($this->once())->method('setHeader')->will($this->returnSelf());
98107
$this->rssFactory->expects($this->once())->method('create')->will($this->returnValue($rssModel));
99108
$this->rssManager->expects($this->once())->method('getProvider')->will($this->returnValue($dataProvider));
100109

101-
$this->expectException(InvalidArgumentException::class);
110+
$this->expectException(\Magento\Framework\Exception\RuntimeException::class);
102111
$this->controller->execute();
103112
}
104113
}

app/code/Magento/Rss/Test/Unit/Model/RssTest.php

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class RssTest extends \PHPUnit\Framework\TestCase
1919
/**
2020
* @var array
2121
*/
22-
protected $feedData = [
22+
private $feedData = [
2323
'title' => 'Feed Title',
2424
'link' => 'http://magento.com/rss/link',
2525
'description' => 'Feed Description',
@@ -33,6 +33,27 @@ class RssTest extends \PHPUnit\Framework\TestCase
3333
],
3434
];
3535

36+
/**
37+
* @var string
38+
*/
39+
private $feedXml = '<?xml version="1.0" encoding="UTF-8"?>
40+
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
41+
<channel>
42+
<title><![CDATA[Feed Title]]></title>
43+
<link>http://magento.com/rss/link</link>
44+
<description><![CDATA[Feed Description]]></description>
45+
<pubDate>Sat, 22 Apr 2017 13:21:12 +0200</pubDate>
46+
<generator>Zend\Feed</generator>
47+
<docs>http://blogs.law.harvard.edu/tech/rss</docs>
48+
<item>
49+
<title><![CDATA[Feed 1 Title]]></title>
50+
<link>http://magento.com/rss/link/id/1</link>
51+
<description><![CDATA[Feed 1 Description]]></description>
52+
<pubDate>Sat, 22 Apr 2017 13:21:12 +0200</pubDate>
53+
</item>
54+
</channel>
55+
</rss>';
56+
3657
/**
3758
* @var ObjectManagerHelper
3859
*/
@@ -43,6 +64,16 @@ class RssTest extends \PHPUnit\Framework\TestCase
4364
*/
4465
private $cacheMock;
4566

67+
/**
68+
* @var \Magento\Framework\App\FeedFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
69+
*/
70+
private $feedFactoryMock;
71+
72+
/**
73+
* @var \Magento\Framework\App\FeedInterface|\PHPUnit_Framework_MockObject_MockObject
74+
*/
75+
private $feedMock;
76+
4677
/**
4778
* @var SerializerInterface|\PHPUnit_Framework_MockObject_MockObject
4879
*/
@@ -52,11 +83,15 @@ protected function setUp()
5283
{
5384
$this->cacheMock = $this->createMock(\Magento\Framework\App\CacheInterface::class);
5485
$this->serializerMock = $this->createMock(SerializerInterface::class);
86+
$this->feedFactoryMock = $this->createMock(\Magento\Framework\App\FeedFactoryInterface::class);
87+
$this->feedMock = $this->createMock(\Magento\Framework\App\FeedInterface::class);
88+
5589
$this->objectManagerHelper = new ObjectManagerHelper($this);
5690
$this->rss = $this->objectManagerHelper->getObject(
5791
\Magento\Rss\Model\Rss::class,
5892
[
5993
'cache' => $this->cacheMock,
94+
'feedFactory' => $this->feedFactoryMock,
6095
'serializer' => $this->serializerMock
6196
]
6297
);
@@ -116,14 +151,16 @@ public function testCreateRssXml()
116151
$dataProvider->expects($this->any())->method('getCacheLifetime')->will($this->returnValue(100));
117152
$dataProvider->expects($this->any())->method('getRssData')->will($this->returnValue($this->feedData));
118153

154+
$this->feedMock->expects($this->once())
155+
->method('getFormattedContent')
156+
->willReturn($this->feedXml);
157+
158+
$this->feedFactoryMock->expects($this->once())
159+
->method('create')
160+
->with($this->feedData, \Magento\Framework\App\FeedFactoryInterface::FORMAT_RSS)
161+
->will($this->returnValue($this->feedMock));
162+
119163
$this->rss->setDataProvider($dataProvider);
120-
$result = $this->rss->createRssXml();
121-
$this->assertContains('<?xml version="1.0" encoding="UTF-8"?>', $result);
122-
$this->assertContains('<title>Feed Title</title>', $result);
123-
$this->assertContains('<title>Feed 1 Title</title>', $result);
124-
$this->assertContains('<link>http://magento.com/rss/link</link>', $result);
125-
$this->assertContains('<link>http://magento.com/rss/link/id/1</link>', $result);
126-
$this->assertContains('<description>Feed Description</description>', $result);
127-
$this->assertContains('<description><![CDATA[Feed 1 Description]]></description>', $result);
164+
$this->assertNotNull($this->rss->createRssXml());
128165
}
129166
}

app/etc/di.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@
174174
<preference for="Magento\Framework\App\View\Deployment\Version\StorageInterface" type="Magento\Framework\App\View\Deployment\Version\Storage\File"/>
175175
<preference for="Magento\Framework\View\Page\FaviconInterface" type="Magento\Theme\Model\Favicon\Favicon" />
176176
<preference for="Magento\Framework\View\Element\Message\InterpretationStrategyInterface" type="Magento\Framework\View\Element\Message\InterpretationMediator" />
177+
<preference for="Magento\Framework\App\FeedInterface" type="Magento\Framework\App\Feed" />
178+
<preference for="Magento\Framework\App\FeedFactoryInterface" type="Magento\Framework\App\FeedFactory" />
177179
<preference for="Magento\Framework\Indexer\Config\DependencyInfoProviderInterface" type="Magento\Framework\Indexer\Config\DependencyInfoProvider" />
178180
<preference for="Magento\Framework\Webapi\CustomAttribute\ServiceTypeListInterface" type="Magento\Eav\Model\TypeLocator\ComplexType"/>
179181
<preference for="Magento\Framework\MultiDimensionalIndexer\IndexTableSwitcherInterface" type="Magento\Framework\MultiDimensionalIndexer\IndexTableSwitcher" />
@@ -282,6 +284,13 @@
282284
</argument>
283285
</arguments>
284286
</type>
287+
<type name="Magento\Framework\App\FeedFactory">
288+
<arguments>
289+
<argument name="formats" xsi:type="array">
290+
<item name="rss" xsi:type="string">Magento\Framework\App\Feed</item>
291+
</argument>
292+
</arguments>
293+
</type>
285294
<type name="Magento\Framework\Session\SaveHandler\Redis">
286295
<arguments>
287296
<argument name="config" xsi:type="object">Cm\RedisSession\Handler\ConfigInterface</argument>
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\App;
9+
10+
use Zend\Feed\Writer\FeedFactory;
11+
12+
/**
13+
* Default XML feed class
14+
*/
15+
class Feed implements FeedInterface
16+
{
17+
/**
18+
* @var array
19+
*/
20+
private $feeds;
21+
22+
/**
23+
* Feed constructor.
24+
* @param array $data
25+
*/
26+
public function __construct(array $data)
27+
{
28+
$this->feeds = $data;
29+
}
30+
31+
/**
32+
* {@inheritdoc}
33+
*/
34+
public function getFormattedContent() : string
35+
{
36+
return FeedFactory::factory($this->feeds)->export(FeedFactoryInterface::FORMAT_RSS);
37+
}
38+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\App;
9+
10+
use Magento\Framework\ObjectManagerInterface;
11+
use Psr\Log\LoggerInterface;
12+
13+
/**
14+
* Feed factory
15+
*/
16+
class FeedFactory implements FeedFactoryInterface
17+
{
18+
/**
19+
* @var ObjectManagerInterface
20+
*/
21+
private $objectManager;
22+
23+
/**
24+
* @var LoggerInterface
25+
*/
26+
private $logger;
27+
28+
/**
29+
* @var array
30+
*/
31+
private $formats;
32+
33+
/**
34+
* @param ObjectManagerInterface $objectManger
35+
* @param LoggerInterface $logger
36+
* @param array $formats
37+
*/
38+
public function __construct(
39+
ObjectManagerInterface $objectManger,
40+
LoggerInterface $logger,
41+
array $formats
42+
) {
43+
$this->objectManager = $objectManger;
44+
$this->logger = $logger;
45+
$this->formats = $formats;
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*/
51+
public function create(array $data, string $format = FeedFactoryInterface::FORMAT_RSS) : FeedInterface
52+
{
53+
if (!isset($this->formats[$format])) {
54+
throw new \Magento\Framework\Exception\InputException(
55+
new \Magento\Framework\Phrase('The format is not supported')
56+
);
57+
}
58+
59+
if (!is_subclass_of($this->formats[$format], \Magento\Framework\App\FeedInterface::class)) {
60+
throw new \Magento\Framework\Exception\InputException(
61+
new \Magento\Framework\Phrase('Wrong format handler type')
62+
);
63+
}
64+
65+
try {
66+
return $this->objectManager->create(
67+
$this->formats[$format],
68+
['data' => $data]
69+
);
70+
} catch (\Exception $e) {
71+
$this->logger->error($e->getMessage());
72+
throw new \Magento\Framework\Exception\RuntimeException(
73+
new \Magento\Framework\Phrase('There has been an error with import'),
74+
$e
75+
);
76+
}
77+
}
78+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\App;
9+
10+
/**
11+
* Feed factory interface
12+
*/
13+
interface FeedFactoryInterface
14+
{
15+
/**
16+
* RSS feed input format
17+
*/
18+
const FORMAT_RSS = 'rss';
19+
20+
/**
21+
* Returns FeedInterface object from a custom array
22+
*
23+
* @throws \Magento\Framework\Exception\InputException
24+
* @throws \Magento\Framework\Exception\RuntimeException
25+
* @param array $data
26+
* @param string $format
27+
* @return FeedInterface
28+
*/
29+
public function create(array $data, string $format = self::FORMAT_RSS) : FeedInterface;
30+
}

0 commit comments

Comments
 (0)