pictcode / lib / Cake / View / Helper / RssHelper.php @ 635eef61
履歴 | 表示 | アノテート | ダウンロード (9.271 KB)
1 | 635eef61 | spyder1211 | <?php
|
---|---|---|---|
2 | /**
|
||
3 | * RSS Helper class file.
|
||
4 | *
|
||
5 | * Simplifies the output of RSS feeds.
|
||
6 | *
|
||
7 | * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
|
||
8 | * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||
9 | *
|
||
10 | * Licensed under The MIT License
|
||
11 | * For full copyright and license information, please see the LICENSE.txt
|
||
12 | * Redistributions of files must retain the above copyright notice.
|
||
13 | *
|
||
14 | * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
|
||
15 | * @link http://cakephp.org CakePHP(tm) Project
|
||
16 | * @package Cake.View.Helper
|
||
17 | * @since CakePHP(tm) v 1.2
|
||
18 | * @license http://www.opensource.org/licenses/mit-license.php MIT License
|
||
19 | */
|
||
20 | |||
21 | App::uses('AppHelper', 'View/Helper'); |
||
22 | App::uses('Xml', 'Utility'); |
||
23 | |||
24 | /**
|
||
25 | * RSS Helper class for easy output RSS structures.
|
||
26 | *
|
||
27 | * @package Cake.View.Helper
|
||
28 | * @property TimeHelper $Time
|
||
29 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html
|
||
30 | */
|
||
31 | class RssHelper extends AppHelper { |
||
32 | |||
33 | /**
|
||
34 | * Helpers used by RSS Helper
|
||
35 | *
|
||
36 | * @var array
|
||
37 | */
|
||
38 | public $helpers = array('Time'); |
||
39 | |||
40 | /**
|
||
41 | * Base URL
|
||
42 | *
|
||
43 | * @var string
|
||
44 | */
|
||
45 | public $base = null; |
||
46 | |||
47 | /**
|
||
48 | * URL to current action.
|
||
49 | *
|
||
50 | * @var string
|
||
51 | */
|
||
52 | public $here = null; |
||
53 | |||
54 | /**
|
||
55 | * Parameter array.
|
||
56 | *
|
||
57 | * @var array
|
||
58 | */
|
||
59 | public $params = array(); |
||
60 | |||
61 | /**
|
||
62 | * Current action.
|
||
63 | *
|
||
64 | * @var string
|
||
65 | */
|
||
66 | public $action = null; |
||
67 | |||
68 | /**
|
||
69 | * POSTed model data
|
||
70 | *
|
||
71 | * @var array
|
||
72 | */
|
||
73 | public $data = null; |
||
74 | |||
75 | /**
|
||
76 | * Name of the current model
|
||
77 | *
|
||
78 | * @var string
|
||
79 | */
|
||
80 | public $model = null; |
||
81 | |||
82 | /**
|
||
83 | * Name of the current field
|
||
84 | *
|
||
85 | * @var string
|
||
86 | */
|
||
87 | public $field = null; |
||
88 | |||
89 | /**
|
||
90 | * Default spec version of generated RSS
|
||
91 | *
|
||
92 | * @var string
|
||
93 | */
|
||
94 | public $version = '2.0'; |
||
95 | |||
96 | /**
|
||
97 | * Returns an RSS document wrapped in `<rss />` tags
|
||
98 | *
|
||
99 | * @param array $attrib `<rss />` tag attributes
|
||
100 | * @param string $content Tag content.
|
||
101 | * @return string An RSS document
|
||
102 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::document
|
||
103 | */
|
||
104 | public function document($attrib = array(), $content = null) { |
||
105 | if ($content === null) { |
||
106 | $content = $attrib; |
||
107 | $attrib = array(); |
||
108 | } |
||
109 | if (!isset($attrib['version']) || empty($attrib['version'])) { |
||
110 | $attrib['version'] = $this->version; |
||
111 | } |
||
112 | |||
113 | return $this->elem('rss', $attrib, $content); |
||
114 | } |
||
115 | |||
116 | /**
|
||
117 | * Returns an RSS `<channel />` element
|
||
118 | *
|
||
119 | * @param array $attrib `<channel />` tag attributes
|
||
120 | * @param array $elements Named array elements which are converted to tags
|
||
121 | * @param string $content Content (`<item />`'s belonging to this channel
|
||
122 | * @return string An RSS `<channel />`
|
||
123 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::channel
|
||
124 | */
|
||
125 | public function channel($attrib = array(), $elements = array(), $content = null) { |
||
126 | if (!isset($elements['link'])) { |
||
127 | $elements['link'] = '/'; |
||
128 | } |
||
129 | if (!isset($elements['title'])) { |
||
130 | $elements['title'] = ''; |
||
131 | } |
||
132 | if (!isset($elements['description'])) { |
||
133 | $elements['description'] = ''; |
||
134 | } |
||
135 | $elements['link'] = $this->url($elements['link'], true); |
||
136 | |||
137 | $elems = ''; |
||
138 | foreach ($elements as $elem => $data) { |
||
139 | $attributes = array(); |
||
140 | if (is_array($data)) { |
||
141 | if (strtolower($elem) === 'cloud') { |
||
142 | $attributes = $data; |
||
143 | $data = array(); |
||
144 | } elseif (isset($data['attrib']) && is_array($data['attrib'])) { |
||
145 | $attributes = $data['attrib']; |
||
146 | unset($data['attrib']); |
||
147 | } else {
|
||
148 | $innerElements = ''; |
||
149 | foreach ($data as $subElement => $value) { |
||
150 | $innerElements .= $this->elem($subElement, array(), $value); |
||
151 | } |
||
152 | $data = $innerElements; |
||
153 | } |
||
154 | } |
||
155 | $elems .= $this->elem($elem, $attributes, $data); |
||
156 | } |
||
157 | return $this->elem('channel', $attrib, $elems . $content, !($content === null)); |
||
158 | } |
||
159 | |||
160 | /**
|
||
161 | * Transforms an array of data using an optional callback, and maps it to a set
|
||
162 | * of `<item />` tags
|
||
163 | *
|
||
164 | * @param array $items The list of items to be mapped
|
||
165 | * @param string|array $callback A string function name, or array containing an object
|
||
166 | * and a string method name
|
||
167 | * @return string A set of RSS `<item />` elements
|
||
168 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::items
|
||
169 | */
|
||
170 | public function items($items, $callback = null) { |
||
171 | if ($callback) { |
||
172 | $items = array_map($callback, $items); |
||
173 | } |
||
174 | |||
175 | $out = ''; |
||
176 | $c = count($items); |
||
177 | |||
178 | for ($i = 0; $i < $c; $i++) { |
||
179 | $out .= $this->item(array(), $items[$i]); |
||
180 | } |
||
181 | return $out; |
||
182 | } |
||
183 | |||
184 | /**
|
||
185 | * Converts an array into an `<item />` element and its contents
|
||
186 | *
|
||
187 | * @param array $att The attributes of the `<item />` element
|
||
188 | * @param array $elements The list of elements contained in this `<item />`
|
||
189 | * @return string An RSS `<item />` element
|
||
190 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::item
|
||
191 | */
|
||
192 | public function item($att = array(), $elements = array()) { |
||
193 | $content = null; |
||
194 | |||
195 | if (isset($elements['link']) && !isset($elements['guid'])) { |
||
196 | $elements['guid'] = $elements['link']; |
||
197 | } |
||
198 | |||
199 | foreach ($elements as $key => $val) { |
||
200 | $attrib = array(); |
||
201 | |||
202 | $escape = true; |
||
203 | if (is_array($val) && isset($val['convertEntities'])) { |
||
204 | $escape = $val['convertEntities']; |
||
205 | unset($val['convertEntities']); |
||
206 | } |
||
207 | |||
208 | switch ($key) { |
||
209 | case 'pubDate' : |
||
210 | $val = $this->time($val); |
||
211 | break;
|
||
212 | case 'category' : |
||
213 | if (is_array($val) && !empty($val[0])) { |
||
214 | foreach ($val as $category) { |
||
215 | $attrib = array(); |
||
216 | if (is_array($category) && isset($category['domain'])) { |
||
217 | $attrib['domain'] = $category['domain']; |
||
218 | unset($category['domain']); |
||
219 | } |
||
220 | $categories[] = $this->elem($key, $attrib, $category); |
||
221 | } |
||
222 | $elements[$key] = implode('', $categories); |
||
223 | continue 2; |
||
224 | } elseif (is_array($val) && isset($val['domain'])) { |
||
225 | $attrib['domain'] = $val['domain']; |
||
226 | } |
||
227 | break;
|
||
228 | case 'link': |
||
229 | case 'guid': |
||
230 | case 'comments': |
||
231 | if (is_array($val) && isset($val['url'])) { |
||
232 | $attrib = $val; |
||
233 | unset($attrib['url']); |
||
234 | $val = $val['url']; |
||
235 | } |
||
236 | $val = $this->url($val, true); |
||
237 | break;
|
||
238 | case 'source': |
||
239 | if (is_array($val) && isset($val['url'])) { |
||
240 | $attrib['url'] = $this->url($val['url'], true); |
||
241 | $val = $val['title']; |
||
242 | } elseif (is_array($val)) { |
||
243 | $attrib['url'] = $this->url($val[0], true); |
||
244 | $val = $val[1]; |
||
245 | } |
||
246 | break;
|
||
247 | case 'enclosure': |
||
248 | if (is_string($val['url']) && is_file(WWW_ROOT . $val['url']) && file_exists(WWW_ROOT . $val['url'])) { |
||
249 | if (!isset($val['length']) && strpos($val['url'], '://') === false) { |
||
250 | $val['length'] = sprintf("%u", filesize(WWW_ROOT . $val['url'])); |
||
251 | } |
||
252 | if (!isset($val['type']) && function_exists('mime_content_type')) { |
||
253 | $val['type'] = mime_content_type(WWW_ROOT . $val['url']); |
||
254 | } |
||
255 | } |
||
256 | $val['url'] = $this->url($val['url'], true); |
||
257 | $attrib = $val; |
||
258 | $val = null; |
||
259 | break;
|
||
260 | default:
|
||
261 | $attrib = $att; |
||
262 | } |
||
263 | if ($val !== null && $escape) { |
||
264 | $val = h($val); |
||
265 | } |
||
266 | $elements[$key] = $this->elem($key, $attrib, $val); |
||
267 | } |
||
268 | if (!empty($elements)) { |
||
269 | $content = implode('', $elements); |
||
270 | } |
||
271 | return $this->elem('item', (array)$att, $content, !($content === null)); |
||
272 | } |
||
273 | |||
274 | /**
|
||
275 | * Converts a time in any format to an RSS time
|
||
276 | *
|
||
277 | * @param int|string|DateTime $time UNIX timestamp or valid time string or DateTime object.
|
||
278 | * @return string An RSS-formatted timestamp
|
||
279 | * @see TimeHelper::toRSS
|
||
280 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::time
|
||
281 | */
|
||
282 | public function time($time) { |
||
283 | return $this->Time->toRSS($time); |
||
284 | } |
||
285 | |||
286 | /**
|
||
287 | * Generates an XML element
|
||
288 | *
|
||
289 | * @param string $name The name of the XML element
|
||
290 | * @param array $attrib The attributes of the XML element
|
||
291 | * @param string|array $content XML element content
|
||
292 | * @param bool $endTag Whether the end tag of the element should be printed
|
||
293 | * @return string XML
|
||
294 | * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/rss.html#RssHelper::elem
|
||
295 | */
|
||
296 | public function elem($name, $attrib = array(), $content = null, $endTag = true) { |
||
297 | $namespace = null; |
||
298 | if (isset($attrib['namespace'])) { |
||
299 | $namespace = $attrib['namespace']; |
||
300 | unset($attrib['namespace']); |
||
301 | } |
||
302 | $cdata = false; |
||
303 | if (is_array($content) && isset($content['cdata'])) { |
||
304 | $cdata = true; |
||
305 | unset($content['cdata']); |
||
306 | } |
||
307 | if (is_array($content) && array_key_exists('value', $content)) { |
||
308 | $content = $content['value']; |
||
309 | } |
||
310 | $children = array(); |
||
311 | if (is_array($content)) { |
||
312 | $children = $content; |
||
313 | $content = null; |
||
314 | } |
||
315 | |||
316 | $xml = '<' . $name; |
||
317 | if (!empty($namespace)) { |
||
318 | $xml .= ' xmlns'; |
||
319 | if (is_array($namespace)) { |
||
320 | $xml .= ':' . $namespace['prefix']; |
||
321 | $namespace = $namespace['url']; |
||
322 | } |
||
323 | $xml .= '="' . $namespace . '"'; |
||
324 | } |
||
325 | $bareName = $name; |
||
326 | if (strpos($name, ':') !== false) { |
||
327 | list($prefix, $bareName) = explode(':', $name, 2); |
||
328 | switch ($prefix) { |
||
329 | case 'atom': |
||
330 | $xml .= ' xmlns:atom="http://www.w3.org/2005/Atom"'; |
||
331 | break;
|
||
332 | } |
||
333 | } |
||
334 | if ($cdata && !empty($content)) { |
||
335 | $content = '<![CDATA[' . $content . ']]>'; |
||
336 | } |
||
337 | $xml .= '>' . $content . '</' . $name . '>'; |
||
338 | $elem = Xml::build($xml, array('return' => 'domdocument')); |
||
339 | $nodes = $elem->getElementsByTagName($bareName); |
||
340 | if ($attrib) { |
||
341 | foreach ($attrib as $key => $value) { |
||
342 | $nodes->item(0)->setAttribute($key, $value); |
||
343 | } |
||
344 | } |
||
345 | foreach ($children as $child) { |
||
346 | $child = $elem->createElement($name, $child); |
||
347 | $nodes->item(0)->appendChild($child); |
||
348 | } |
||
349 | |||
350 | $xml = $elem->saveXml(); |
||
351 | $xml = trim(substr($xml, strpos($xml, '?>') + 2)); |
||
352 | return $xml; |
||
353 | } |
||
354 | |||
355 | } |