pictcode / lib / Cake / View / Helper / RssHelper.php @ 48ae03cf
履歴 | 表示 | アノテート | ダウンロード (9.271 KB)
| 1 |
<?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 |
} |