Skip to content

Commit 906cf5c

Browse files
committed
Allow CDATA for title and description #16
Signed-off-by: Hidehito Nozawa <[email protected]>
1 parent c29057b commit 906cf5c

File tree

6 files changed

+69
-11
lines changed

6 files changed

+69
-11
lines changed

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
test:
2+
docker-compose up php54
3+
docker-compose up php55
4+
docker-compose up php56
5+
docker-compose up php70

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ $channel
3333
$item = new Item();
3434
$item
3535
->title('Blog Entry Title')
36-
->description('Blog body')
36+
->description('<div>Blog body</div>')
3737
->contentEncoded('<div>Blog body</div>')
3838
->url('http://blog.example.com/2012/08/21/blog-entry/')
3939
->author('Hidehito Nozawa')
4040
->pubDate(strtotime('Tue, 21 Aug 2012 19:50:37 +0900'))
4141
->guid('http://blog.example.com/2012/08/21/blog-entry/', true)
42+
->preferCdata(true) // By this, title and description become CDATA wrapped HTML.
4243
->appendTo($channel);
4344

4445
// Podcast item
@@ -68,9 +69,9 @@ Output:
6869
<lastBuildDate>Tue, 21 Aug 2012 10:50:37 +0000</lastBuildDate>
6970
<ttl>60</ttl>
7071
<item xmlns:default="http://purl.org/rss/1.0/modules/content/">
71-
<title>Blog Entry Title</title>
72+
<title><![CDATA[Blog Entry Title]]></title>
7273
<link>http://blog.example.com/2012/08/21/blog-entry/</link>
73-
<description>Blog body</description>
74+
<description><![CDATA[<div>Blog body</div>]]></description>
7475
<content:encoded xmlns="http://purl.org/rss/1.0/modules/content/"><![CDATA[<div>Blog body</div>]]></content:encoded>
7576
<guid>http://blog.example.com/2012/08/21/blog-entry/</guid>
7677
<pubDate>Tue, 21 Aug 2012 10:50:37 +0000</pubDate>

examples/simple-feed.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,13 @@
2828
$item = new Item();
2929
$item
3030
->title('Blog Entry Title')
31-
->description('Blog body')
31+
->description('<div>Blog body</div>')
3232
->contentEncoded('<div>Blog body</div>')
3333
->url('http://blog.example.com/2012/08/21/blog-entry/')
3434
->author('Hidehito Nozawa')
3535
->pubDate(strtotime('Tue, 21 Aug 2012 19:50:37 +0900'))
3636
->guid('http://blog.example.com/2012/08/21/blog-entry/', true)
37+
->preferCdata(true) // By this, title and description become CDATA wrapped HTML.
3738
->appendTo($channel);
3839

3940
// Podcast item

src/Suin/RSSWriter/Item.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ class Item implements ItemInterface
3838
/** @var string */
3939
protected $author;
4040

41+
protected $preferCdata = false;
42+
4143
public function title($title)
4244
{
4345
$this->title = $title;
@@ -93,6 +95,12 @@ public function author($author)
9395
return $this;
9496
}
9597

98+
public function preferCdata($preferCdata)
99+
{
100+
$this->preferCdata = (bool)$preferCdata;
101+
return $this;
102+
}
103+
96104
public function appendTo(ChannelInterface $channel)
97105
{
98106
$channel->addItem($this);
@@ -102,16 +110,23 @@ public function appendTo(ChannelInterface $channel)
102110
public function asXML()
103111
{
104112
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8" ?><item></item>', LIBXML_NOERROR | LIBXML_ERR_NONE | LIBXML_ERR_FATAL);
105-
$xml->addChild('title', $this->title);
113+
114+
if ($this->preferCdata) {
115+
$xml->addCdataChild('title', $this->title);
116+
} else {
117+
$xml->addChild('title', $this->title);
118+
}
119+
106120
$xml->addChild('link', $this->url);
107-
$xml->addChild('description', $this->description);
121+
122+
if ($this->preferCdata) {
123+
$xml->addCdataChild('description', $this->description);
124+
} else {
125+
$xml->addChild('description', $this->description);
126+
}
108127

109128
if ($this->contentEncoded) {
110-
// SimpleXMLElement does not support CDATA transformation
111-
$element = $xml->addChild('encoded', null, 'http://purl.org/rss/1.0/modules/content/');
112-
$element = dom_import_simplexml($element);
113-
$elementOwner = $element->ownerDocument;
114-
$element->appendChild($elementOwner->createCDATASection($this->contentEncoded));
129+
$xml->addCdataChild('encoded', $this->contentEncoded, 'http://purl.org/rss/1.0/modules/content/');
115130
}
116131

117132
foreach ($this->categories as $category) {

src/Suin/RSSWriter/SimpleXMLElement.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,12 @@ public function addChild($name, $value = null, $namespace = null)
1616

1717
return parent::addChild($name, $value, $namespace);
1818
}
19+
20+
public function addCdataChild($name, $value = null, $namespace = null)
21+
{
22+
$element = $this->addChild($name, null, $namespace);
23+
$element = dom_import_simplexml($element);
24+
$elementOwner = $element->ownerDocument;
25+
$element->appendChild($elementOwner->createCDATASection($value));
26+
}
1927
}

tests/Suin/RSSWriter/ItemTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,34 @@ public function testAuthor()
135135
$this->assertAttributeSame($author, 'author', $item);
136136
}
137137

138+
public function testPreferCdata()
139+
{
140+
$item = new Item();
141+
$item->title('<h1>title</h1>');
142+
$item->description('<p>description</p>');
143+
144+
// By default, prefer no CDATA on title and description
145+
$actualXml = $item->asXML()->asXML();
146+
$this->assertContains('<title>&lt;h1&gt;title&lt;/h1&gt;</title>', $actualXml);
147+
$this->assertContains('<description>&lt;p&gt;description&lt;/p&gt;</description>', $actualXml);
148+
149+
// Once prefer-cdata is enabled, title and description is wrapped by CDATA
150+
$item->preferCdata(true);
151+
$actualXml = $item->asXML()->asXML();
152+
$this->assertContains('<title><![CDATA[<h1>title</h1>]]></title>', $actualXml);
153+
$this->assertContains('<description><![CDATA[<p>description</p>]]></description>', $actualXml);
154+
155+
// Of course, prefer-cdata can be disabled again
156+
$item->preferCdata(false);
157+
$actualXml = $item->asXML()->asXML();
158+
$this->assertContains('<title>&lt;h1&gt;title&lt;/h1&gt;</title>', $actualXml);
159+
$this->assertContains('<description>&lt;p&gt;description&lt;/p&gt;</description>', $actualXml);
160+
161+
// And like other APIs `preferCdata` is also fluent interface
162+
$obj = $item->preferCdata(true);
163+
$this->assertSame($obj, $item);
164+
}
165+
138166
public function testAsXML()
139167
{
140168
$now = time();

0 commit comments

Comments
 (0)