Skip to content

Commit

Permalink
Use serialized view as parent.
Browse files Browse the repository at this point in the history
  • Loading branch information
dereuromark committed Jan 2, 2024
1 parent 6a8784b commit 9b13685
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 57 deletions.
61 changes: 17 additions & 44 deletions src/View/RssView.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Cake\Routing\Router;
use Cake\Utility\Hash;
use Cake\Utility\Xml;
use Cake\View\View;
use Cake\View\SerializedView;
use RuntimeException;

/**
Expand Down Expand Up @@ -39,7 +39,7 @@
* @license http://www.opensource.org/licenses/mit-license.php MIT License
* @link https://www.dereuromark.de/2013/10/03/rss-feeds-in-cakephp
*/
class RssView extends View {
class RssView extends SerializedView {

/**
* Default spec version of generated RSS.
Expand Down Expand Up @@ -91,8 +91,11 @@ class RssView extends View {
* @param \Cake\Event\EventManager|null $eventManager
* @param array $viewOptions
*/
public function __construct(?ServerRequest $request = null, ?Response &$response = null,
?EventManager $eventManager = null, array $viewOptions = [],
public function __construct(
?ServerRequest $request = null,
?Response &$response = null,
?EventManager $eventManager = null,
array $viewOptions = [],
) {
parent::__construct($request, $response, $eventManager, $viewOptions);

Expand All @@ -118,7 +121,7 @@ public static function contentType(): string {
* @param string $url
* @return void
*/
public function setNamespace($prefix, $url) {
public function setNamespace(string $prefix, string $url): void {
$this->_namespaces[$prefix] = $url;
}

Expand All @@ -128,7 +131,7 @@ public function setNamespace($prefix, $url) {
* @param array $channel
* @return array Channel
*/
public function channel($channel) {
public function channel(array $channel): array {
if (!isset($channel['link'])) {
$channel['link'] = '/';
}
Expand All @@ -151,7 +154,7 @@ public function channel($channel) {
* @param \DateTime|string|int $time
* @return string An RSS-formatted timestamp
*/
public function time($time) {
public function time($time): string {
$time = new DateTime($time);

return $time->toRssString();
Expand All @@ -172,44 +175,14 @@ public function loadHelpers() {
return $this;
}

/**
* Render a RSS view.
*
* Uses the special '_serialize' parameter to convert a set of
* view variables into a XML response. Makes generating simple
* XML responses very easy. You can omit the '_serialize' parameter,
* and use a normal view + layout as well.
*
* @param string|null $template The view being rendered.
* @param string|false|null $layout The layout being rendered.
* @return string The rendered view.
*/
public function render(?string $template = null, $layout = null): string {
if (isset($this->viewVars['_serialize'])) {
return $this->_serialize($this->viewVars['_serialize']);
}

/** @var string|false|null $template */
if ($template === false) {
trigger_error('Using false is deprecated, use empty string instead.', E_USER_DEPRECATED);
$template = '';
}

if ($template !== '' && $this->_getTemplateFileName($template)) {
return parent::render($template, false);
}

return '';
}

/**
* Serialize view vars.
*
* @param array|string $serialize The viewVars that need to be serialized.
* @throws \RuntimeException When the prefix is not specified
* @return string The serialized data
*/
protected function _serialize($serialize) {
protected function _serialize(array|string $serialize): string {
$rootNode = $this->viewVars['_rootNode'] ?? 'channel';

if (is_array($serialize)) {
Expand Down Expand Up @@ -277,16 +250,16 @@ protected function _serialize($serialize) {
* @param array $item
* @return array
*/
protected function _prepareOutput($item) {
protected function _prepareOutput(array $item): array {
foreach ($item as $key => $val) {
$prefix = null;
// The cast prevents a PHP bug for switch case and false positives with integers
$bareKey = (string)$key;

// Detect namespaces
if (strpos($key, ':') !== false) {
if (str_contains($key, ':')) {
[$prefix, $bareKey] = explode(':', $key, 2);
if (strpos($prefix, '@') !== false) {
if (str_contains($prefix, '@')) {
$prefix = substr($prefix, 1);
}
if (!in_array($prefix, $this->_usedNamespaces)) {
Expand Down Expand Up @@ -362,7 +335,7 @@ protected function _prepareOutput($item) {
break;
case 'enclosure':
if (isset($val['url']) && is_string($val['url']) && is_file(WWW_ROOT . $val['url']) && file_exists(WWW_ROOT . $val['url'])) {
if (!isset($val['length']) && strpos($val['url'], '://') === false) {
if (!isset($val['length']) && !str_contains($val['url'], '://')) {
$val['length'] = sprintf('%u', filesize(WWW_ROOT . $val['url']));
}
if (!isset($val['type']) && function_exists('mime_content_type')) {
Expand Down Expand Up @@ -393,7 +366,7 @@ protected function _prepareOutput($item) {
* @param string $content
* @return string
*/
protected function _newCdata($content) {
protected function _newCdata(string $content): string {
$i = count($this->_cdata);
$this->_cdata[$i] = $content;

Expand All @@ -404,7 +377,7 @@ protected function _newCdata($content) {
* @param string $content
* @return string
*/
protected function _replaceCdata($content) {
protected function _replaceCdata(string $content): string {
foreach ($this->_cdata as $n => $data) {
$data = '<![CDATA[' . $data . ']]>';
$content = str_replace('###CDATA-' . $n . '###', $data, $content);
Expand Down
52 changes: 39 additions & 13 deletions tests/TestCase/View/RssViewTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ public function testSerialize() {
'source' => ['url' => 'http://foo.bar', 'content' => 'Foo bar']],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -147,8 +149,10 @@ public function testSerializeWithPrefixes() {
'source' => 'http://foo.bar'],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$time = date('r', $time);
Expand Down Expand Up @@ -197,8 +201,10 @@ public function testSerializeWithUnconfiguredPrefix() {
['title' => 'Title Two'],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));

$this->expectException(RuntimeException::class);

Expand Down Expand Up @@ -229,8 +235,10 @@ public function testSerializeWithArrayLinks() {
['title' => 'Title Two', 'link' => ['controller' => 'Foo', 'action' => 'bar'], 'description' => 'Content two'],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -292,8 +300,10 @@ public function testSerializeWithContent() {
'content:encoded' => 'HTML <img src="http://domain.com/some/link/to/image.jpg"/> <b>content</b> two'],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -348,8 +358,10 @@ public function testSerializeWithCustomNamespace() {
['title' => 'Title One', 'link' => ['controller' => 'Foo', 'action' => 'bar']],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -394,8 +406,10 @@ public function testSerializeWithImage() {
['title' => 'Title One', 'link' => ['controller' => 'Foo', 'action' => 'bar']],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -450,8 +464,10 @@ public function testSerializeWithCategories() {
'comments' => ['controller' => 'Foo', 'action' => 'bar', '_ext' => 'rss']],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -507,8 +523,10 @@ public function testSerializeWithEnclosure() {
'enclosure' => ['url' => 'http://www.example.com/media/3d.wmv', 'length' => 78645, 'type' => 'video/wmv']],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -555,8 +573,10 @@ public function testSerializeWithCustomTags() {
'foo' => ['@url' => 'http://www.example.com/media/3d.wmv', '@length' => 78645, '@type' => 'video/wmv']],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -600,8 +620,10 @@ public function testSerializeWithSpecialChars() {
'description' => 'My content "&" and <other> stuff here should also be escaped safely'],
],
];
$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -659,8 +681,10 @@ public function testMedia() {
],
];

$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down Expand Up @@ -708,8 +732,10 @@ public function testIsPermalink() {
],
];

$viewVars = ['channel' => $data, '_serialize' => 'channel'];
$viewVars = ['channel' => $data];
$View = new RssView($Request, $Response, null, ['viewVars' => $viewVars]);
$serialize = 'channel';
$View->setConfig(compact('serialize'));
$result = $View->render('');

$expected = <<<RSS
Expand Down

0 comments on commit 9b13685

Please sign in to comment.