From e2efcc108cf2fdd7ff31a665608ade3b29d13f72 Mon Sep 17 00:00:00 2001 From: nate Date: Tue, 22 Aug 2006 08:05:44 +0000 Subject: [PATCH] Initial import of RSS and XML helpers git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@3425 3807eeeb-6ff5-0310-8944-8be069107fe0 --- cake/libs/view/helpers/rss.php | 228 +++++++++++++++++++++++++++ cake/libs/view/helpers/xml.php | 274 +++++++++++++++++++++++++++++++++ 2 files changed, 502 insertions(+) create mode 100644 cake/libs/view/helpers/rss.php create mode 100644 cake/libs/view/helpers/xml.php diff --git a/cake/libs/view/helpers/rss.php b/cake/libs/view/helpers/rss.php new file mode 100644 index 000000000..45d7491b5 --- /dev/null +++ b/cake/libs/view/helpers/rss.php @@ -0,0 +1,228 @@ + + * Copyright (c) 2006, Cake Software Foundation, Inc. + * 1785 E. Sahara Avenue, Suite 490-204 + * Las Vegas, Nevada 89104 + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright (c) 2006, Cake Software Foundation, Inc. + * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project + * @package cake + * @subpackage cake.cake.libs.view.helpers + * @since CakePHP v 1.2 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/mit-license.php The MIT License + */ +/** + * XML Helper class for easy output of XML structures. + * + * XmlHelper encloses all methods needed while working with XML documents. + * + * @package cake + * @subpackage cake.cake.libs.view.helpers + */ +uses('view' . DS . 'helpers' . DS . 'xml'); + +class RssHelper extends XmlHelper { + + var $helpers = array('Html', 'Text', 'Time'); +/** + * Base URL + * + * @access public + * @var string + */ + var $base = null; +/** + * URL to current action. + * + * @access public + * @var string + */ + var $here = null; +/** + * Parameter array. + * + * @access public + * @var array + */ + var $params = array(); +/** + * Current action. + * + * @access public + * @var string + */ + var $action = null; +/** + * POSTed model data + * + * @access public + * @var array + */ + var $data = null; +/** + * Name of the current model + * + * @access public + * @var string + */ + var $model = null; +/** + * Name of the current field + * + * @access public + * @var string + */ + var $field = null; +/** + * Default spec version of generated RSS + * + * @access public + * @var string + */ + var $version = '2.0'; +/** + * Returns an RSS document wrapped in tags + * + * @param array $attrib tag attributes + * @return string An RSS document + */ + function document($attrib = array(), $content = null) { + if ($content === null) { + $content = $attrib; + $attrib = array(); + } + if (!isset($attrib['version']) || empty($attrib['version'])) { + $attrib['version'] = $this->version; + } + + $attrib = array_reverse(am($this->__prepareNamespaces(), $attrib)); + return $this->elem('rss', $attrib, $content); + } +/** + * Returns an RSS element + * + * @param array $attrib tag attributes + * @param mixed $elements Named array elements which are converted to tags + * @param mixed $content Content ('s belonging to this channel + * @return string An RSS + */ + function channel($attrib = array(), $elements = array(), $content = null) { + if (!isset($elements['title']) && !empty($this->view->pageTitle)) { + $elements['title'] = $this->view->pageTitle; + } + if (!isset($elements['link'])) { + $elements['link'] = '/'; + } + $elements['link'] = $this->Html->url($elements['link'], true); + + $elems = ''; + foreach ($elements as $elem => $data) { + $elems .= $this->elem($elem, array(), $data); + } + return $this->elem('channel', $attrib, $elems . $this->__composeContent($content), !($content === null)); + } +/** + * Transforms an array of data using an optional callback, and maps it to a set + * of tags + * + * @param array $items The list of items to be mapped + * @param mixed $callback A string function name, or array containing an object + * and a string method name + * @return string A set of RSS elements + */ + function items($items, $callback = null) { + if ($callback != null) { + $items = array_map($callback, $items); + } + + $out = ''; + $c = count($items); + for ($i = 0; $i < $c; $i++) { + $out .= $this->item(array(), $items[$i]); + } + return $out; + } +/** + * Converts an array into an element and its contents + * + * @param array $attrib The attributes of the element + * @param array $elements The list of elements contained in this + * @return string An RSS element + */ + function item($attrib = array(), $elements = array()) { + $content = null; + foreach ($elements as $key => $val) { + $attrib = array(); + switch ($key) { + case 'pubDate' : + $val = $this->time($val); + break; + case 'link': + case 'guid': + case 'comments': + if (is_array($val) && isset($val['url'])) { + $attrib = $val; + unset($attrib['url']); + $val = $val['url']; + } + $val = $this->Html->url($val, true); + break; + case 'source': + if (is_array($val) && isset($val['url'])) { + $attrib['url'] = $this->Html->url($val['url'], true); + $val = $val['title']; + } elseif (is_array($val)) { + $attrib['url'] = $this->Html->url($val[0], true); + $val = $val[1]; + } + break; + case 'enclosure': + if (is_string($val['url']) && is_file(WWW_ROOT . $val['url']) && file_exists(WWW_ROOT . $val['url'])) { + if (!isset($val['length']) && strpos($val['url'], '://') === false) { + $val['length'] = sprintf("%u", filesize(WWW_ROOT . $val['url'])); + } + if (!isset($val['type']) && function_exists('mime_content_type')) { + $val['type'] = mime_content_type(WWW_ROOT . $val['url']); + } + } + $val['url'] = $html->Html->url($val['url'], true); + $attrib = $val; + $val = null; + break; + } + if ($val != null) { + $val = h($val); + } + $elements[$key] = $this->elem($key, array(), $val); + } + if (!empty($elements)) { + $content = join('', $elements); + } + return $this->output($this->elem('item', $attrib, $content, !($content === null))); + } +/** + * Converts a time in any format to an RSS time + * + * @param mixed $time + * @return string An RSS-formatted timestamp + * @see TimeHelper::toRSS + */ + function time($time) { + return $this->Time->toRSS($time); + } +} + +?> \ No newline at end of file diff --git a/cake/libs/view/helpers/xml.php b/cake/libs/view/helpers/xml.php new file mode 100644 index 000000000..49f2d510f --- /dev/null +++ b/cake/libs/view/helpers/xml.php @@ -0,0 +1,274 @@ + + * Copyright (c) 2006, Cake Software Foundation, Inc. + * 1785 E. Sahara Avenue, Suite 490-204 + * Las Vegas, Nevada 89104 + * + * Licensed under The MIT License + * Redistributions of files must retain the above copyright notice. + * + * @filesource + * @copyright Copyright (c) 2006, Cake Software Foundation, Inc. + * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project + * @package cake + * @subpackage cake.cake.libs.view.helpers + * @since CakePHP v 1.2 + * @version $Revision$ + * @modifiedby $LastChangedBy$ + * @lastmodified $Date$ + * @license http://www.opensource.org/licenses/mit-license.php The MIT License + */ +/** + * XML Helper class for easy output of XML structures. + * + * XmlHelper encloses all methods needed while working with XML documents. + * + * @package cake + * @subpackage cake.cake.libs.view.helpers + */ +class XmlHelper extends Helper { + + var $helpers = array('Html'); +/** + * Base URL + * + * @access public + * @var string + */ + var $base = null; +/** + * URL to current action. + * + * @access public + * @var string + */ + var $here = null; +/** + * Parameter array. + * + * @access public + * @var array + */ + var $params = array(); +/** + * Current action. + * + * @access public + * @var string + */ + var $action = null; +/** + * POSTed model data + * + * @access public + * @var array + */ + var $data = null; +/** + * Name of the current model + * + * @access public + * @var string + */ + var $model = null; +/** + * Name of the current field + * + * @access public + * @var string + */ + var $field = null; +/** + * Map of common namespace URIs + * + * @access private + * @var array + */ + var $__defaultNamespaceMap = array( + 'dc' => 'http://purl.org/dc/elements/1.1/', // Dublin Core + 'dct' => 'http://purl.org/dc/terms/', // Dublin Core Terms + 'g' => 'http://base.google.com/ns/1.0', // Google Base + 'rc' => 'http://purl.org/rss/1.0/modules/content/', // RSS 1.0 Content Module + 'wf' => 'http://wellformedweb.org/CommentAPI/', // Well-Formed Web Comment API + 'fb' => 'http://rssnamespace.org/feedburner/ext/1.0', // FeedBurner extensions + 'lj' => 'http://www.livejournal.org/rss/lj/1.0/', // Live Journal + 'itunes' => 'http://www.itunes.com/dtds/podcast-1.0.dtd', // iTunes + 'xhtml' => 'http://www.w3.org/1999/xhtml' // XHTML + ); +/** + * Namespaces to be utilized by default when generating documents + * + * @access private + * @var array + */ + var $__namespaces = array(); +/** + * Default document encoding + * + * @access public + * @var string + */ + var $encoding = 'UTF-8'; +/** + * Returns an XML document header + * + * @param array $attrib Header tag attributes + * @return string XML header + */ + function header($attrib = array()) { + $attrib = am(array('version' => '1.0', 'encoding' => $this->encoding), $attrib); + return $this->output('<' . '?xml' . $this->__composeAttributes($attrib) . ' ?' . '>'); + } +/** + * Adds a namespace to any documents generated + * + * @param string $name The namespace name + * @param string $url The namespace URI; can be empty if in the default namespace map + * @return boolean False if no URL is specified, and the namespace does not exist + * default namespace map, otherwise true + */ + function addNs($name, $url = null) { + if ($url == null && in_array($name, array_keys($this->__defaultNamespaceMap))) { + $url = $this->__defaultNamespaceMap[$name]; + } elseif ($url == null) { + return false; + } + + if (!strpos($url, '://') && in_array($name, array_keys($this->__defaultNamespaceMap))) { + $_url = $this->__defaultNamespaceMap[$name]; + $name = $url; + $url = $_url; + } + $this->__namespaces[$name] = $url; + return true; + } +/** + * Removes a namespace added in addNs() + * + * @param string $name The namespace name or URI + * @return void + */ + function removeNs($name) { + if (in_array($name, array_keys($this->__namespaces))) { + unset($this->__namespaces[$name]); + } elseif (in_array($name, $this->__namespaces)) { + $keys = array_keys($this->__namespaces); + $count = count($keys); + for ($i = 0; $i < $count; $i++) { + if ($this->__namespaces[$keys[$i]] == $name) { + unset($this->__namespaces[$keys[$i]]); + return; + } + } + } + } +/** + * Prepares the current set of namespaces for output in elem() / __composeAttributes() + * + * @return array The contents of $__namespaces, with all keys prefixed with 'xmlns:' + */ + function __prepareNamespaces() { + if (!empty($this->__namespaces)) { + $keys = array_keys($this->__namespaces); + $count = count($keys); + for ($i = 0; $i < $count; $i++) { + $keys[$i] = 'xmlns:' . $keys[$i]; + } + return array_combine($keys, array_values($this->__namespaces)); + } + return array(); + } +/** + * Generates an XML element + * + * @param string $name The name of the XML element + * @param array $attrib The attributes of the XML element + * @param mixed $content XML element content + * @param boolean $endTag Whether the end tag of the element should be printed + * @return string XML + */ + function elem($name, $attrib = array(), $content = null, $endTag = true) { + + $ns = null; + if (isset($attrib['namespace'])) { + $ns = $attrib['namespace'] . ':'; + unset($attrib['namespace']); + } + $out = "<{$ns}{$name}" . $this->__composeAttributes($attrib); + + if ((empty($content) || $content == null) && $endTag) { + $out .= ' />'; + } else { + $out .= '>' . $this->__composeContent($content); + if ($endTag) { + $out .= ""; + } + } + + return $this->output($out); + } +/** + * Generates XML element attributes + * + * @param mixed $attributes + * @return string Formatted XML attributes for inclusion in an XML element + */ + function __composeAttributes($attributes = array()) { + $out = ''; + if (is_array($attributes) && !empty($attributes)) { + $attr = array(); + $keys = array_keys($attributes); + $count = count($keys); + for ($i = 0; $i < $count; $i++) { + $attr[] = $keys[$i] . '="' . h($attributes[$keys[$i]]) . '"'; + } + $out .= ' ' . join(' ', $attr); + } elseif (is_string($attributes) && !empty($attributes)) { + $out .= ' ' . $attributes; + } + return $out; + } +/** + * Generates XML content based on the type of variable or object passed + * + * @param mixed $content The content to be converted to XML + * @return string XML + */ + function __composeContent($content) { + $out = ''; + if (is_string($content)) { + $out .= $content; + } elseif (is_array($content)) { + $keys = array_keys($content); + $count = count($keys); + for ($i = 0; $i < $count; $i++) { + if (is_numeric($keys[$i])) { + $out .= $this->__composeContent($content[$keys[$i]]); + } elseif (is_array($content[$keys[$i]])) { + $attr = $child = array(); + if (countdim($content[$keys[$i]]) >= 2) { + + } else { + + } + //$out .= $this->elem($keys[$i] + } + } + } elseif (is_object($content) && (is_a($content, 'XMLNode') || is_a($content, 'xmlnode'))) { + $out .= $content->toString(); + } elseif (is_object($content) && method_exists($content, 'toString')) { + $out .= $content->toString(); + } elseif (is_object($content) && method_exists($content, '__toString')) { + $out .= $content->__toString(); + } + return $out; + } +} + +?> \ No newline at end of file