début de script pour fusionner les RSS des strips et les annonces sur le forum

This commit is contained in:
nojhan 2008-04-26 21:33:55 +00:00
commit d45e9d721f
66 changed files with 12583 additions and 0 deletions

403
Zend/Feed.php Normal file
View file

@ -0,0 +1,403 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Feed.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* Feed utility class
*
* Base Zend_Feed class, containing constants and the Zend_Http_Client instance
* accessor.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed
{
/**
* HTTP client object to use for retrieving feeds
*
* @var Zend_Http_Client
*/
protected static $_httpClient = null;
/**
* Override HTTP PUT and DELETE request methods?
*
* @var boolean
*/
protected static $_httpMethodOverride = false;
/**
* @var array
*/
protected static $_namespaces = array(
'opensearch' => 'http://a9.com/-/spec/opensearchrss/1.0/',
'atom' => 'http://www.w3.org/2005/Atom',
'rss' => 'http://blogs.law.harvard.edu/tech/rss',
);
/**
* Set the HTTP client instance
*
* Sets the HTTP client object to use for retrieving the feeds.
*
* @param Zend_Http_Client $httpClient
* @return void
*/
public static function setHttpClient(Zend_Http_Client $httpClient)
{
self::$_httpClient = $httpClient;
}
/**
* Gets the HTTP client object. If none is set, a new Zend_Http_Client will be used.
*
* @return Zend_Http_Client_Abstract
*/
public static function getHttpClient()
{
if (!self::$_httpClient instanceof Zend_Http_Client) {
/**
* @see Zend_Http_Client
*/
require_once 'Zend/Http/Client.php';
self::$_httpClient = new Zend_Http_Client();
}
return self::$_httpClient;
}
/**
* Toggle using POST instead of PUT and DELETE HTTP methods
*
* Some feed implementations do not accept PUT and DELETE HTTP
* methods, or they can't be used because of proxies or other
* measures. This allows turning on using POST where PUT and
* DELETE would normally be used; in addition, an
* X-Method-Override header will be sent with a value of PUT or
* DELETE as appropriate.
*
* @param boolean $override Whether to override PUT and DELETE.
* @return void
*/
public static function setHttpMethodOverride($override = true)
{
self::$_httpMethodOverride = $override;
}
/**
* Get the HTTP override state
*
* @return boolean
*/
public static function getHttpMethodOverride()
{
return self::$_httpMethodOverride;
}
/**
* Get the full version of a namespace prefix
*
* Looks up a prefix (atom:, etc.) in the list of registered
* namespaces and returns the full namespace URI if
* available. Returns the prefix, unmodified, if it's not
* registered.
*
* @return string
*/
public static function lookupNamespace($prefix)
{
return isset(self::$_namespaces[$prefix]) ?
self::$_namespaces[$prefix] :
$prefix;
}
/**
* Add a namespace and prefix to the registered list
*
* Takes a prefix and a full namespace URI and adds them to the
* list of registered namespaces for use by
* Zend_Feed::lookupNamespace().
*
* @param string $prefix The namespace prefix
* @param string $namespaceURI The full namespace URI
* @return void
*/
public static function registerNamespace($prefix, $namespaceURI)
{
self::$_namespaces[$prefix] = $namespaceURI;
}
/**
* Imports a feed located at $uri.
*
* @param string $uri
* @throws Zend_Feed_Exception
* @return Zend_Feed_Abstract
*/
public static function import($uri)
{
$client = self::getHttpClient();
$client->setUri($uri);
$response = $client->request('GET');
if ($response->getStatus() !== 200) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
}
$feed = $response->getBody();
return self::importString($feed);
}
/**
* Imports a feed represented by $string.
*
* @param string $string
* @throws Zend_Feed_Exception
* @return Zend_Feed_Abstract
*/
public static function importString($string)
{
// Load the feed as an XML DOMDocument object
@ini_set('track_errors', 1);
$doc = @DOMDocument::loadXML($string);
@ini_restore('track_errors');
if (!$doc) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
} else {
$php_errormsg = '(error message not available)';
}
}
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
}
// Try to find the base feed element or a single <entry> of an Atom feed
if ($doc->getElementsByTagName('feed')->item(0) ||
$doc->getElementsByTagName('entry')->item(0)) {
/**
* @see Zend_Feed_Atom
*/
require_once 'Zend/Feed/Atom.php';
// return a newly created Zend_Feed_Atom object
return new Zend_Feed_Atom(null, $string);
}
// Try to find the base feed element of an RSS feed
if ($doc->getElementsByTagName('channel')->item(0)) {
/**
* @see Zend_Feed_Rss
*/
require_once 'Zend/Feed/Rss.php';
// return a newly created Zend_Feed_Rss object
return new Zend_Feed_Rss(null, $string);
}
// $string does not appear to be a valid feed of the supported types
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Invalid or unsupported feed format');
}
/**
* Imports a feed from a file located at $filename.
*
* @param string $filename
* @throws Zend_Feed_Exception
* @return Zend_Feed_Abstract
*/
public static function importFile($filename)
{
@ini_set('track_errors', 1);
$feed = @file_get_contents($filename);
@ini_restore('track_errors');
if ($feed === false) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("File could not be loaded: $php_errormsg");
}
return self::importString($feed);
}
/**
* Attempts to find feeds at $uri referenced by <link ... /> tags. Returns an
* array of the feeds referenced at $uri.
*
* @todo Allow findFeeds() to follow one, but only one, code 302.
*
* @param string $uri
* @throws Zend_Feed_Exception
* @return array
*/
public static function findFeeds($uri)
{
// Get the HTTP response from $uri and save the contents
$client = self::getHttpClient();
$client->setUri($uri);
$response = $client->request();
if ($response->getStatus() !== 200) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("Failed to access $uri, got response code " . $response->getStatus());
}
$contents = $response->getBody();
// Parse the contents for appropriate <link ... /> tags
@ini_set('track_errors', 1);
$pattern = '~(<link[^>]+)/?>~i';
$result = @preg_match_all($pattern, $contents, $matches);
@ini_restore('track_errors');
if ($result === false) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("Internal error: $php_errormsg");
}
// Try to fetch a feed for each link tag that appears to refer to a feed
$feeds = array();
if (isset($matches[1]) && count($matches[1]) > 0) {
foreach ($matches[1] as $link) {
// force string to be an utf-8 one
if (!mb_check_encoding($link, 'UTF-8')) {
$link = mb_convert_encoding($link, 'UTF-8');
}
$xml = @simplexml_load_string(rtrim($link, ' /') . ' />');
if ($xml === false) {
continue;
}
$attributes = $xml->attributes();
if (!isset($attributes['rel']) || !@preg_match('~^(?:alternate|service\.feed)~i', $attributes['rel'])) {
continue;
}
if (!isset($attributes['type']) ||
!@preg_match('~^application/(?:atom|rss|rdf)\+xml~', $attributes['type'])) {
continue;
}
if (!isset($attributes['href'])) {
continue;
}
try {
// checks if we need to canonize the given uri
try {
$uri = Zend_Uri::factory((string) $attributes['href']);
} catch (Zend_Uri_Exception $e) {
// canonize the uri
$path = (string) $attributes['href'];
$query = $fragment = '';
if (substr($path, 0, 1) != '/') {
// add the current root path to this one
$path = rtrim($client->getUri()->getPath(), '/') . '/' . $path;
}
if (strpos($path, '?') !== false) {
list($path, $query) = explode('?', $path, 2);
}
if (strpos($query, '#') !== false) {
list($query, $fragment) = explode('#', $query, 2);
}
$uri = Zend_Uri::factory($client->getUri(true));
$uri->setPath($path);
$uri->setQuery($query);
$uri->setFragment($fragment);
}
$feed = self::import($uri);
} catch (Exception $e) {
continue;
}
$feeds[] = $feed;
}
}
// Return the fetched feeds
return $feeds;
}
/**
* Construct a new Zend_Feed_Abstract object from a custom array
*
* @param array $data
* @param string $format (rss|atom) the requested output format
* @return Zend_Feed_Abstract
*/
public static function importArray(array $data, $format = 'atom')
{
$obj = 'Zend_Feed_' . ucfirst(strtolower($format));
/**
* @see Zend_Loader
*/
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($obj);
Zend_Loader::loadClass('Zend_Feed_Builder');
return new $obj(null, null, new Zend_Feed_Builder($data));
}
/**
* Construct a new Zend_Feed_Abstract object from a Zend_Feed_Builder_Interface data source
*
* @param Zend_Feed_Builder_Interface $builder this object will be used to extract the data of the feed
* @param string $format (rss|atom) the requested output format
* @return Zend_Feed_Abstract
*/
public static function importBuilder(Zend_Feed_Builder_Interface $builder, $format = 'atom')
{
$obj = 'Zend_Feed_' . ucfirst(strtolower($format));
/**
* @see Zend_Loader
*/
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($obj);
return new $obj(null, null, $builder);
}
}

258
Zend/Feed/Abstract.php Normal file
View file

@ -0,0 +1,258 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Element
*/
require_once 'Zend/Feed/Element.php';
/**
* The Zend_Feed_Abstract class is an abstract class representing feeds.
*
* Zend_Feed_Abstract implements two core PHP 5 interfaces: ArrayAccess and
* Iterator. In both cases the collection being treated as an array is
* considered to be the entry collection, such that iterating over the
* feed takes you through each of the feed.s entries.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator
{
/**
* Current index on the collection of feed entries for the
* Iterator implementation.
*
* @var integer
*/
protected $_entryIndex = 0;
/**
* Cache of feed entries.
*
* @var array
*/
protected $_entries;
/**
* Feed constructor
*
* The Zend_Feed_Abstract constructor takes the URI of a feed or a
* feed represented as a string and loads it as XML.
*
* @param string $uri The full URI of the feed to load, or NULL if not retrieved via HTTP or as an array.
* @param string $string The feed as a string, or NULL if retrieved via HTTP or as an array.
* @param Zend_Feed_Builder_Interface $builder The feed as a builder instance or NULL if retrieved as a string or via HTTP.
* @return void
* @throws Zend_Feed_Exception If loading the feed failed.
*/
public function __construct($uri = null, $string = null, Zend_Feed_Builder_Interface $builder = null)
{
if ($uri !== null) {
// Retrieve the feed via HTTP
$client = Zend_Feed::getHttpClient();
$client->setUri($uri);
$response = $client->request('GET');
if ($response->getStatus() !== 200) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
}
$this->_element = $response->getBody();
$this->__wakeup();
} elseif ($string !== null) {
// Retrieve the feed from $string
$this->_element = $string;
$this->__wakeup();
} else {
// Generate the feed from the array
$header = $builder->getHeader();
$this->_element = new DOMDocument('1.0', $header['charset']);
$root = $this->_mapFeedHeaders($header);
$this->_mapFeedEntries($root, $builder->getEntries());
$this->_element = $root;
$this->_buildEntryCache();
}
}
/**
* Load the feed as an XML DOMDocument object
*
* @return void
* @throws Zend_Feed_Exception
*/
public function __wakeup()
{
@ini_set('track_errors', 1);
$doc = @DOMDocument::loadXML($this->_element);
@ini_restore('track_errors');
if (!$doc) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
} else {
$php_errormsg = '(error message not available)';
}
}
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
}
$this->_element = $doc;
}
/**
* Prepare for serialiation
*
* @return array
*/
public function __sleep()
{
$this->_element = $this->saveXML();
return array('_element');
}
/**
* Cache the individual feed elements so they don't need to be
* searched for on every operation.
*
* @return void
*/
protected function _buildEntryCache()
{
$this->_entries = array();
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $this->_entryElementName) {
$this->_entries[] = $child;
}
}
}
/**
* Get the number of entries in this feed object.
*
* @return integer Entry count.
*/
public function count()
{
return count($this->_entries);
}
/**
* Required by the Iterator interface.
*
* @return void
*/
public function rewind()
{
$this->_entryIndex = 0;
}
/**
* Required by the Iterator interface.
*
* @return mixed The current row, or null if no rows.
*/
public function current()
{
return new $this->_entryClassName(
null,
$this->_entries[$this->_entryIndex]);
}
/**
* Required by the Iterator interface.
*
* @return mixed The current row number (starts at 0), or NULL if no rows
*/
public function key()
{
return $this->_entryIndex;
}
/**
* Required by the Iterator interface.
*
* @return mixed The next row, or null if no more rows.
*/
public function next()
{
++$this->_entryIndex;
}
/**
* Required by the Iterator interface.
*
* @return boolean Whether the iteration is valid
*/
public function valid()
{
return 0 <= $this->_entryIndex && $this->_entryIndex < $this->count();
}
/**
* Generate the header of the feed when working in write mode
*
* @param array $array the data to use
* @return DOMElement root node
*/
abstract protected function _mapFeedHeaders($array);
/**
* Generate the entries of the feed when working in write mode
*
* @param DOMElement $root the root node to use
* @param array $array the data to use
* @return DOMElement root node
*/
abstract protected function _mapFeedEntries(DOMElement $root, $array);
/**
* Send feed to a http client with the correct header
*
* @throws Zend_Feed_Exception if headers have already been sent
* @return void
*/
abstract public function send();
}

390
Zend/Feed/Atom.php Normal file
View file

@ -0,0 +1,390 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Atom.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Abstract
*/
require_once 'Zend/Feed/Abstract.php';
/**
* @see Zend_Feed_Entry_Atom
*/
require_once 'Zend/Feed/Entry/Atom.php';
/**
* Atom feed class
*
* The Zend_Feed_Atom class is a concrete subclass of the general
* Zend_Feed_Abstract class, tailored for representing an Atom
* feed. It shares all of the same methods with its abstract
* parent. The distinction is made in the format of data that
* Zend_Feed_Atom expects, and as a further pointer for users as to
* what kind of feed object they have been passed.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Atom extends Zend_Feed_Abstract
{
/**
* The classname for individual feed elements.
*
* @var string
*/
protected $_entryClassName = 'Zend_Feed_Entry_Atom';
/**
* The element name for individual feed elements (Atom <entry>
* elements).
*
* @var string
*/
protected $_entryElementName = 'entry';
/**
* The default namespace for Atom feeds.
*
* @var string
*/
protected $_defaultNamespace = 'atom';
/**
* Override Zend_Feed_Abstract to set up the $_element and $_entries aliases.
*
* @return void
* @throws Zend_Feed_Exception
*/
public function __wakeup()
{
parent::__wakeup();
// Find the base feed element and create an alias to it.
$element = $this->_element->getElementsByTagName('feed')->item(0);
if (!$element) {
// Try to find a single <entry> instead.
$element = $this->_element->getElementsByTagName($this->_entryElementName)->item(0);
if (!$element) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <feed> or <' . $this->_entryElementName
. '> element found, cannot parse feed.');
}
$doc = new DOMDocument($this->_element->version,
$this->_element->actualEncoding);
$feed = $doc->appendChild($doc->createElement('feed'));
$feed->appendChild($doc->importNode($element, true));
$element = $feed;
}
$this->_element = $element;
// Find the entries and save a pointer to them for speed and
// simplicity.
$this->_buildEntryCache();
}
/**
* Easy access to <link> tags keyed by "rel" attributes.
*
* If $elt->link() is called with no arguments, we will attempt to
* return the value of the <link> tag(s) like all other
* method-syntax attribute access. If an argument is passed to
* link(), however, then we will return the "href" value of the
* first <link> tag that has a "rel" attribute matching $rel:
*
* $elt->link(): returns the value of the link tag.
* $elt->link('self'): returns the href from the first <link rel="self"> in the entry.
*
* @param string $rel The "rel" attribute to look for.
* @return mixed
*/
public function link($rel = null)
{
if ($rel === null) {
return parent::__call('link', null);
}
// index link tags by their "rel" attribute.
$links = parent::__get('link');
if (!is_array($links)) {
if ($links instanceof Zend_Feed_Element) {
$links = array($links);
} else {
return $links;
}
}
foreach ($links as $link) {
if (empty($link['rel'])) {
continue;
}
if ($rel == $link['rel']) {
return $link['href'];
}
}
return null;
}
/**
* Make accessing some individual elements of the feed easier.
*
* Special accessors 'entry' and 'entries' are provided so that if
* you wish to iterate over an Atom feed's entries, you can do so
* using foreach ($feed->entries as $entry) or foreach
* ($feed->entry as $entry).
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
switch ($var) {
case 'entry':
// fall through to the next case
case 'entries':
return $this;
default:
return parent::__get($var);
}
}
/**
* Generate the header of the feed when working in write mode
*
* @param array $array the data to use
* @return DOMElement root node
*/
protected function _mapFeedHeaders($array)
{
$feed = $this->_element->createElement('feed');
$feed->setAttribute('xmlns', 'http://www.w3.org/2005/Atom');
$id = $this->_element->createElement('id', $array->link);
$feed->appendChild($id);
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($array->title));
$feed->appendChild($title);
if (isset($array->author)) {
$author = $this->_element->createElement('author');
$name = $this->_element->createElement('name', $array->author);
$author->appendChild($name);
if (isset($array->email)) {
$email = $this->_element->createElement('email', $array->email);
$author->appendChild($email);
}
$feed->appendChild($author);
}
$updated = isset($array->lastUpdate) ? $array->lastUpdate : time();
$updated = $this->_element->createElement('updated', date(DATE_ATOM, $updated));
$feed->appendChild($updated);
if (isset($array->published)) {
$published = $this->_element->createElement('published', date(DATE_ATOM, $array->published));
$feed->appendChild($published);
}
$link = $this->_element->createElement('link');
$link->setAttribute('rel', 'self');
$link->setAttribute('href', $array->link);
if (isset($array->language)) {
$link->setAttribute('hreflang', $array->language);
}
$feed->appendChild($link);
if (isset($array->description)) {
$subtitle = $this->_element->createElement('subtitle');
$subtitle->appendChild($this->_element->createCDATASection($array->description));
$feed->appendChild($subtitle);
}
if (isset($array->copyright)) {
$copyright = $this->_element->createElement('rights', $array->copyright);
$feed->appendChild($copyright);
}
if (isset($array->image)) {
$image = $this->_element->createElement('logo', $array->image);
$feed->appendChild($image);
}
$generator = !empty($array->generator) ? $array->generator : 'Zend_Feed';
$generator = $this->_element->createElement('generator', $generator);
$feed->appendChild($generator);
return $feed;
}
/**
* Generate the entries of the feed when working in write mode
*
* The following nodes are constructed for each feed entry
* <entry>
* <id>url to feed entry</id>
* <title>entry title</title>
* <updated>last update</updated>
* <link rel="alternate" href="url to feed entry" />
* <summary>short text</summary>
* <content>long version, can contain html</content>
* </entry>
*
* @param array $array the data to use
* @param DOMElement $root the root node to use
* @return void
*/
protected function _mapFeedEntries(DOMElement $root, $array)
{
foreach ($array as $dataentry) {
$entry = $this->_element->createElement('entry');
$id = $this->_element->createElement('id', isset($dataentry->guid) ? $dataentry->guid : $dataentry->link);
$entry->appendChild($id);
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($dataentry->title));
$entry->appendChild($title);
$updated = isset($dataentry->lastUpdate) ? $dataentry->lastUpdate : time();
$updated = $this->_element->createElement('updated', date(DATE_ATOM, $updated));
$entry->appendChild($updated);
$link = $this->_element->createElement('link');
$link->setAttribute('rel', 'alternate');
$link->setAttribute('href', $dataentry->link);
$entry->appendChild($link);
$summary = $this->_element->createElement('summary');
$summary->appendChild($this->_element->createCDATASection($dataentry->description));
$entry->appendChild($summary);
if (isset($dataentry->content)) {
$content = $this->_element->createElement('content');
$content->setAttribute('type', 'html');
$content->appendChild($this->_element->createCDATASection($dataentry->content));
$entry->appendChild($content);
}
if (isset($dataentry->category)) {
foreach ($dataentry->category as $category) {
$node = $this->_element->createElement('category');
$node->setAttribute('term', $category['term']);
if (isset($category['scheme'])) {
$node->setAttribute('scheme', $category['scheme']);
}
$entry->appendChild($node);
}
}
if (isset($dataentry->source)) {
$source = $this->_element->createElement('source');
$title = $this->_element->createElement('title', $dataentry->source['title']);
$source->appendChild($title);
$link = $this->_element->createElement('link', $dataentry->source['title']);
$link->setAttribute('rel', 'alternate');
$link->setAttribute('href', $dataentry->source['url']);
$source->appendChild($link);
}
if (isset($dataentry->enclosure)) {
foreach ($dataentry->enclosure as $enclosure) {
$node = $this->_element->createElement('link');
$node->setAttribute('rel', 'enclosure');
$node->setAttribute('href', $enclosure['url']);
if (isset($enclosure['type'])) {
$node->setAttribute('type', $enclosure['type']);
}
if (isset($enclosure['length'])) {
$node->setAttribute('length', $enclosure['length']);
}
$entry->appendChild($node);
}
}
if (isset($dataentry->comments)) {
$comments = $this->_element->createElementNS('http://wellformedweb.org/CommentAPI/',
'wfw:comment',
$dataentry->comments);
$entry->appendChild($comments);
}
if (isset($dataentry->commentRss)) {
$comments = $this->_element->createElementNS('http://wellformedweb.org/CommentAPI/',
'wfw:commentRss',
$dataentry->commentRss);
$entry->appendChild($comments);
}
$root->appendChild($entry);
}
}
/**
* Override Zend_Feed_Element to allow formated feeds
*
* @return string
*/
public function saveXml()
{
// Return a complete document including XML prologue.
$doc = new DOMDocument($this->_element->ownerDocument->version,
$this->_element->ownerDocument->actualEncoding);
$doc->appendChild($doc->importNode($this->_element, true));
$doc->formatOutput = true;
return $doc->saveXML();
}
/**
* Send feed to a http client with the correct header
*
* @return void
* @throws Zend_Feed_Exception if headers have already been sent
*/
public function send()
{
if (headers_sent()) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot send ATOM because headers have already been sent.');
}
header('Content-type: application/atom+xml; charset: ' . $this->_element->ownerDocument->actualEncoding);
echo $this->saveXML();
}
}

395
Zend/Feed/Builder.php Normal file
View file

@ -0,0 +1,395 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Builder.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Builder_Interface
*/
require_once 'Zend/Feed/Builder/Interface.php';
/**
* @see Zend_Feed_Builder_Header
*/
require_once 'Zend/Feed/Builder/Header.php';
/**
* @see Zend_Feed_Builder_Entry
*/
require_once 'Zend/Feed/Builder/Entry.php';
/**
* A simple implementation of Zend_Feed_Builder_Interface.
*
* Users are encouraged to make their own classes to implement Zend_Feed_Builder_Interface
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder implements Zend_Feed_Builder_Interface
{
/**
* The data of the feed
*
* @var $_data array
*/
private $_data;
/**
* Header of the feed
*
* @var $_header Zend_Feed_Builder_Header
*/
private $_header;
/**
* List of the entries of the feed
*
* @var $_entries array
*/
private $_entries = array();
/**
* Constructor. The $data array must conform to the following format:
* <code>
* array(
* 'title' => 'title of the feed', //required
* 'link' => 'canonical url to the feed', //required
* 'lastUpdate' => 'timestamp of the update date', // optional
* 'published' => 'timestamp of the publication date', //optional
* 'charset' => 'charset', // required
* 'description' => 'short description of the feed', //optional
* 'author' => 'author/publisher of the feed', //optional
* 'email' => 'email of the author', //optional
* 'webmaster' => 'email address for person responsible for technical issues' // optional, ignored if atom is used
* 'copyright' => 'copyright notice', //optional
* 'image' => 'url to image', //optional
* 'generator' => 'generator', // optional
* 'language' => 'language the feed is written in', // optional
* 'ttl' => 'how long in minutes a feed can be cached before refreshing', // optional, ignored if atom is used
* 'rating' => 'The PICS rating for the channel.', // optional, ignored if atom is used
* 'cloud' => array(
* 'domain' => 'domain of the cloud, e.g. rpc.sys.com' // required
* 'port' => 'port to connect to' // optional, default to 80
* 'path' => 'path of the cloud, e.g. /RPC2 //required
* 'registerProcedure' => 'procedure to call, e.g. myCloud.rssPleaseNotify' // required
* 'protocol' => 'protocol to use, e.g. soap or xml-rpc' // required
* ), a cloud to be notified of updates // optional, ignored if atom is used
* 'textInput' => array(
* 'title' => 'the label of the Submit button in the text input area' // required,
* 'description' => 'explains the text input area' // required
* 'name' => 'the name of the text object in the text input area' // required
* 'link' => 'the URL of the CGI script that processes text input requests' // required
* ) // a text input box that can be displayed with the feed // optional, ignored if atom is used
* 'skipHours' => array(
* 'hour in 24 format', // e.g 13 (1pm)
* // up to 24 rows whose value is a number between 0 and 23
* ) // Hint telling aggregators which hours they can skip // optional, ignored if atom is used
* 'skipDays ' => array(
* 'a day to skip', // e.g Monday
* // up to 7 rows whose value is a Monday, Tuesday, Wednesday, Thursday, Friday, Saturday or Sunday
* ) // Hint telling aggregators which days they can skip // optional, ignored if atom is used
* 'itunes' => array(
* 'author' => 'Artist column' // optional, default to the main author value
* 'owner' => array(
* 'name' => 'name of the owner' // optional, default to main author value
* 'email' => 'email of the owner' // optional, default to main email value
* ) // Owner of the podcast // optional
* 'image' => 'album/podcast art' // optional, default to the main image value
* 'subtitle' => 'short description' // optional, default to the main description value
* 'summary' => 'longer description' // optional, default to the main description value
* 'block' => 'Prevent an episode from appearing (yes|no)' // optional
* 'category' => array(
* array('main' => 'main category', // required
* 'sub' => 'sub category' // optional
* ),
* // up to 3 rows
* ) // 'Category column and in iTunes Music Store Browse' // required
* 'explicit' => 'parental advisory graphic (yes|no|clean)' // optional
* 'keywords' => 'a comma separated list of 12 keywords maximum' // optional
* 'new-feed-url' => 'used to inform iTunes of new feed URL location' // optional
* ) // Itunes extension data // optional, ignored if atom is used
* 'entries' => array(
* array(
* 'title' => 'title of the feed entry', //required
* 'link' => 'url to a feed entry', //required
* 'description' => 'short version of a feed entry', // only text, no html, required
* 'guid' => 'id of the article, if not given link value will used', //optional
* 'content' => 'long version', // can contain html, optional
* 'lastUpdate' => 'timestamp of the publication date', // optional
* 'comments' => 'comments page of the feed entry', // optional
* 'commentRss' => 'the feed url of the associated comments', // optional
* 'source' => array(
* 'title' => 'title of the original source' // required,
* 'url' => 'url of the original source' // required
* ) // original source of the feed entry // optional
* 'category' => array(
* array(
* 'term' => 'first category label' // required,
* 'scheme' => 'url that identifies a categorization scheme' // optional
* ),
* array(
* //data for the second category and so on
* )
* ) // list of the attached categories // optional
* 'enclosure' => array(
* array(
* 'url' => 'url of the linked enclosure' // required
* 'type' => 'mime type of the enclosure' // optional
* 'length' => 'length of the linked content in octets' // optional
* ),
* array(
* //data for the second enclosure and so on
* )
* ) // list of the enclosures of the feed entry // optional
* ),
* array(
* //data for the second entry and so on
* )
* )
* );
* </code>
*
* @param array $data
* @return void
*/
public function __construct(array $data)
{
$this->_data = $data;
$this->_createHeader($data);
if (isset($data['entries'])) {
$this->_createEntries($data['entries']);
}
}
/**
* Returns an instance of Zend_Feed_Builder_Header
* describing the header of the feed
*
* @return Zend_Feed_Builder_Header
*/
public function getHeader()
{
return $this->_header;
}
/**
* Returns an array of Zend_Feed_Builder_Entry instances
* describing the entries of the feed
*
* @return array of Zend_Feed_Builder_Entry
*/
public function getEntries()
{
return $this->_entries;
}
/**
* Create the Zend_Feed_Builder_Header instance
*
* @param array $data
* @throws Zend_Feed_Builder_Exception
* @return void
*/
private function _createHeader(array $data)
{
$mandatories = array('title', 'link', 'charset');
foreach ($mandatories as $mandatory) {
if (!isset($data[$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
}
}
$this->_header = new Zend_Feed_Builder_Header($data['title'], $data['link'], $data['charset']);
if (isset($data['lastUpdate'])) {
$this->_header->setLastUpdate($data['lastUpdate']);
}
if (isset($data['published'])) {
$this->_header->setPublishedDate($data['published']);
}
if (isset($data['description'])) {
$this->_header->setDescription($data['description']);
}
if (isset($data['author'])) {
$this->_header->setAuthor($data['author']);
}
if (isset($data['email'])) {
$this->_header->setEmail($data['email']);
}
if (isset($data['webmaster'])) {
$this->_header->setWebmaster($data['webmaster']);
}
if (isset($data['copyright'])) {
$this->_header->setCopyright($data['copyright']);
}
if (isset($data['image'])) {
$this->_header->setImage($data['image']);
}
if (isset($data['generator'])) {
$this->_header->setGenerator($data['generator']);
}
if (isset($data['language'])) {
$this->_header->setLanguage($data['language']);
}
if (isset($data['ttl'])) {
$this->_header->setTtl($data['ttl']);
}
if (isset($data['rating'])) {
$this->_header->setRating($data['rating']);
}
if (isset($data['cloud'])) {
$mandatories = array('domain', 'path', 'registerProcedure', 'protocol');
foreach ($mandatories as $mandatory) {
if (!isset($data['cloud'][$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your cloud");
}
}
$uri_str = 'http://' . $data['cloud']['domain'] . $data['cloud']['path'];
$this->_header->setCloud($uri_str, $data['cloud']['registerProcedure'], $data['cloud']['protocol']);
}
if (isset($data['textInput'])) {
$mandatories = array('title', 'description', 'name', 'link');
foreach ($mandatories as $mandatory) {
if (!isset($data['textInput'][$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define $mandatory property of your textInput");
}
}
$this->_header->setTextInput($data['textInput']['title'],
$data['textInput']['description'],
$data['textInput']['name'],
$data['textInput']['link']);
}
if (isset($data['skipHours'])) {
$this->_header->setSkipHours($data['skipHours']);
}
if (isset($data['skipDays'])) {
$this->_header->setSkipDays($data['skipDays']);
}
if (isset($data['itunes'])) {
$itunes = new Zend_Feed_Builder_Header_Itunes($data['itunes']['category']);
if (isset($data['itunes']['author'])) {
$itunes->setAuthor($data['itunes']['author']);
}
if (isset($data['itunes']['owner'])) {
$name = isset($data['itunes']['owner']['name']) ? $data['itunes']['owner']['name'] : '';
$email = isset($data['itunes']['owner']['email']) ? $data['itunes']['owner']['email'] : '';
$itunes->setOwner($name, $email);
}
if (isset($data['itunes']['image'])) {
$itunes->setImage($data['itunes']['image']);
}
if (isset($data['itunes']['subtitle'])) {
$itunes->setSubtitle($data['itunes']['subtitle']);
}
if (isset($data['itunes']['summary'])) {
$itunes->setSummary($data['itunes']['summary']);
}
if (isset($data['itunes']['block'])) {
$itunes->setBlock($data['itunes']['block']);
}
if (isset($data['itunes']['explicit'])) {
$itunes->setExplicit($data['itunes']['explicit']);
}
if (isset($data['itunes']['keywords'])) {
$itunes->setKeywords($data['itunes']['keywords']);
}
if (isset($data['itunes']['new-feed-url'])) {
$itunes->setNewFeedUrl($data['itunes']['new-feed-url']);
}
$this->_header->setITunes($itunes);
}
}
/**
* Create the array of article entries
*
* @param array $data
* @throws Zend_Feed_Builder_Exception
* @return void
*/
private function _createEntries(array $data)
{
foreach ($data as $row) {
$mandatories = array('title', 'link', 'description');
foreach ($mandatories as $mandatory) {
if (!isset($row[$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key is missing");
}
}
$entry = new Zend_Feed_Builder_Entry($row['title'], $row['link'], $row['description']);
if (isset($row['guid'])) {
$entry->setId($row['guid']);
}
if (isset($row['content'])) {
$entry->setContent($row['content']);
}
if (isset($row['lastUpdate'])) {
$entry->setLastUpdate($row['lastUpdate']);
}
if (isset($row['comments'])) {
$entry->setCommentsUrl($row['comments']);
}
if (isset($row['commentRss'])) {
$entry->setCommentsRssUrl($row['commentRss']);
}
if (isset($row['source'])) {
$mandatories = array('title', 'url');
foreach ($mandatories as $mandatory) {
if (!isset($row['source'][$mandatory])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$mandatory key of source property is missing");
}
}
$entry->setSource($row['source']['title'], $row['source']['url']);
}
if (isset($row['category'])) {
$entry->setCategories($row['category']);
}
if (isset($row['enclosure'])) {
$entry->setEnclosures($row['enclosure']);
}
$this->_entries[] = $entry;
}
}
}

285
Zend/Feed/Builder/Entry.php Normal file
View file

@ -0,0 +1,285 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Entry.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* An entry of a custom build feed
*
* Classes implementing the Zend_Feed_Builder_Interface interface
* uses this class to describe an entry of a feed
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Entry extends ArrayObject
{
/**
* Create a new builder entry
*
* @param string $title
* @param string $link
* @param string $description short version of the entry, no html
* @return void
*/
public function __construct($title, $link, $description)
{
$this->offsetSet('title', $title);
$this->offsetSet('link', $link);
$this->offsetSet('description', $description);
$this->setLastUpdate(time());
}
/**
* Read only properties accessor
*
* @param string $name property to read
* @return mixed
*/
public function __get($name)
{
if (!$this->offsetExists($name)) {
return NULL;
}
return $this->offsetGet($name);
}
/**
* Write properties accessor
*
* @param string $name name of the property to set
* @param mixed $value value to set
* @return void
*/
public function __set($name, $value)
{
$this->offsetSet($name, $value);
}
/**
* Isset accessor
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Unset accessor
*
* @param string $key
* @return void
*/
public function __unset($key)
{
if ($this->offsetExists($key)) {
$this->offsetUnset($key);
}
}
/**
* Sets the id/guid of the entry
*
* @param string $id
* @return Zend_Feed_Builder_Entry
*/
public function setId($id)
{
$this->offsetSet('guid', $id);
return $this;
}
/**
* Sets the full html content of the entry
*
* @param string $content
* @return Zend_Feed_Builder_Entry
*/
public function setContent($content)
{
$this->offsetSet('content', $content);
return $this;
}
/**
* Timestamp of the update date
*
* @param int $lastUpdate
* @return Zend_Feed_Builder_Entry
*/
public function setLastUpdate($lastUpdate)
{
$this->offsetSet('lastUpdate', $lastUpdate);
return $this;
}
/**
* Sets the url of the commented page associated to the entry
*
* @param string $comments
* @return Zend_Feed_Builder_Entry
*/
public function setCommentsUrl($comments)
{
$this->offsetSet('comments', $comments);
return $this;
}
/**
* Sets the url of the comments feed link
*
* @param string $commentRss
* @return Zend_Feed_Builder_Entry
*/
public function setCommentsRssUrl($commentRss)
{
$this->offsetSet('commentRss', $commentRss);
return $this;
}
/**
* Defines a reference to the original source
*
* @param string $title
* @param string $url
* @return Zend_Feed_Builder_Entry
*/
public function setSource($title, $url)
{
$this->offsetSet('source', array('title' => $title,
'url' => $url));
return $this;
}
/**
* Sets the categories of the entry
* Format of the array:
* <code>
* array(
* array(
* 'term' => 'first category label',
* 'scheme' => 'url that identifies a categorization scheme' // optional
* ),
* // second category and so one
* )
* </code>
*
* @param array $categories
* @return Zend_Feed_Builder_Entry
*/
public function setCategories(array $categories)
{
foreach ($categories as $category) {
$this->addCategory($category);
}
return $this;
}
/**
* Add a category to the entry
*
* @param array $category see Zend_Feed_Builder_Entry::setCategories() for format
* @return Zend_Feed_Builder_Entry
* @throws Zend_Feed_Builder_Exception
*/
public function addCategory(array $category)
{
if (empty($category['term'])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to define the name of the category");
}
if (!$this->offsetExists('category')) {
$categories = array($category);
} else {
$categories = $this->offsetGet('category');
$categories[] = $category;
}
$this->offsetSet('category', $categories);
return $this;
}
/**
* Sets the enclosures of the entry
* Format of the array:
* <code>
* array(
* array(
* 'url' => 'url of the linked enclosure',
* 'type' => 'mime type of the enclosure' // optional
* 'length' => 'length of the linked content in octets' // optional
* ),
* // second enclosure and so one
* )
* </code>
*
* @param array $enclosures
* @return Zend_Feed_Builder_Entry
* @throws Zend_Feed_Builder_Exception
*/
public function setEnclosures(array $enclosures)
{
foreach ($enclosures as $enclosure) {
if (empty($enclosure['url'])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to supply an url for your enclosure");
}
$type = isset($enclosure['type']) ? $enclosure['type'] : '';
$length = isset($enclosure['length']) ? $enclosure['length'] : '';
$this->addEnclosure($enclosure['url'], $type, $length);
}
return $this;
}
/**
* Add an enclosure to the entry
*
* @param string $url
* @param string $type
* @param string $length
* @return Zend_Feed_Builder_Entry
*/
public function addEnclosure($url, $type = '', $length = '')
{
if (!$this->offsetExists('enclosure')) {
$enclosure = array();
} else {
$enclosure = $this->offsetGet('enclosure');
}
$enclosure[] = array('url' => $url,
'type' => $type,
'length' => $length);
$this->offsetSet('enclosure', $enclosure);
return $this;
}
}

View file

@ -0,0 +1,40 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
/**
* Zend_Feed_Builder exception class
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Exception extends Zend_Feed_Exception
{
}

View file

@ -0,0 +1,420 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Header.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Loader
*/
require_once 'Zend/Loader.php';
/**
* @see Zend_Feed_Builder_Header_Itunes
*/
require_once 'Zend/Feed/Builder/Header/Itunes.php';
/**
* @see Zend_Uri
*/
require_once 'Zend/Uri.php';
/**
* Header of a custom build feed
*
* Classes implementing the Zend_Feed_Builder_Interface interface
* uses this class to describe the header of a feed
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Header extends ArrayObject
{
/**
* Constructor
*
* @param string $title title of the feed
* @param string $link canonical url of the feed
* @param string $charset charset of the textual data
* @return void
*/
public function __construct($title, $link, $charset = 'utf-8')
{
$this->offsetSet('title', $title);
$this->offsetSet('link', $link);
$this->offsetSet('charset', $charset);
$this->setLastUpdate(time())
->setGenerator('Zend_Feed');
}
/**
* Read only properties accessor
*
* @param string $name property to read
* @return mixed
*/
public function __get($name)
{
if (!$this->offsetExists($name)) {
return NULL;
}
return $this->offsetGet($name);
}
/**
* Write properties accessor
*
* @param string $name name of the property to set
* @param mixed $value value to set
* @return void
*/
public function __set($name, $value)
{
$this->offsetSet($name, $value);
}
/**
* Isset accessor
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Unset accessor
*
* @param string $key
* @return void
*/
public function __unset($key)
{
if ($this->offsetExists($key)) {
$this->offsetUnset($key);
}
}
/**
* Timestamp of the update date
*
* @param int $lastUpdate
* @return Zend_Feed_Builder_Header
*/
public function setLastUpdate($lastUpdate)
{
$this->offsetSet('lastUpdate', $lastUpdate);
return $this;
}
/**
* Timestamp of the publication date
*
* @param int $published
* @return Zend_Feed_Builder_Header
*/
public function setPublishedDate($published)
{
$this->offsetSet('published', $published);
return $this;
}
/**
* Short description of the feed
*
* @param string $description
* @return Zend_Feed_Builder_Header
*/
public function setDescription($description)
{
$this->offsetSet('description', $description);
return $this;
}
/**
* Sets the author of the feed
*
* @param string $author
* @return Zend_Feed_Builder_Header
*/
public function setAuthor($author)
{
$this->offsetSet('author', $author);
return $this;
}
/**
* Sets the author's email
*
* @param string $email
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setEmail($email)
{
Zend_Loader::loadClass('Zend_Validate_EmailAddress');
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($email)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set a valid email address into the email property");
}
$this->offsetSet('email', $email);
return $this;
}
/**
* Sets the copyright notice
*
* @param string $copyright
* @return Zend_Feed_Builder_Header
*/
public function setCopyright($copyright)
{
$this->offsetSet('copyright', $copyright);
return $this;
}
/**
* Sets the image of the feed
*
* @param string $image
* @return Zend_Feed_Builder_Header
*/
public function setImage($image)
{
$this->offsetSet('image', $image);
return $this;
}
/**
* Sets the generator of the feed
*
* @param string $generator
* @return Zend_Feed_Builder_Header
*/
public function setGenerator($generator)
{
$this->offsetSet('generator', $generator);
return $this;
}
/**
* Sets the language of the feed
*
* @param string $language
* @return Zend_Feed_Builder_Header
*/
public function setLanguage($language)
{
$this->offsetSet('language', $language);
return $this;
}
/**
* Email address for person responsible for technical issues
* Ignored if atom is used
*
* @param string $webmaster
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setWebmaster($webmaster)
{
Zend_Loader::loadClass('Zend_Validate_EmailAddress');
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($webmaster)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set a valid email address into the webmaster property");
}
$this->offsetSet('webmaster', $webmaster);
return $this;
}
/**
* How long in minutes a feed can be cached before refreshing
* Ignored if atom is used
*
* @param int $ttl
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setTtl($ttl)
{
Zend_Loader::loadClass('Zend_Validate_Int');
$validate = new Zend_Validate_Int();
if (!$validate->isValid($ttl)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set an integer value to the ttl property");
}
$this->offsetSet('ttl', $ttl);
return $this;
}
/**
* PICS rating for the feed
* Ignored if atom is used
*
* @param string $rating
* @return Zend_Feed_Builder_Header
*/
public function setRating($rating)
{
$this->offsetSet('rating', $rating);
return $this;
}
/**
* Cloud to be notified of updates of the feed
* Ignored if atom is used
*
* @param string|Zend_Uri_Http $uri
* @param string $procedure procedure to call, e.g. myCloud.rssPleaseNotify
* @param string $protocol protocol to use, e.g. soap or xml-rpc
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setCloud($uri, $procedure, $protocol)
{
if (is_string($uri) && Zend_Uri_Http::check($uri)) {
$uri = Zend_Uri::factory($uri);
}
if (!$uri instanceof Zend_Uri_Http) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception('Passed parameter is not a valid HTTP URI');
}
if (!$uri->getPort()) {
$uri->setPort(80);
}
$this->offsetSet('cloud', array('uri' => $uri,
'procedure' => $procedure,
'protocol' => $protocol));
return $this;
}
/**
* A text input box that can be displayed with the feed
* Ignored if atom is used
*
* @param string $title the label of the Submit button in the text input area
* @param string $description explains the text input area
* @param string $name the name of the text object in the text input area
* @param string $link the URL of the CGI script that processes text input requests
* @return Zend_Feed_Builder_Header
*/
public function setTextInput($title, $description, $name, $link)
{
$this->offsetSet('textInput', array('title' => $title,
'description' => $description,
'name' => $name,
'link' => $link));
return $this;
}
/**
* Hint telling aggregators which hours they can skip
* Ignored if atom is used
*
* @param array $hours list of hours in 24 format
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setSkipHours(array $hours)
{
if (count($hours) > 24) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you can not have more than 24 rows in the skipHours property");
}
foreach ($hours as $hour) {
if ($hour < 0 || $hour > 23) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$hour has te be between 0 and 23");
}
}
$this->offsetSet('skipHours', $hours);
return $this;
}
/**
* Hint telling aggregators which days they can skip
* Ignored if atom is used
*
* @param array $days list of days to skip, e.g. Monday
* @return Zend_Feed_Builder_Header
* @throws Zend_Feed_Builder_Exception
*/
public function setSkipDays(array $days)
{
if (count($days) > 7) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you can not have more than 7 days in the skipDays property");
}
$valid = array('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
foreach ($days as $day) {
if (!in_array(strtolower($day), $valid)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("$day is not a valid day");
}
}
$this->offsetSet('skipDays', $days);
return $this;
}
/**
* Sets the iTunes rss extension
*
* @param Zend_Feed_Builder_Header_Itunes $itunes
* @return Zend_Feed_Builder_Header
*/
public function setITunes(Zend_Feed_Builder_Header_Itunes $itunes)
{
$this->offsetSet('itunes', $itunes);
return $this;
}
}

View file

@ -0,0 +1,285 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Itunes.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* ITunes rss extension
*
* Classes used to describe the itunes channel extension
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Builder_Header_Itunes extends ArrayObject
{
/**
* Constructor
*
* @param array $categories Categories columns and in iTunes Music Store Browse
* @return void
*/
public function __construct(array $categories)
{
$this->setCategories($categories);
}
/**
* Sets the categories column and in iTunes Music Store Browse
* $categories must conform to the following format:
* <code>
* array(array('main' => 'main category',
* 'sub' => 'sub category' // optionnal
* ),
* // up to 3 rows
* )
* </code>
*
* @param array $categories
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setCategories(array $categories)
{
$nb = count($categories);
if (0 === $nb) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set at least one itunes category");
}
if ($nb > 3) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set at most three itunes categories");
}
foreach ($categories as $i => $category) {
if (empty($category['main'])) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set the main category (category #$i)");
}
}
$this->offsetSet('category', $categories);
return $this;
}
/**
* Sets the artist value, default to the feed's author value
*
* @param string $author
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setAuthor($author)
{
$this->offsetSet('author', $author);
return $this;
}
/**
* Sets the owner of the postcast
*
* @param string $name default to the feed's author value
* @param string $email default to the feed's email value
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setOwner($name = '', $email = '')
{
if (!empty($email)) {
Zend_Loader::loadClass('Zend_Validate_EmailAddress');
$validate = new Zend_Validate_EmailAddress();
if (!$validate->isValid($email)) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set a valid email address into the itunes owner's email property");
}
}
$this->offsetSet('owner', array('name' => $name, 'email' => $email));
return $this;
}
/**
* Sets the album/podcast art picture
* Default to the feed's image value
*
* @param string $image
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setImage($image)
{
$this->offsetSet('image', $image);
return $this;
}
/**
* Sets the short description of the podcast
* Default to the feed's description
*
* @param string $subtitle
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setSubtitle($subtitle)
{
$this->offsetSet('subtitle', $subtitle);
return $this;
}
/**
* Sets the longer description of the podcast
* Default to the feed's description
*
* @param string $summary
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setSummary($summary)
{
$this->offsetSet('summary', $summary);
return $this;
}
/**
* Prevent a feed from appearing
*
* @param string $block can be 'yes' or 'no'
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setBlock($block)
{
$block = strtolower($block);
if (!in_array($block, array('yes', 'no'))) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set yes or no to the itunes block property");
}
$this->offsetSet('block', $block);
return $this;
}
/**
* Configuration of the parental advisory graphic
*
* @param string $explicit can be 'yes', 'no' or 'clean'
* @return Zend_Feed_Builder_Header_Itunes
* @throws Zend_Feed_Builder_Exception
*/
public function setExplicit($explicit)
{
$explicit = strtolower($explicit);
if (!in_array($explicit, array('yes', 'no', 'clean'))) {
/**
* @see Zend_Feed_Builder_Exception
*/
require_once 'Zend/Feed/Builder/Exception.php';
throw new Zend_Feed_Builder_Exception("you have to set yes, no or clean to the itunes explicit property");
}
$this->offsetSet('explicit', $explicit);
return $this;
}
/**
* Sets a comma separated list of 12 keywords maximum
*
* @param string $keywords
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setKeywords($keywords)
{
$this->offsetSet('keywords', $keywords);
return $this;
}
/**
* Sets the new feed URL location
*
* @param string $url
* @return Zend_Feed_Builder_Header_Itunes
*/
public function setNewFeedUrl($url)
{
$this->offsetSet('new_feed_url', $url);
return $this;
}
/**
* Read only properties accessor
*
* @param string $name property to read
* @return mixed
*/
public function __get($name)
{
if (!$this->offsetExists($name)) {
return NULL;
}
return $this->offsetGet($name);
}
/**
* Write properties accessor
*
* @param string $name name of the property to set
* @param mixed $value value to set
* @return void
*/
public function __set($name, $value)
{
$this->offsetSet($name, $value);
}
/**
* Isset accessor
*
* @param string $key
* @return boolean
*/
public function __isset($key)
{
return $this->offsetExists($key);
}
/**
* Unset accessor
*
* @param string $key
* @return void
*/
public function __unset($key)
{
if ($this->offsetExists($key)) {
$this->offsetUnset($key);
}
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* Input feed data interface
*
* Classes implementing this interface can be passe to Zend_Feed::importBuilder
* as an input data source for the Zend_Feed construction
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Feed_Builder_Interface
{
/**
* Returns an instance of Zend_Feed_Builder_Header
* describing the header of the feed
*
* @return Zend_Feed_Builder_Header
*/
public function getHeader();
/**
* Returns an array of Zend_Feed_Builder_Entry instances
* describing the entries of the feed
*
* @return array of Zend_Feed_Builder_Entry
*/
public function getEntries();
}

408
Zend/Feed/Element.php Normal file
View file

@ -0,0 +1,408 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Element.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* Wraps a DOMElement allowing for SimpleXML-like access to attributes.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Element implements ArrayAccess
{
/**
* @var DOMElement
*/
protected $_element;
/**
* @var Zend_Feed_Element
*/
protected $_parentElement;
/**
* @var boolean
*/
protected $_appended = true;
/**
* Zend_Feed_Element constructor.
*
* @param DOMElement $element The DOM element we're encapsulating.
* @return void
*/
public function __construct($element = null)
{
$this->_element = $element;
}
/**
* Get a DOM representation of the element
*
* Returns the underlying DOM object, which can then be
* manipulated with full DOM methods.
*
* @return DOMDocument
*/
public function getDOM()
{
return $this->_element;
}
/**
* Update the object from a DOM element
*
* Take a DOMElement object, which may be originally from a call
* to getDOM() or may be custom created, and use it as the
* DOM tree for this Zend_Feed_Element.
*
* @param DOMElement $element
* @return void
*/
public function setDOM(DOMElement $element)
{
$this->_element = $this->_element->ownerDocument->importNode($element, true);
}
/**
* Set the parent element of this object to another
* Zend_Feed_Element.
*
* @param Zend_Feed_Element $element
* @return void
*/
public function setParent(Zend_Feed_Element $element)
{
$this->_parentElement = $element;
$this->_appended = false;
}
/**
* Appends this element to its parent if necessary.
*
* @return void
*/
protected function ensureAppended()
{
if (!$this->_appended) {
$this->_parentElement->getDOM()->appendChild($this->_element);
$this->_appended = true;
$this->_parentElement->ensureAppended();
}
}
/**
* Get an XML string representation of this element
*
* Returns a string of this element's XML, including the XML
* prologue.
*
* @return string
*/
public function saveXml()
{
// Return a complete document including XML prologue.
$doc = new DOMDocument($this->_element->ownerDocument->version,
$this->_element->ownerDocument->actualEncoding);
$doc->appendChild($doc->importNode($this->_element, true));
return $doc->saveXML();
}
/**
* Get the XML for only this element
*
* Returns a string of this element's XML without prologue.
*
* @return string
*/
public function saveXmlFragment()
{
return $this->_element->ownerDocument->saveXML($this->_element);
}
/**
* Map variable access onto the underlying entry representation.
*
* Get-style access returns a Zend_Feed_Element representing the
* child element accessed. To get string values, use method syntax
* with the __call() overriding.
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
$nodes = $this->_children($var);
$length = count($nodes);
if ($length == 1) {
return new Zend_Feed_Element($nodes[0]);
} elseif ($length > 1) {
return array_map(create_function('$e', 'return new Zend_Feed_Element($e);'), $nodes);
} else {
// When creating anonymous nodes for __set chaining, don't
// call appendChild() on them. Instead we pass the current
// element to them as an extra reference; the child is
// then responsible for appending itself when it is
// actually set. This way "if ($foo->bar)" doesn't create
// a phantom "bar" element in our tree.
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
$node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns), $elt);
} else {
$node = $this->_element->ownerDocument->createElement($var);
}
$node = new self($node);
$node->setParent($this);
return $node;
}
}
/**
* Map variable sets onto the underlying entry representation.
*
* @param string $var The property to change.
* @param string $val The property's new value.
* @return void
* @throws Zend_Feed_Exception
*/
public function __set($var, $val)
{
$this->ensureAppended();
$nodes = $this->_children($var);
if (!$nodes) {
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
$node = $this->_element->ownerDocument->createElementNS(Zend_Feed::lookupNamespace($ns), $var, $val);
$this->_element->appendChild($node);
} else {
$node = $this->_element->ownerDocument->createElement($var, $val);
$this->_element->appendChild($node);
}
} elseif (count($nodes) > 1) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot set the value of multiple tags simultaneously.');
} else {
$nodes[0]->nodeValue = $val;
}
}
/**
* Map isset calls onto the underlying entry representation.
*
* @param string $var
* @return boolean
*/
public function __isset($var)
{
// Look for access of the form {ns:var}. We don't use
// _children() here because we can break out of the loop
// immediately once we find something.
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $elt && $child->prefix == $ns) {
return true;
}
}
} else {
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $var) {
return true;
}
}
}
}
/**
* Get the value of an element with method syntax.
*
* Map method calls to get the string value of the requested
* element. If there are multiple elements that match, this will
* return an array of those objects.
*
* @param string $var The element to get the string value of.
* @param mixed $unused This parameter is not used.
* @return mixed The node's value, null, or an array of nodes.
*/
public function __call($var, $unused)
{
$nodes = $this->_children($var);
if (!$nodes) {
return null;
} elseif (count($nodes) > 1) {
return $nodes;
} else {
return $nodes[0]->nodeValue;
}
}
/**
* Remove all children matching $var.
*
* @param string $var
* @return void
*/
public function __unset($var)
{
$nodes = $this->_children($var);
foreach ($nodes as $node) {
$parent = $node->parentNode;
$parent->removeChild($node);
}
}
/**
* Returns the nodeValue of this element when this object is used
* in a string context.
*
* @return string
*/
public function __toString()
{
return $this->_element->nodeValue;
}
/**
* Finds children with tagnames matching $var
*
* Similar to SimpleXML's children() method.
*
* @param string $var Tagname to match, can be either namespace:tagName or just tagName.
* @return array
*/
protected function _children($var)
{
$found = array();
// Look for access of the form {ns:var}.
if (strpos($var, ':') !== false) {
list($ns, $elt) = explode(':', $var, 2);
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $elt && $child->prefix == $ns) {
$found[] = $child;
}
}
} else {
foreach ($this->_element->childNodes as $child) {
if ($child->localName == $var) {
$found[] = $child;
}
}
}
return $found;
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @return boolean
*/
public function offsetExists($offset)
{
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->hasAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
} else {
return $this->_element->hasAttribute($offset);
}
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @return string
*/
public function offsetGet($offset)
{
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->getAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
} else {
return $this->_element->getAttribute($offset);
}
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @param string $value
* @return string
*/
public function offsetSet($offset, $value)
{
$this->ensureAppended();
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->setAttributeNS(Zend_Feed::lookupNamespace($ns), $attr, $value);
} else {
return $this->_element->setAttribute($offset, $value);
}
}
/**
* Required by the ArrayAccess interface.
*
* @param string $offset
* @return boolean
*/
public function offsetUnset($offset)
{
if (strpos($offset, ':') !== false) {
list($ns, $attr) = explode(':', $offset, 2);
return $this->_element->removeAttributeNS(Zend_Feed::lookupNamespace($ns), $attr);
} else {
return $this->_element->removeAttribute($offset);
}
}
}

View file

@ -0,0 +1,123 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Abstract.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed
*/
require_once 'Zend/Feed.php';
/**
* @see Zend_Feed_Element
*/
require_once 'Zend/Feed/Element.php';
/**
* Zend_Feed_Entry_Abstract represents a single entry in an Atom or RSS
* feed.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Feed_Entry_Abstract extends Zend_Feed_Element
{
/**
* Root XML element for entries. Subclasses must define this to a
* non-null value.
*
* @var string
*/
protected $_rootElement;
/**
* Root namespace for entries. Subclasses may define this to a
* non-null value.
*
* @var string
*/
protected $_rootNamespace = null;
/**
* Zend_Feed_Entry_Abstract constructor
*
* The Zend_Feed_Entry_Abstract constructor takes the URI of the feed the entry
* is part of, and optionally an XML construct (usually a
* SimpleXMLElement, but it can be an XML string or a DOMNode as
* well) that contains the contents of the entry.
*
* @param string $uri
* @param SimpleXMLElement|DOMNode|string $element
* @return void
* @throws Zend_Feed_Exception
*/
public function __construct($uri = null, $element = null)
{
if (!($element instanceof DOMElement)) {
if ($element) {
// Load the feed as an XML DOMDocument object
@ini_set('track_errors', 1);
$doc = @DOMDocument::loadXML($element);
@ini_restore('track_errors');
if (!$doc) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
} else {
$php_errormsg = '(error message not available)';
}
}
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
}
$element = $doc->getElementsByTagName($this->_rootElement)->item(0);
if (!$element) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <' . $this->_rootElement . '> element found, cannot parse feed.');
}
} else {
$doc = new DOMDocument('1.0', 'utf-8');
if ($this->_rootNamespace !== null) {
$element = $doc->createElementNS(Zend_Feed::lookupNamespace($this->_rootNamespace), $this->_rootElement);
} else {
$element = $doc->createElement($this->_rootElement);
}
}
}
parent::__construct($element);
}
}

273
Zend/Feed/Entry/Atom.php Normal file
View file

@ -0,0 +1,273 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Atom.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Entry_Abstract
*/
require_once 'Zend/Feed/Entry/Abstract.php';
/**
* Concrete class for working with Atom entries.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Entry_Atom extends Zend_Feed_Entry_Abstract
{
/**
* Root XML element for Atom entries.
*
* @var string
*/
protected $_rootElement = 'entry';
/**
* Root namespace for Atom entries.
*
* @var string
*/
protected $_rootNamespace = 'atom';
/**
* Delete an atom entry.
*
* Delete tries to delete this entry from its feed. If the entry
* does not contain a link rel="edit", we throw an error (either
* the entry does not yet exist or this is not an editable
* feed). If we have a link rel="edit", we do the empty-body
* HTTP DELETE to that URI and check for a response of 2xx.
* Usually the response would be 204 No Content, but the Atom
* Publishing Protocol permits it to be 200 OK.
*
* @return void
* @throws Zend_Feed_Exception
*/
public function delete()
{
// Look for link rel="edit" in the entry object.
$deleteUri = $this->link('edit');
if (!$deleteUri) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot delete entry; no link rel="edit" is present.');
}
// DELETE
$client = Zend_Feed::getHttpClient();
do {
$client->setUri($deleteUri);
if (Zend_Feed::getHttpMethodOverride()) {
$client->setHeader('X-HTTP-Method-Override', 'DELETE');
$response = $client->request('POST');
} else {
$response = $client->request('DELETE');
}
$httpStatus = $response->getStatus();
switch ((int) $httpStatus / 100) {
// Success
case 2:
return true;
// Redirect
case 3:
$deleteUri = $response->getHeader('Location');
continue;
// Error
default:
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception("Expected response code 2xx, got $httpStatus");
}
} while (true);
}
/**
* Save a new or updated Atom entry.
*
* Save is used to either create new entries or to save changes to
* existing ones. If we have a link rel="edit", we are changing
* an existing entry. In this case we re-serialize the entry and
* PUT it to the edit URI, checking for a 200 OK result.
*
* For posting new entries, you must specify the $postUri
* parameter to save() to tell the object where to post itself.
* We use $postUri and POST the serialized entry there, checking
* for a 201 Created response. If the insert is successful, we
* then parse the response from the POST to get any values that
* the server has generated: an id, an updated time, and its new
* link rel="edit".
*
* @param string $postUri Location to POST for creating new entries.
* @return void
* @throws Zend_Feed_Exception
*/
public function save($postUri = null)
{
if ($this->id()) {
// If id is set, look for link rel="edit" in the
// entry object and PUT.
$editUri = $this->link('edit');
if (!$editUri) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot edit entry; no link rel="edit" is present.');
}
$client = Zend_Feed::getHttpClient();
$client->setUri($editUri);
if (Zend_Feed::getHttpMethodOverride()) {
$client->setHeaders(array('X-HTTP-Method-Override: PUT',
'Content-Type: application/atom+xml'));
$client->setRawData($this->saveXML());
$response = $client->request('POST');
} else {
$client->setHeaders('Content-Type', 'application/atom+xml');
$client->setRawData($this->saveXML());
$response = $client->request('PUT');
}
if ($response->getStatus() !== 200) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Expected response code 200, got ' . $response->getStatus());
}
} else {
if ($postUri === null) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('PostURI must be specified to save new entries.');
}
$client = Zend_Feed::getHttpClient();
$client->setUri($postUri);
$client->setRawData($this->saveXML());
$response = $client->request('POST');
if ($response->getStatus() !== 201) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Expected response code 201, got '
. $response->getStatus());
}
}
// Update internal properties using $client->responseBody;
@ini_set('track_errors', 1);
$newEntry = @DOMDocument::loadXML($response->getBody());
@ini_restore('track_errors');
if (!$newEntry) {
// prevent the class to generate an undefined variable notice (ZF-2590)
if (!isset($php_errormsg)) {
if (function_exists('xdebug_is_enabled')) {
$php_errormsg = '(error message not available, when XDebug is running)';
} else {
$php_errormsg = '(error message not available)';
}
}
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('XML cannot be parsed: ' . $php_errormsg);
}
$newEntry = $newEntry->getElementsByTagName($this->_rootElement)->item(0);
if (!$newEntry) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <feed> element found in server response:'
. "\n\n" . $client->responseBody);
}
if ($this->_element->parentNode) {
$oldElement = $this->_element;
$this->_element = $oldElement->ownerDocument->importNode($newEntry, true);
$oldElement->parentNode->replaceChild($this->_element, $oldElement);
} else {
$this->_element = $newEntry;
}
}
/**
* Easy access to <link> tags keyed by "rel" attributes.
*
* If $elt->link() is called with no arguments, we will attempt to
* return the value of the <link> tag(s) like all other
* method-syntax attribute access. If an argument is passed to
* link(), however, then we will return the "href" value of the
* first <link> tag that has a "rel" attribute matching $rel:
*
* $elt->link(): returns the value of the link tag.
* $elt->link('self'): returns the href from the first <link rel="self"> in the entry.
*
* @param string $rel The "rel" attribute to look for.
* @return mixed
*/
public function link($rel = null)
{
if ($rel === null) {
return parent::__call('link', null);
}
// index link tags by their "rel" attribute.
$links = parent::__get('link');
if (!is_array($links)) {
if ($links instanceof Zend_Feed_Element) {
$links = array($links);
} else {
return $links;
}
}
foreach ($links as $link) {
if (empty($link['rel'])) {
continue;
}
if ($rel == $link['rel']) {
return $link['href'];
}
}
return null;
}
}

122
Zend/Feed/Entry/Rss.php Normal file
View file

@ -0,0 +1,122 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Rss.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Entry_Abstract
*/
require_once 'Zend/Feed/Entry/Abstract.php';
/**
* Concrete class for working with RSS items.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Entry_Rss extends Zend_Feed_Entry_Abstract
{
/**
* Root XML element for RSS items.
*
* @var string
*/
protected $_rootElement = 'item';
/**
* Overwrites parent::_get method to enable read access
* to content:encoded element.
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
switch ($var) {
case 'content':
$prefix = $this->_element->lookupPrefix('http://purl.org/rss/1.0/modules/content/');
return parent::__get("$prefix:encoded");
default:
return parent::__get($var);
}
}
/**
* Overwrites parent::_set method to enable write access
* to content:encoded element.
*
* @param string $var The property to change.
* @param string $val The property's new value.
* @return void
*/
public function __set($var, $value)
{
switch ($var) {
case 'content':
parent::__set('content:encoded', $value);
break;
default:
parent::__set($var, $value);
}
}
/**
* Overwrites parent::_isset method to enable access
* to content:encoded element.
*
* @param string $var
* @return boolean
*/
public function __isset($var)
{
switch ($var) {
case 'content':
// don't use other callback to prevent invalid returned value
return $this->content() !== null;
default:
return parent::__isset($var);
}
}
/**
* Overwrites parent::_call method to enable read access
* to content:encoded element.
* Please note that method-style write access is not currently supported
* by parent method, consequently this method doesn't as well.
*
* @param string $var The element to get the string value of.
* @param mixed $unused This parameter is not used.
* @return mixed The node's value, null, or an array of nodes.
*/
public function __call($var, $unused)
{
switch ($var) {
case 'content':
$prefix = $this->_element->lookupPrefix('http://purl.org/rss/1.0/modules/content/');
return parent::__call("$prefix:encoded", $unused);
default:
return parent::__call($var, $unused);
}
}
}

42
Zend/Feed/Exception.php Normal file
View file

@ -0,0 +1,42 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Exception
*/
require_once 'Zend/Exception.php';
/**
* Feed exceptions
*
* Class to represent exceptions that occur during Feed operations.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Exception extends Zend_Exception
{}

504
Zend/Feed/Rss.php Normal file
View file

@ -0,0 +1,504 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Rss.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Feed_Abstract
*/
require_once 'Zend/Feed/Abstract.php';
/**
* @see Zend_Feed_Entry_Rss
*/
require_once 'Zend/Feed/Entry/Rss.php';
/**
* RSS channel class
*
* The Zend_Feed_Rss class is a concrete subclass of
* Zend_Feed_Abstract meant for representing RSS channels. It does not
* add any methods to its parent, just provides a classname to check
* against with the instanceof operator, and expects to be handling
* RSS-formatted data instead of Atom.
*
* @category Zend
* @package Zend_Feed
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Feed_Rss extends Zend_Feed_Abstract
{
/**
* The classname for individual channel elements.
*
* @var string
*/
protected $_entryClassName = 'Zend_Feed_Entry_Rss';
/**
* The element name for individual channel elements (RSS <item>s).
*
* @var string
*/
protected $_entryElementName = 'item';
/**
* The default namespace for RSS channels.
*
* @var string
*/
protected $_defaultNamespace = 'rss';
/**
* Override Zend_Feed_Abstract to set up the $_element and $_entries aliases.
*
* @return void
* @throws Zend_Feed_Exception
*/
public function __wakeup()
{
parent::__wakeup();
// Find the base channel element and create an alias to it.
$this->_element = $this->_element->getElementsByTagName('channel')->item(0);
if (!$this->_element) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('No root <channel> element found, cannot parse channel.');
}
// Find the entries and save a pointer to them for speed and
// simplicity.
$this->_buildEntryCache();
}
/**
* Make accessing some individual elements of the channel easier.
*
* Special accessors 'item' and 'items' are provided so that if
* you wish to iterate over an RSS channel's items, you can do so
* using foreach ($channel->items as $item) or foreach
* ($channel->item as $item).
*
* @param string $var The property to access.
* @return mixed
*/
public function __get($var)
{
switch ($var) {
case 'item':
// fall through to the next case
case 'items':
return $this;
default:
return parent::__get($var);
}
}
/**
* Generate the header of the feed when working in write mode
*
* @param array $array the data to use
* @return DOMElement root node
*/
protected function _mapFeedHeaders($array)
{
$channel = $this->_element->createElement('channel');
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($array->title));
$channel->appendChild($title);
$link = $this->_element->createElement('link', $array->link);
$channel->appendChild($link);
$desc = isset($array->description) ? $array->description : '';
$description = $this->_element->createElement('description');
$description->appendChild($this->_element->createCDATASection($desc));
$channel->appendChild($description);
$pubdate = isset($array->lastUpdate) ? $array->lastUpdate : time();
$pubdate = $this->_element->createElement('pubDate', gmdate('r', $pubdate));
$channel->appendChild($pubdate);
if (isset($array->published)) {
$lastBuildDate = $this->_element->createElement('lastBuildDate', gmdate('r', $array->published));
}
$editor = '';
if (!empty($array->email)) {
$editor .= $array->email;
}
if (!empty($array->author)) {
$editor .= ' (' . $array->author . ')';
}
if (!empty($editor)) {
$author = $this->_element->createElement('managingEditor', ltrim($editor));
$channel->appendChild($author);
}
if (isset($array->webmaster)) {
$channel->appendChild($this->_element->createElement('webMaster', $array->webmaster));
}
if (!empty($array->copyright)) {
$copyright = $this->_element->createElement('copyright', $array->copyright);
$channel->appendChild($copyright);
}
if (!empty($array->image)) {
$image = $this->_element->createElement('image');
$url = $this->_element->createElement('url', $array->image);
$image->appendChild($url);
$imagetitle = $this->_element->createElement('title', $array->title);
$image->appendChild($imagetitle);
$imagelink = $this->_element->createElement('link', $array->link);
$image->appendChild($imagelink);
$channel->appendChild($image);
}
$generator = !empty($array->generator) ? $array->generator : 'Zend_Feed';
$generator = $this->_element->createElement('generator', $generator);
$channel->appendChild($generator);
if (!empty($array->language)) {
$language = $this->_element->createElement('language', $array->language);
$channel->appendChild($language);
}
$doc = $this->_element->createElement('docs', 'http://blogs.law.harvard.edu/tech/rss');
$channel->appendChild($doc);
if (isset($array->cloud)) {
$cloud = $this->_element->createElement('cloud');
$cloud->setAttribute('domain', $array->cloud['uri']->getHost());
$cloud->setAttribute('port', $array->cloud['uri']->getPort());
$cloud->setAttribute('path', $array->cloud['uri']->getPath());
$cloud->setAttribute('registerProcedure', $array->cloud['procedure']);
$cloud->setAttribute('protocol', $array->cloud['protocol']);
$channel->appendChild($cloud);
}
if (isset($array->rating)) {
$rating = $this->_element->createElement('rating', $array->rating);
$channel->appendChild($rating);
}
if (isset($array->textInput)) {
$textinput = $this->_element->createElement('textInput');
$textinput->appendChild($this->_element->createElement('title', $array->textInput['title']));
$textinput->appendChild($this->_element->createElement('description', $array->textInput['description']));
$textinput->appendChild($this->_element->createElement('name', $array->textInput['name']));
$textinput->appendChild($this->_element->createElement('link', $array->textInput['link']));
$channel->appendChild($textinput);
}
if (isset($array->skipHours)) {
$skipHours = $this->_element->createElement('skipHours');
foreach ($array->skipHours as $hour) {
$skipHours->appendChild($this->_element->createElement('hour', $hour));
}
$channel->appendChild($skipHours);
}
if (isset($array->skipDays)) {
$skipDays = $this->_element->createElement('skipDays');
foreach ($array->skipDays as $day) {
$skipDays->appendChild($this->_element->createElement('day', $day));
}
$channel->appendChild($skipDays);
}
if (isset($array->itunes)) {
$this->_buildiTunes($channel, $array);
}
return $channel;
}
/**
* Adds the iTunes extensions to a root node
*
* @param DOMElement $root
* @param array $array
* @return void
*/
private function _buildiTunes(DOMElement $root, $array)
{
/* author node */
$author = '';
if (isset($array->itunes->author)) {
$author = $array->itunes->author;
} elseif (isset($array->author)) {
$author = $array->author;
}
if (!empty($author)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:author', $author);
$root->appendChild($node);
}
/* owner node */
$author = '';
$email = '';
if (isset($array->itunes->owner)) {
if (isset($array->itunes->owner['name'])) {
$author = $array->itunes->owner['name'];
}
if (isset($array->itunes->owner['email'])) {
$email = $array->itunes->owner['email'];
}
}
if (empty($author) && isset($array->author)) {
$author = $array->author;
}
if (empty($email) && isset($array->email)) {
$email = $array->email;
}
if (!empty($author) || !empty($email)) {
$owner = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:owner');
if (!empty($author)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:name', $author);
$owner->appendChild($node);
}
if (!empty($email)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:email', $email);
$owner->appendChild($node);
}
$root->appendChild($owner);
}
$image = '';
if (isset($array->itunes->image)) {
$image = $array->itunes->image;
} elseif (isset($array->image)) {
$image = $array->image;
}
if (!empty($image)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:image');
$node->setAttribute('href', $image);
$root->appendChild($node);
}
$subtitle = '';
if (isset($array->itunes->subtitle)) {
$subtitle = $array->itunes->subtitle;
} elseif (isset($array->description)) {
$subtitle = $array->description;
}
if (!empty($subtitle)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:subtitle', $subtitle);
$root->appendChild($node);
}
$summary = '';
if (isset($array->itunes->summary)) {
$summary = $array->itunes->summary;
} elseif (isset($array->description)) {
$summary = $array->description;
}
if (!empty($summary)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:summary', $summary);
$root->appendChild($node);
}
if (isset($array->itunes->block)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:block', $array->itunes->block);
$root->appendChild($node);
}
if (isset($array->itunes->explicit)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:explicit', $array->itunes->explicit);
$root->appendChild($node);
}
if (isset($array->itunes->keywords)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:keywords', $array->itunes->keywords);
$root->appendChild($node);
}
if (isset($array->itunes->new_feed_url)) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:new-feed-url', $array->itunes->new_feed_url);
$root->appendChild($node);
}
if (isset($array->itunes->category)) {
foreach ($array->itunes->category as $i => $category) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
$node->setAttribute('text', $category['main']);
$root->appendChild($node);
$add_end_category = false;
if (!empty($category['sub'])) {
$add_end_category = true;
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
$node->setAttribute('text', $category['sub']);
$root->appendChild($node);
}
if ($i > 0 || $add_end_category) {
$node = $this->_element->createElementNS('http://www.itunes.com/DTDs/Podcast-1.0.dtd', 'itunes:category');
$root->appendChild($node);
}
}
}
}
/**
* Generate the entries of the feed when working in write mode
*
* The following nodes are constructed for each feed entry
* <item>
* <title>entry title</title>
* <link>url to feed entry</link>
* <guid>url to feed entry</guid>
* <description>short text</description>
* <content:encoded>long version, can contain html</content:encoded>
* </item>
*
* @param DOMElement $root the root node to use
* @param array $array the data to use
* @return void
*/
protected function _mapFeedEntries(DOMElement $root, $array)
{
Zend_Feed::registerNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
foreach ($array as $dataentry) {
$item = $this->_element->createElement('item');
$title = $this->_element->createElement('title');
$title->appendChild($this->_element->createCDATASection($dataentry->title));
$item->appendChild($title);
$link = $this->_element->createElement('link', $dataentry->link);
$item->appendChild($link);
if (isset($dataentry->guid)) {
$guid = $this->_element->createElement('guid', $dataentry->guid);
$item->appendChild($guid);
}
$description = $this->_element->createElement('description');
$description->appendChild($this->_element->createCDATASection($dataentry->description));
$item->appendChild($description);
if (isset($dataentry->content)) {
$content = $this->_element->createElement('content:encoded');
$content->appendChild($this->_element->createCDATASection($dataentry->content));
$item->appendChild($content);
}
$pubdate = isset($dataentry->lastUpdate) ? $dataentry->lastUpdate : time();
$pubdate = $this->_element->createElement('pubDate', gmdate('r', $pubdate));
$item->appendChild($pubdate);
if (isset($dataentry->category)) {
foreach ($dataentry->category as $category) {
$node = $this->_element->createElement('category', $category['term']);
if (isset($category['scheme'])) {
$node->setAttribute('domain', $category['scheme']);
}
$item->appendChild($node);
}
}
if (isset($dataentry->source)) {
$source = $this->_element->createElement('source', $dataentry->source['title']);
$source->setAttribute('url', $dataentry->source['url']);
$item->appendChild($source);
}
if (isset($dataentry->comments)) {
$comments = $this->_element->createElement('comments', $dataentry->comments);
$item->appendChild($comments);
}
if (isset($dataentry->commentRss)) {
$comments = $this->_element->createElementNS('http://wellformedweb.org/CommentAPI/',
'wfw:commentRss',
$dataentry->commentRss);
$item->appendChild($comments);
}
if (isset($dataentry->enclosure)) {
foreach ($dataentry->enclosure as $enclosure) {
$node = $this->_element->createElement('enclosure');
$node->setAttribute('url', $enclosure['url']);
if (isset($enclosure['type'])) {
$node->setAttribute('type', $enclosure['type']);
}
if (isset($enclosure['length'])) {
$node->setAttribute('length', $enclosure['length']);
}
$item->appendChild($node);
}
}
$root->appendChild($item);
}
}
/**
* Override Zend_Feed_Element to include <rss> root node
*
* @return string
*/
public function saveXml()
{
// Return a complete document including XML prologue.
$doc = new DOMDocument($this->_element->ownerDocument->version,
$this->_element->ownerDocument->actualEncoding);
$root = $doc->createElement('rss');
// Use rss version 2.0
$root->setAttribute('version', '2.0');
// Content namespace
$root->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:content', 'http://purl.org/rss/1.0/modules/content/');
$root->appendChild($doc->importNode($this->_element, true));
// Append root node
$doc->appendChild($root);
// Format output
$doc->formatOutput = true;
return $doc->saveXML();
}
/**
* Send feed to a http client with the correct header
*
* @return void
* @throws Zend_Feed_Exception if headers have already been sent
*/
public function send()
{
if (headers_sent()) {
/**
* @see Zend_Feed_Exception
*/
require_once 'Zend/Feed/Exception.php';
throw new Zend_Feed_Exception('Cannot send RSS because headers have already been sent.');
}
header('Content-type: application/rss+xml; charset: ' . $this->_element->ownerDocument->actualEncoding);
echo $this->saveXml();
}
}

1086
Zend/Http/Client.php Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,33 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter_Exception
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Http/Client/Exception.php';
/**
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Client_Adapter_Exception extends Zend_Http_Client_Exception
{}

View file

@ -0,0 +1,78 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* An interface description for Zend_Http_Client_Adapter classes.
*
* These classes are used as connectors for Zend_Http_Client, performing the
* tasks of connecting, writing, reading and closing connection to the server.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Http_Client_Adapter_Interface
{
/**
* Set the configuration array for the adapter
*
* @param array $config
*/
public function setConfig($config = array());
/**
* Connect to the remote server
*
* @param string $host
* @param int $port
* @param boolean $secure
*/
public function connect($host, $port = 80, $secure = false);
/**
* Send request to the remote server
*
* @param string $method
* @param Zend_Uri_Http $url
* @param string $http_ver
* @param array $headers
* @param string $body
* @return string Request as text
*/
public function write($method, $url, $http_ver = '1.1', $headers = array(), $body = '');
/**
* Read response from server
*
* @return string
*/
public function read();
/**
* Close the connection to the server
*
*/
public function close();
}

View file

@ -0,0 +1,267 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @version $Id: Proxy.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Uri/Http.php';
require_once 'Zend/Http/Client.php';
require_once 'Zend/Http/Client/Adapter/Socket.php';
/**
* HTTP Proxy-supporting Zend_Http_Client adapter class, based on the default
* socket based adapter.
*
* Should be used if proxy HTTP access is required. If no proxy is set, will
* fall back to Zend_Http_Client_Adapter_Socket behavior. Just like the
* default Socket adapter, this adapter does not require any special extensions
* installed.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Client_Adapter_Proxy extends Zend_Http_Client_Adapter_Socket
{
/**
* Parameters array
*
* @var array
*/
protected $config = array(
'ssltransport' => 'ssl',
'proxy_host' => '',
'proxy_port' => 8080,
'proxy_user' => '',
'proxy_pass' => '',
'proxy_auth' => Zend_Http_Client::AUTH_BASIC
);
/**
* Whether HTTPS CONNECT was already negotiated with the proxy or not
*
* @var boolean
*/
protected $negotiated = false;
/**
* Connect to the remote server
*
* Will try to connect to the proxy server. If no proxy was set, will
* fall back to the target server (behave like regular Socket adapter)
*
* @param string $host
* @param int $port
* @param boolean $secure
* @param int $timeout
*/
public function connect($host, $port = 80, $secure = false)
{
// If no proxy is set, fall back to Socket adapter
if (! $this->config['proxy_host']) return parent::connect($host, $port, $secure);
// Go through a proxy - the connection is actually to the proxy server
$host = $this->config['proxy_host'];
$port = $this->config['proxy_port'];
// If we are connected to the wrong proxy, disconnect first
if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
if (is_resource($this->socket)) $this->close();
}
// Now, if we are not connected, connect
if (! is_resource($this->socket) || ! $this->config['keepalive']) {
$this->socket = @fsockopen($host, $port, $errno, $errstr, (int) $this->config['timeout']);
if (! $this->socket) {
$this->close();
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception(
'Unable to Connect to proxy server ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr);
}
// Set the stream timeout
if (!stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout');
}
// Update connected_to
$this->connected_to = array($host, $port);
}
}
/**
* Send request to the proxy server
*
* @param string $method
* @param Zend_Uri_Http $uri
* @param string $http_ver
* @param array $headers
* @param string $body
* @return string Request as string
*/
public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
{
// If no proxy is set, fall back to default Socket adapter
if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body);
// Make sure we're properly connected
if (! $this->socket) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected");
}
$host = $this->config['proxy_host'];
$port = $this->config['proxy_port'];
if ($this->connected_to[0] != $host || $this->connected_to[1] != $port) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server");
}
// Add Proxy-Authorization header
if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization']))
$headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader(
$this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth']
);
// if we are proxying HTTPS, preform CONNECT handshake with the proxy
if ($uri->getScheme() == 'https' && (! $this->negotiated)) {
$this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers);
$this->negotiated = true;
}
// Save request method for later
$this->method = $method;
// Build request headers
$request = "{$method} {$uri->__toString()} HTTP/{$http_ver}\r\n";
// Add all headers to the request string
foreach ($headers as $k => $v) {
if (is_string($k)) $v = "$k: $v";
$request .= "$v\r\n";
}
// Add the request body
$request .= "\r\n" . $body;
// Send the request
if (! @fwrite($this->socket, $request)) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
}
return $request;
}
/**
* Preform handshaking with HTTPS proxy using CONNECT method
*
* @param string $host
* @param integer $port
* @param string $http_ver
* @param array $headers
*/
protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array())
{
$request = "CONNECT $host:$port HTTP/$http_ver\r\n" .
"Host: " . $this->config['proxy_host'] . "\r\n";
// Add the user-agent header
if (isset($this->config['useragent'])) {
$request .= "User-agent: " . $this->config['useragent'] . "\r\n";
}
// If the proxy-authorization header is set, send it to proxy but remove
// it from headers sent to target host
if (isset($headers['proxy-authorization'])) {
$request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n";
unset($headers['proxy-authorization']);
}
$request .= "\r\n";
// Send the request
if (! @fwrite($this->socket, $request)) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
}
// Read response headers only
$response = '';
$gotStatus = false;
while ($line = @fgets($this->socket)) {
$gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
if ($gotStatus) {
$response .= $line;
if (!chop($line)) break;
}
}
// Check that the response from the proxy is 200
if (Zend_Http_Response::extractCode($response) != 200) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response);
}
// If all is good, switch socket to secure mode. We have to fall back
// through the different modes
$modes = array(
STREAM_CRYPTO_METHOD_TLS_CLIENT,
STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
STREAM_CRYPTO_METHOD_SSLv2_CLIENT
);
$success = false;
foreach($modes as $mode) {
$success = stream_socket_enable_crypto($this->socket, true, $mode);
if ($success) break;
}
if (! $success) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" .
" HTTPS server through proxy: could not negotiate secure connection.");
}
}
/**
* Close the connection to the server
*
*/
public function close()
{
parent::close();
$this->negotiated = false;
}
/**
* Destructor: make sure the socket is disconnected
*
*/
public function __destruct()
{
if ($this->socket) $this->close();
}
}

View file

@ -0,0 +1,319 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @version $Id: Socket.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Uri/Http.php';
require_once 'Zend/Http/Client/Adapter/Interface.php';
/**
* A sockets based (stream_socket_client) adapter class for Zend_Http_Client. Can be used
* on almost every PHP environment, and does not require any special extensions.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Client_Adapter_Socket implements Zend_Http_Client_Adapter_Interface
{
/**
* The socket for server connection
*
* @var resource|null
*/
protected $socket = null;
/**
* What host/port are we connected to?
*
* @var array
*/
protected $connected_to = array(null, null);
/**
* Parameters array
*
* @var array
*/
protected $config = array(
'ssltransport' => 'ssl',
'sslcert' => null,
'sslpassphrase' => null
);
/**
* Request method - will be set by write() and might be used by read()
*
* @var string
*/
protected $method = null;
/**
* Adapter constructor, currently empty. Config is set using setConfig()
*
*/
public function __construct()
{
}
/**
* Set the configuration array for the adapter
*
* @param array $config
*/
public function setConfig($config = array())
{
if (! is_array($config)) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception(
'$config expects an array, ' . gettype($config) . ' recieved.');
}
foreach ($config as $k => $v) {
$this->config[strtolower($k)] = $v;
}
}
/**
* Connect to the remote server
*
* @param string $host
* @param int $port
* @param boolean $secure
* @param int $timeout
*/
public function connect($host, $port = 80, $secure = false)
{
// If the URI should be accessed via SSL, prepend the Hostname with ssl://
$host = ($secure ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
// If we are connected to the wrong host, disconnect first
if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
if (is_resource($this->socket)) $this->close();
}
// Now, if we are not connected, connect
if (! is_resource($this->socket) || ! $this->config['keepalive']) {
$context = stream_context_create();
if ($secure) {
if ($this->config['sslcert'] !== null) {
if (! stream_context_set_option($context, 'ssl', 'local_cert',
$this->config['sslcert'])) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Unable to set sslcert option');
}
}
if ($this->config['sslpassphrase'] !== null) {
if (! stream_context_set_option($context, 'ssl', 'passphrase',
$this->config['sslpassphrase'])) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Unable to set sslpassphrase option');
}
}
}
$this->socket = @stream_socket_client($host . ':' . $port,
$errno,
$errstr,
(int) $this->config['timeout'],
STREAM_CLIENT_CONNECT,
$context);
if (! $this->socket) {
$this->close();
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception(
'Unable to Connect to ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr);
}
// Set the stream timeout
if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Unable to set the connection timeout');
}
// Update connected_to
$this->connected_to = array($host, $port);
}
}
/**
* Send request to the remote server
*
* @param string $method
* @param Zend_Uri_Http $uri
* @param string $http_ver
* @param array $headers
* @param string $body
* @return string Request as string
*/
public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
{
// Make sure we're properly connected
if (! $this->socket) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are not connected');
}
$host = $uri->getHost();
$host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Trying to write but we are connected to the wrong host');
}
// Save request method for later
$this->method = $method;
// Build request headers
$path = $uri->getPath();
if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
$request = "{$method} {$path} HTTP/{$http_ver}\r\n";
foreach ($headers as $k => $v) {
if (is_string($k)) $v = ucfirst($k) . ": $v";
$request .= "$v\r\n";
}
// Add the request body
$request .= "\r\n" . $body;
// Send the request
if (! @fwrite($this->socket, $request)) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Error writing request to server');
}
return $request;
}
/**
* Read response from server
*
* @return string
*/
public function read()
{
// First, read headers only
$response = '';
$gotStatus = false;
while ($line = @fgets($this->socket)) {
$gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
if ($gotStatus) {
$response .= $line;
if (!chop($line)) break;
}
}
// Handle 100 and 101 responses internally by restarting the read again
if (Zend_Http_Response::extractCode($response) == 100 ||
Zend_Http_Response::extractCode($response) == 101) return $this->read();
// If this was a HEAD request, return after reading the header (no need to read body)
if ($this->method == Zend_Http_Client::HEAD) return $response;
// Check headers to see what kind of connection / transfer encoding we have
$headers = Zend_Http_Response::extractHeaders($response);
// if the connection is set to close, just read until socket closes
if (isset($headers['connection']) && $headers['connection'] == 'close') {
while ($buff = @fread($this->socket, 8192)) {
$response .= $buff;
}
$this->close();
// Else, if we got a transfer-encoding header (chunked body)
} elseif (isset($headers['transfer-encoding'])) {
if ($headers['transfer-encoding'] == 'chunked') {
do {
$chunk = '';
$line = @fgets($this->socket);
$chunk .= $line;
$hexchunksize = ltrim(chop($line), '0');
$hexchunksize = strlen($hexchunksize) ? strtolower($hexchunksize) : 0;
$chunksize = hexdec(chop($line));
if (dechex($chunksize) != $hexchunksize) {
@fclose($this->socket);
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception('Invalid chunk size "' .
$hexchunksize . '" unable to read chunked body');
}
$left_to_read = $chunksize;
while ($left_to_read > 0) {
$line = @fread($this->socket, $left_to_read);
$chunk .= $line;
$left_to_read -= strlen($line);
}
$chunk .= @fgets($this->socket);
$response .= $chunk;
} while ($chunksize > 0);
} else {
throw new Zend_Http_Client_Adapter_Exception('Cannot handle "' .
$headers['transfer-encoding'] . '" transfer encoding');
}
// Else, if we got the content-length header, read this number of bytes
} elseif (isset($headers['content-length'])) {
$left_to_read = $headers['content-length'];
$chunk = '';
while ($left_to_read > 0) {
$chunk = @fread($this->socket, $left_to_read);
$left_to_read -= strlen($chunk);
$response .= $chunk;
}
// Fallback: just read the response (should not happen)
} else {
while ($buff = @fread($this->socket, 8192)) {
$response .= $buff;
}
$this->close();
}
return $response;
}
/**
* Close the connection to the server
*
*/
public function close()
{
if (is_resource($this->socket)) @fclose($this->socket);
$this->socket = null;
$this->connected_to = array(null, null);
}
/**
* Destructor: make sure the socket is disconnected
*
*/
public function __destruct()
{
if ($this->socket) $this->close();
}
}

View file

@ -0,0 +1,193 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @version $Id: Test.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Uri/Http.php';
require_once 'Zend/Http/Response.php';
require_once 'Zend/Http/Client/Adapter/Interface.php';
/**
* A testing-purposes adapter.
*
* Should be used to test all components that rely on Zend_Http_Client,
* without actually performing an HTTP request. You should instantiate this
* object manually, and then set it as the client's adapter. Then, you can
* set the expected response using the setResponse() method.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Adapter
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Client_Adapter_Test implements Zend_Http_Client_Adapter_Interface
{
/**
* Parameters array
*
* @var array
*/
protected $config = array();
/**
* Buffer of responses to be returned by the read() method. Can be
* set using setResponse() and addResponse().
*
* @var array
*/
protected $responses = array("HTTP/1.1 400 Bad Request\r\n\r\n");
/**
* Current position in the response buffer
*
* @var integer
*/
protected $responseIndex = 0;
/**
* Adapter constructor, currently empty. Config is set using setConfig()
*
*/
public function __construct()
{ }
/**
* Set the configuration array for the adapter
*
* @param array $config
*/
public function setConfig($config = array())
{
if (! is_array($config)) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception(
'$config expects an array, ' . gettype($config) . ' recieved.');
}
foreach ($config as $k => $v) {
$this->config[strtolower($k)] = $v;
}
}
/**
* Connect to the remote server
*
* @param string $host
* @param int $port
* @param boolean $secure
* @param int $timeout
*/
public function connect($host, $port = 80, $secure = false)
{ }
/**
* Send request to the remote server
*
* @param string $method
* @param Zend_Uri_Http $uri
* @param string $http_ver
* @param array $headers
* @param string $body
* @return string Request as string
*/
public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
{
$host = $uri->getHost();
$host = (strtolower($uri->getScheme()) == 'https' ? 'sslv2://' . $host : $host);
// Build request headers
$path = $uri->getPath();
if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
$request = "{$method} {$path} HTTP/{$http_ver}\r\n";
foreach ($headers as $k => $v) {
if (is_string($k)) $v = ucfirst($k) . ": $v";
$request .= "$v\r\n";
}
// Add the request body
$request .= "\r\n" . $body;
// Do nothing - just return the request as string
return $request;
}
/**
* Return the response set in $this->setResponse()
*
* @return string
*/
public function read()
{
if ($this->responseIndex >= count($this->responses)) {
$this->responseIndex = 0;
}
return $this->responses[$this->responseIndex++];
}
/**
* Close the connection (dummy)
*
*/
public function close()
{ }
/**
* Set the HTTP response(s) to be returned by this adapter
*
* @param Zend_Http_Response|array|string $response
*/
public function setResponse($response)
{
if ($response instanceof Zend_Http_Response) {
$response = $response->asString();
}
$this->responses = (array)$response;
$this->responseIndex = 0;
}
/**
* Add another response to the response buffer.
*
* @param string $response
*/
public function addResponse($response)
{
$this->responses[] = $response;
}
/**
* Sets the position of the response buffer. Selects which
* response will be returned on the next call to read().
*
* @param integer $index
*/
public function setResponseIndex($index)
{
if ($index < 0 || $index >= count($this->responses)) {
require_once 'Zend/Http/Client/Adapter/Exception.php';
throw new Zend_Http_Client_Adapter_Exception(
'Index out of range of response buffer size');
}
$this->responseIndex = $index;
}
}

View file

@ -0,0 +1,33 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Client_Exception
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Http/Exception.php';
/**
* @category Zend
* @package Zend_Http
* @subpackage Client
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Client_Exception extends Zend_Http_Exception
{}

327
Zend/Http/Cookie.php Normal file
View file

@ -0,0 +1,327 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to version 1.0 of the Zend Framework
* license, that is bundled with this package in the file LICENSE.txt,
* and is available through the world-wide-web at the following URL:
* http://framework.zend.com/license/new-bsd. If you did not
* receive a copy of the Zend Framework license and are unable to
* obtain it through the world-wide-web, please send a note to
* license@zend.com so we can mail you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Cookie
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
* @version $Id: Cookie.php 8064 2008-02-16 10:58:39Z thomas $
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Uri/Http.php';
/**
* Zend_Http_Cookie is a class describing an HTTP cookie and all it's parameters.
*
* Zend_Http_Cookie is a class describing an HTTP cookie and all it's parameters. The
* class also enables validating whether the cookie should be sent to the server in
* a specified scenario according to the request URI, the expiry time and whether
* session cookies should be used or not. Generally speaking cookies should be
* contained in a Cookiejar object, or instantiated manually and added to an HTTP
* request.
*
* See http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
*
* @category Zend
* @package Zend_Http
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Cookie
{
/**
* Cookie name
*
* @var string
*/
protected $name;
/**
* Cookie value
*
* @var string
*/
protected $value;
/**
* Cookie expiry date
*
* @var int
*/
protected $expires;
/**
* Cookie domain
*
* @var string
*/
protected $domain;
/**
* Cookie path
*
* @var string
*/
protected $path;
/**
* Whether the cookie is secure or not
*
* @var boolean
*/
protected $secure;
/**
* Cookie object constructor
*
* @todo Add validation of each one of the parameters (legal domain, etc.)
*
* @param string $name
* @param string $value
* @param int $expires
* @param string $domain
* @param string $path
* @param bool $secure
*/
public function __construct($name, $value, $domain, $expires = null, $path = null, $secure = false)
{
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})");
}
if (! $this->name = (string) $name) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('Cookies must have a name');
}
if (! $this->domain = (string) $domain) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('Cookies must have a domain');
}
$this->value = (string) $value;
$this->expires = ($expires === null ? null : (int) $expires);
$this->path = ($path ? $path : '/');
$this->secure = $secure;
}
/**
* Get Cookie name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Get cookie value
*
* @return string
*/
public function getValue()
{
return $this->value;
}
/**
* Get cookie domain
*
* @return string
*/
public function getDomain()
{
return $this->domain;
}
/**
* Get the cookie path
*
* @return string
*/
public function getPath()
{
return $this->path;
}
/**
* Get the expiry time of the cookie, or null if no expiry time is set
*
* @return int|null
*/
public function getExpiryTime()
{
return $this->expires;
}
/**
* Check whether the cookie should only be sent over secure connections
*
* @return boolean
*/
public function isSecure()
{
return $this->secure;
}
/**
* Check whether the cookie has expired
*
* Always returns false if the cookie is a session cookie (has no expiry time)
*
* @param int $now Timestamp to consider as "now"
* @return boolean
*/
public function isExpired($now = null)
{
if ($now === null) $now = time();
if (is_int($this->expires) && $this->expires < $now) {
return true;
} else {
return false;
}
}
/**
* Check whether the cookie is a session cookie (has no expiry time set)
*
* @return boolean
*/
public function isSessionCookie()
{
return ($this->expires === null);
}
/**
* Checks whether the cookie should be sent or not in a specific scenario
*
* @param string|Zend_Uri_Http $uri URI to check against (secure, domain, path)
* @param boolean $matchSessionCookies Whether to send session cookies
* @param int $now Override the current time when checking for expiry time
* @return boolean
*/
public function match($uri, $matchSessionCookies = true, $now = null)
{
if (is_string ($uri)) {
$uri = Zend_Uri_Http::factory($uri);
}
// Make sure we have a valid Zend_Uri_Http object
if (! ($uri->valid() && ($uri->getScheme() == 'http' || $uri->getScheme() =='https'))) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('Passed URI is not a valid HTTP or HTTPS URI');
}
// Check that the cookie is secure (if required) and not expired
if ($this->secure && $uri->getScheme() != 'https') return false;
if ($this->isExpired($now)) return false;
if ($this->isSessionCookie() && ! $matchSessionCookies) return false;
// Validate domain and path
// Domain is validated using tail match, while path is validated using head match
$domain_preg = preg_quote($this->getDomain(), "/");
if (! preg_match("/{$domain_preg}$/", $uri->getHost())) return false;
$path_preg = preg_quote($this->getPath(), "/");
if (! preg_match("/^{$path_preg}/", $uri->getPath())) return false;
// If we didn't die until now, return true.
return true;
}
/**
* Get the cookie as a string, suitable for sending as a "Cookie" header in an
* HTTP request
*
* @return string
*/
public function __toString()
{
return $this->name . '=' . urlencode($this->value) . ';';
}
/**
* Generate a new Cookie object from a cookie string
* (for example the value of the Set-Cookie HTTP header)
*
* @param string $cookieStr
* @param Zend_Uri_Http|string $ref_uri Reference URI for default values (domain, path)
* @return Zend_Http_Cookie A new Zend_Http_Cookie object or false on failure.
*/
public static function fromString($cookieStr, $ref_uri = null)
{
// Set default values
if (is_string($ref_uri)) {
$ref_uri = Zend_Uri_Http::factory($ref_uri);
}
$name = '';
$value = '';
$domain = '';
$path = '';
$expires = null;
$secure = false;
$parts = explode(';', $cookieStr);
// If first part does not include '=', fail
if (strpos($parts[0], '=') === false) return false;
// Get the name and value of the cookie
list($name, $value) = explode('=', trim(array_shift($parts)), 2);
$name = trim($name);
$value = urldecode(trim($value));
// Set default domain and path
if ($ref_uri instanceof Zend_Uri_Http) {
$domain = $ref_uri->getHost();
$path = $ref_uri->getPath();
$path = substr($path, 0, strrpos($path, '/'));
}
// Set other cookie parameters
foreach ($parts as $part) {
$part = trim($part);
if (strtolower($part) == 'secure') {
$secure = true;
continue;
}
$keyValue = explode('=', $part, 2);
if (count($keyValue) == 2) {
list($k, $v) = $keyValue;
switch (strtolower($k)) {
case 'expires':
$expires = strtotime($v);
break;
case 'path':
$path = $v;
break;
case 'domain':
$domain = $v;
break;
default:
break;
}
}
}
if ($name !== '') {
return new Zend_Http_Cookie($name, $value, $domain, $expires, $path, $secure);
} else {
return false;
}
}
}

350
Zend/Http/CookieJar.php Normal file
View file

@ -0,0 +1,350 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to version 1.0 of the Zend Framework
* license, that is bundled with this package in the file LICENSE.txt,
* and is available through the world-wide-web at the following URL:
* http://framework.zend.com/license/new-bsd. If you did not
* receive a copy of the Zend Framework license and are unable to
* obtain it through the world-wide-web, please send a note to
* license@zend.com so we can mail you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage CookieJar
* @version $Id: CookieJar.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once "Zend/Uri.php";
require_once "Zend/Http/Cookie.php";
require_once "Zend/Http/Response.php";
/**
* A Zend_Http_CookieJar object is designed to contain and maintain HTTP cookies, and should
* be used along with Zend_Http_Client in order to manage cookies across HTTP requests and
* responses.
*
* The class contains an array of Zend_Http_Cookie objects. Cookies can be added to the jar
* automatically from a request or manually. Then, the jar can find and return the cookies
* needed for a specific HTTP request.
*
* A special parameter can be passed to all methods of this class that return cookies: Cookies
* can be returned either in their native form (as Zend_Http_Cookie objects) or as strings -
* the later is suitable for sending as the value of the "Cookie" header in an HTTP request.
* You can also choose, when returning more than one cookie, whether to get an array of strings
* (by passing Zend_Http_CookieJar::COOKIE_STRING_ARRAY) or one unified string for all cookies
* (by passing Zend_Http_CookieJar::COOKIE_STRING_CONCAT).
*
* @link http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
*
* @category Zend
* @package Zend_Http
* @subpackage CookieJar
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com/)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_CookieJar
{
/**
* Return cookie(s) as a Zend_Http_Cookie object
*
*/
const COOKIE_OBJECT = 0;
/**
* Return cookie(s) as a string (suitable for sending in an HTTP request)
*
*/
const COOKIE_STRING_ARRAY = 1;
/**
* Return all cookies as one long string (suitable for sending in an HTTP request)
*
*/
const COOKIE_STRING_CONCAT = 2;
/**
* Array storing cookies
*
* Cookies are stored according to domain and path:
* $cookies
* + www.mydomain.com
* + /
* - cookie1
* - cookie2
* + /somepath
* - othercookie
* + www.otherdomain.net
* + /
* - alsocookie
*
* @var array
*/
protected $cookies = array();
/**
* Construct a new CookieJar object
*
*/
public function __construct()
{ }
/**
* Add a cookie to the jar. Cookie should be passed either as a Zend_Http_Cookie object
* or as a string - in which case an object is created from the string.
*
* @param Zend_Http_Cookie|string $cookie
* @param Zend_Uri_Http|string $ref_uri Optional reference URI (for domain, path, secure)
*/
public function addCookie($cookie, $ref_uri = null)
{
if (is_string($cookie)) {
$cookie = Zend_Http_Cookie::fromString($cookie, $ref_uri);
}
if ($cookie instanceof Zend_Http_Cookie) {
$domain = $cookie->getDomain();
$path = $cookie->getPath();
if (! isset($this->cookies[$domain])) $this->cookies[$domain] = array();
if (! isset($this->cookies[$domain][$path])) $this->cookies[$domain][$path] = array();
$this->cookies[$domain][$path][$cookie->getName()] = $cookie;
} else {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('Supplient argument is not a valid cookie string or object');
}
}
/**
* Parse an HTTP response, adding all the cookies set in that response
* to the cookie jar.
*
* @param Zend_Http_Response $response
* @param Zend_Uri_Http|string $ref_uri Requested URI
*/
public function addCookiesFromResponse($response, $ref_uri)
{
if (! $response instanceof Zend_Http_Response) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('$response is expected to be a Response object, ' .
gettype($response) . ' was passed');
}
$cookie_hdrs = $response->getHeader('Set-Cookie');
if (is_array($cookie_hdrs)) {
foreach ($cookie_hdrs as $cookie) {
$this->addCookie($cookie, $ref_uri);
}
} elseif (is_string($cookie_hdrs)) {
$this->addCookie($cookie_hdrs, $ref_uri);
}
}
/**
* Get all cookies in the cookie jar as an array
*
* @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings
* @return array|string
*/
public function getAllCookies($ret_as = self::COOKIE_OBJECT)
{
$cookies = $this->_flattenCookiesArray($this->cookies, $ret_as);
return $cookies;
}
/**
* Return an array of all cookies matching a specific request according to the request URI,
* whether session cookies should be sent or not, and the time to consider as "now" when
* checking cookie expiry time.
*
* @param string|Zend_Uri_Http $uri URI to check against (secure, domain, path)
* @param boolean $matchSessionCookies Whether to send session cookies
* @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings
* @param int $now Override the current time when checking for expiry time
* @return array|string
*/
public function getMatchingCookies($uri, $matchSessionCookies = true,
$ret_as = self::COOKIE_OBJECT, $now = null)
{
if (is_string($uri)) $uri = Zend_Uri::factory($uri);
if (! $uri instanceof Zend_Uri_Http) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception("Invalid URI string or object passed");
}
// Set path
$path = $uri->getPath();
$path = substr($path, 0, strrpos($path, '/'));
if (! $path) $path = '/';
// First, reduce the array of cookies to only those matching domain and path
$cookies = $this->_matchDomain($uri->getHost());
$cookies = $this->_matchPath($cookies, $path);
$cookies = $this->_flattenCookiesArray($cookies, self::COOKIE_OBJECT);
// Next, run Cookie->match on all cookies to check secure, time and session mathcing
$ret = array();
foreach ($cookies as $cookie)
if ($cookie->match($uri, $matchSessionCookies, $now))
$ret[] = $cookie;
// Now, use self::_flattenCookiesArray again - only to convert to the return format ;)
$ret = $this->_flattenCookiesArray($ret, $ret_as);
return $ret;
}
/**
* Get a specific cookie according to a URI and name
*
* @param Zend_Uri_Http|string $uri The uri (domain and path) to match
* @param string $cookie_name The cookie's name
* @param int $ret_as Whether to return cookies as objects of Zend_Http_Cookie or as strings
* @return Zend_Http_Cookie|string
*/
public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT)
{
if (is_string($uri)) {
$uri = Zend_Uri::factory($uri);
}
if (! $uri instanceof Zend_Uri_Http) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('Invalid URI specified');
}
// Get correct cookie path
$path = $uri->getPath();
$path = substr($path, 0, strrpos($path, '/'));
if (! $path) $path = '/';
if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) {
$cookie = $this->cookies[$uri->getHost()][$path][$cookie_name];
switch ($ret_as) {
case self::COOKIE_OBJECT:
return $cookie;
break;
case self::COOKIE_STRING_ARRAY:
case self::COOKIE_STRING_CONCAT:
return $cookie->__toString();
break;
default:
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception("Invalid value passed for \$ret_as: {$ret_as}");
break;
}
} else {
return false;
}
}
/**
* Helper function to recursivly flatten an array. Shoud be used when exporting the
* cookies array (or parts of it)
*
* @param Zend_Http_Cookie|array $ptr
* @param int $ret_as What value to return
* @return array|string
*/
protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) {
if (is_array($ptr)) {
$ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array());
foreach ($ptr as $item) {
if ($ret_as == self::COOKIE_STRING_CONCAT) {
$ret .= $this->_flattenCookiesArray($item, $ret_as);
} else {
$ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as));
}
}
return $ret;
} elseif ($ptr instanceof Zend_Http_Cookie) {
switch ($ret_as) {
case self::COOKIE_STRING_ARRAY:
return array($ptr->__toString());
break;
case self::COOKIE_STRING_CONCAT:
return $ptr->__toString();
break;
case self::COOKIE_OBJECT:
default:
return array($ptr);
break;
}
}
return null;
}
/**
* Return a subset of the cookies array matching a specific domain
*
* Returned array is actually an array of pointers to items in the $this->cookies array.
*
* @param string $domain
* @return array
*/
protected function _matchDomain($domain) {
$ret = array();
foreach (array_keys($this->cookies) as $cdom) {
$regex = "/" . preg_quote($cdom, "/") . "$/i";
if (preg_match($regex, $domain)) $ret[$cdom] = &$this->cookies[$cdom];
}
return $ret;
}
/**
* Return a subset of a domain-matching cookies that also match a specified path
*
* Returned array is actually an array of pointers to items in the $passed array.
*
* @param array $dom_array
* @param string $path
* @return array
*/
protected function _matchPath($domains, $path) {
$ret = array();
if (substr($path, -1) != '/') $path .= '/';
foreach ($domains as $dom => $paths_array) {
foreach (array_keys($paths_array) as $cpath) {
$regex = "|^" . preg_quote($cpath, "|") . "|i";
if (preg_match($regex, $path)) {
if (! isset($ret[$dom])) $ret[$dom] = array();
$ret[$dom][$cpath] = &$paths_array[$cpath];
}
}
}
return $ret;
}
/**
* Create a new CookieJar object and automatically load into it all the
* cookies set in an Http_Response object. If $uri is set, it will be
* considered as the requested URI for setting default domain and path
* of the cookie.
*
* @param Zend_Http_Response $response HTTP Response object
* @param Zend_Uri_Http|string $uri The requested URI
* @return Zend_Http_CookieJar
* @todo Add the $uri functionality.
*/
public static function fromResponse(Zend_Http_Response $response, $ref_uri)
{
$jar = new self();
$jar->addCookiesFromResponse($response, $ref_uri);
return $jar;
}
}

33
Zend/Http/Exception.php Normal file
View file

@ -0,0 +1,33 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Exception
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
require_once 'Zend/Exception.php';
/**
* @category Zend
* @package Zend_Http
* @subpackage Client
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Exception extends Zend_Exception
{}

625
Zend/Http/Response.php Normal file
View file

@ -0,0 +1,625 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Http
* @subpackage Response
* @version $Id: Response.php 8064 2008-02-16 10:58:39Z thomas $
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* Zend_Http_Response represents an HTTP 1.0 / 1.1 response message. It
* includes easy access to all the response's different elemts, as well as some
* convenience methods for parsing and validating HTTP responses.
*
* @package Zend_Http
* @subpackage Response
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Http_Response
{
/**
* List of all known HTTP response codes - used by responseCodeAsText() to
* translate numeric codes to messages.
*
* @var array
*/
protected static $messages = array(
// Informational 1xx
100 => 'Continue',
101 => 'Switching Protocols',
// Success 2xx
200 => 'OK',
201 => 'Created',
202 => 'Accepted',
203 => 'Non-Authoritative Information',
204 => 'No Content',
205 => 'Reset Content',
206 => 'Partial Content',
// Redirection 3xx
300 => 'Multiple Choices',
301 => 'Moved Permanently',
302 => 'Found', // 1.1
303 => 'See Other',
304 => 'Not Modified',
305 => 'Use Proxy',
// 306 is deprecated but reserved
307 => 'Temporary Redirect',
// Client Error 4xx
400 => 'Bad Request',
401 => 'Unauthorized',
402 => 'Payment Required',
403 => 'Forbidden',
404 => 'Not Found',
405 => 'Method Not Allowed',
406 => 'Not Acceptable',
407 => 'Proxy Authentication Required',
408 => 'Request Timeout',
409 => 'Conflict',
410 => 'Gone',
411 => 'Length Required',
412 => 'Precondition Failed',
413 => 'Request Entity Too Large',
414 => 'Request-URI Too Long',
415 => 'Unsupported Media Type',
416 => 'Requested Range Not Satisfiable',
417 => 'Expectation Failed',
// Server Error 5xx
500 => 'Internal Server Error',
501 => 'Not Implemented',
502 => 'Bad Gateway',
503 => 'Service Unavailable',
504 => 'Gateway Timeout',
505 => 'HTTP Version Not Supported',
509 => 'Bandwidth Limit Exceeded'
);
/**
* The HTTP version (1.0, 1.1)
*
* @var string
*/
protected $version;
/**
* The HTTP response code
*
* @var int
*/
protected $code;
/**
* The HTTP response code as string
* (e.g. 'Not Found' for 404 or 'Internal Server Error' for 500)
*
* @var string
*/
protected $message;
/**
* The HTTP response headers array
*
* @var array
*/
protected $headers = array();
/**
* The HTTP response body
*
* @var string
*/
protected $body;
/**
* HTTP response constructor
*
* In most cases, you would use Zend_Http_Response::fromString to parse an HTTP
* response string and create a new Zend_Http_Response object.
*
* NOTE: The constructor no longer accepts nulls or empty values for the code and
* headers and will throw an exception if the passed values do not form a valid HTTP
* responses.
*
* If no message is passed, the message will be guessed according to the response code.
*
* @param int $code Response code (200, 404, ...)
* @param array $headers Headers array
* @param string $body Response body
* @param string $version HTTP version
* @param string $message Response code as text
* @throws Zend_Http_Exception
*/
public function __construct($code, $headers, $body = null, $version = '1.1', $message = null)
{
// Make sure the response code is valid and set it
if (self::responseCodeAsText($code) === null) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception("{$code} is not a valid HTTP response code");
}
$this->code = $code;
// Make sure we got valid headers and set them
if (! is_array($headers)) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('No valid headers were passed');
}
foreach ($headers as $name => $value) {
if (is_int($name))
list($name, $value) = explode(": ", $value, 1);
$this->headers[ucwords(strtolower($name))] = $value;
}
// Set the body
$this->body = $body;
// Set the HTTP version
if (! preg_match('|^\d\.\d$|', $version)) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception("Invalid HTTP response version: $version");
}
$this->version = $version;
// If we got the response message, set it. Else, set it according to
// the response code
if (is_string($message)) {
$this->message = $message;
} else {
$this->message = self::responseCodeAsText($code);
}
}
/**
* Check whether the response is an error
*
* @return boolean
*/
public function isError()
{
$restype = floor($this->code / 100);
if ($restype == 4 || $restype == 5) {
return true;
}
return false;
}
/**
* Check whether the response in successful
*
* @return boolean
*/
public function isSuccessful()
{
$restype = floor($this->code / 100);
if ($restype == 2 || $restype == 1) { // Shouldn't 3xx count as success as well ???
return true;
}
return false;
}
/**
* Check whether the response is a redirection
*
* @return boolean
*/
public function isRedirect()
{
$restype = floor($this->code / 100);
if ($restype == 3) {
return true;
}
return false;
}
/**
* Get the response body as string
*
* This method returns the body of the HTTP response (the content), as it
* should be in it's readable version - that is, after decoding it (if it
* was decoded), deflating it (if it was gzip compressed), etc.
*
* If you want to get the raw body (as transfered on wire) use
* $this->getRawBody() instead.
*
* @return string
*/
public function getBody()
{
$body = '';
// Decode the body if it was transfer-encoded
switch ($this->getHeader('transfer-encoding')) {
// Handle chunked body
case 'chunked':
$body = self::decodeChunkedBody($this->body);
break;
// No transfer encoding, or unknown encoding extension:
// return body as is
default:
$body = $this->body;
break;
}
// Decode any content-encoding (gzip or deflate) if needed
switch (strtolower($this->getHeader('content-encoding'))) {
// Handle gzip encoding
case 'gzip':
$body = self::decodeGzip($body);
break;
// Handle deflate encoding
case 'deflate':
$body = self::decodeDeflate($body);
break;
default:
break;
}
return $body;
}
/**
* Get the raw response body (as transfered "on wire") as string
*
* If the body is encoded (with Transfer-Encoding, not content-encoding -
* IE "chunked" body), gzip compressed, etc. it will not be decoded.
*
* @return string
*/
public function getRawBody()
{
return $this->body;
}
/**
* Get the HTTP version of the response
*
* @return string
*/
public function getVersion()
{
return $this->version;
}
/**
* Get the HTTP response status code
*
* @return int
*/
public function getStatus()
{
return $this->code;
}
/**
* Return a message describing the HTTP response code
* (Eg. "OK", "Not Found", "Moved Permanently")
*
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Get the response headers
*
* @return array
*/
public function getHeaders()
{
return $this->headers;
}
/**
* Get a specific header as string, or null if it is not set
*
* @param string$header
* @return string|array|null
*/
public function getHeader($header)
{
$header = ucwords(strtolower($header));
if (! is_string($header) || ! isset($this->headers[$header])) return null;
return $this->headers[$header];
}
/**
* Get all headers as string
*
* @param boolean $status_line Whether to return the first status line (IE "HTTP 200 OK")
* @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
* @return string
*/
public function getHeadersAsString($status_line = true, $br = "\n")
{
$str = '';
if ($status_line) {
$str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}";
}
// Iterate over the headers and stringify them
foreach ($this->headers as $name => $value)
{
if (is_string($value))
$str .= "{$name}: {$value}{$br}";
elseif (is_array($value)) {
foreach ($value as $subval) {
$str .= "{$name}: {$subval}{$br}";
}
}
}
return $str;
}
/**
* Get the entire response as string
*
* @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
* @return string
*/
public function asString($br = "\n")
{
return $this->getHeadersAsString(true, $br) . $br . $this->getBody();
}
/**
* A convenience function that returns a text representation of
* HTTP response codes. Returns 'Unknown' for unknown codes.
* Returns array of all codes, if $code is not specified.
*
* Conforms to HTTP/1.1 as defined in RFC 2616 (except for 'Unknown')
* See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 for reference
*
* @param int $code HTTP response code
* @param boolean $http11 Use HTTP version 1.1
* @return string
*/
public static function responseCodeAsText($code = null, $http11 = true)
{
$messages = self::$messages;
if (! $http11) $messages[302] = 'Moved Temporarily';
if ($code === null) {
return $messages;
} elseif (isset($messages[$code])) {
return $messages[$code];
} else {
return 'Unknown';
}
}
/**
* Extract the response code from a response string
*
* @param string $response_str
* @return int
*/
public static function extractCode($response_str)
{
preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m);
if (isset($m[1])) {
return (int) $m[1];
} else {
return false;
}
}
/**
* Extract the HTTP message from a response
*
* @param string $response_str
* @return string
*/
public static function extractMessage($response_str)
{
preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m);
if (isset($m[1])) {
return $m[1];
} else {
return false;
}
}
/**
* Extract the HTTP version from a response
*
* @param string $response_str
* @return string
*/
public static function extractVersion($response_str)
{
preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m);
if (isset($m[1])) {
return $m[1];
} else {
return false;
}
}
/**
* Extract the headers from a response string
*
* @param string $response_str
* @return array
*/
public static function extractHeaders($response_str)
{
$headers = array();
// First, split body and headers
$parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
if (! $parts[0]) return $headers;
// Split headers part to lines
$lines = explode("\n", $parts[0]);
unset($parts);
$last_header = null;
foreach($lines as $line) {
$line = trim($line, "\r\n");
if ($line == "") break;
if (preg_match("|^([\w-]+):\s+(.+)|", $line, $m)) {
unset($last_header);
$h_name = strtolower($m[1]);
$h_value = $m[2];
if (isset($headers[$h_name])) {
if (! is_array($headers[$h_name])) {
$headers[$h_name] = array($headers[$h_name]);
}
$headers[$h_name][] = $h_value;
} else {
$headers[$h_name] = $h_value;
}
$last_header = $h_name;
} elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) {
if (is_array($headers[$last_header])) {
end($headers[$last_header]);
$last_header_key = key($headers[$last_header]);
$headers[$last_header][$last_header_key] .= $m[1];
} else {
$headers[$last_header] .= $m[1];
}
}
}
return $headers;
}
/**
* Extract the body from a response string
*
* @param string $response_str
* @return string
*/
public static function extractBody($response_str)
{
$parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
if (isset($parts[1])) {
return $parts[1];
} else {
return '';
}
}
/**
* Decode a "chunked" transfer-encoded body and return the decoded text
*
* @param string $body
* @return string
*/
public static function decodeChunkedBody($body)
{
$decBody = '';
while (trim($body)) {
if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception("Error parsing body - doesn't seem to be a chunked message");
}
$length = hexdec(trim($m[1]));
$cut = strlen($m[0]);
$decBody .= substr($body, $cut, $length);
$body = substr($body, $cut + $length + 2);
}
return $decBody;
}
/**
* Decode a gzip encoded message (when Content-encoding = gzip)
*
* Currently requires PHP with zlib support
*
* @param string $body
* @return string
*/
public static function decodeGzip($body)
{
if (! function_exists('gzinflate')) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('Unable to decode gzipped response ' .
'body: perhaps the zlib extension is not loaded?');
}
return gzinflate(substr($body, 10));
}
/**
* Decode a zlib deflated message (when Content-encoding = deflate)
*
* Currently requires PHP with zlib support
*
* @param string $body
* @return string
*/
public static function decodeDeflate($body)
{
if (! function_exists('gzuncompress')) {
require_once 'Zend/Http/Exception.php';
throw new Zend_Http_Exception('Unable to decode deflated response ' .
'body: perhaps the zlib extension is not loaded?');
}
return gzuncompress($body);
}
/**
* Create a new Zend_Http_Response object from a string
*
* @param string $response_str
* @return Zend_Http_Response
*/
public static function fromString($response_str)
{
$code = self::extractCode($response_str);
$headers = self::extractHeaders($response_str);
$body = self::extractBody($response_str);
$version = self::extractVersion($response_str);
$message = self::extractMessage($response_str);
return new Zend_Http_Response($code, $headers, $body, $version, $message);
}
}

258
Zend/Loader.php Normal file
View file

@ -0,0 +1,258 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Loader
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Loader.php 8906 2008-03-19 19:15:30Z darby $
*/
/**
* Static methods for loading classes and files.
*
* @category Zend
* @package Zend_Loader
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Loader
{
/**
* Loads a class from a PHP file. The filename must be formatted
* as "$class.php".
*
* If $dirs is a string or an array, it will search the directories
* in the order supplied, and attempt to load the first matching file.
*
* If $dirs is null, it will split the class name at underscores to
* generate a path hierarchy (e.g., "Zend_Example_Class" will map
* to "Zend/Example/Class.php").
*
* If the file was not found in the $dirs, or if no $dirs were specified,
* it will attempt to load it from PHP's include_path.
*
* @param string $class - The full class name of a Zend component.
* @param string|array $dirs - OPTIONAL Either a path or an array of paths
* to search.
* @return void
* @throws Zend_Exception
*/
public static function loadClass($class, $dirs = null)
{
if (class_exists($class, false) || interface_exists($class, false)) {
return;
}
if ((null !== $dirs) && !is_string($dirs) && !is_array($dirs)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception('Directory argument must be a string or an array');
}
// autodiscover the path from the class name
$file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
if (!empty($dirs)) {
// use the autodiscovered path
$dirPath = dirname($file);
if (is_string($dirs)) {
$dirs = explode(PATH_SEPARATOR, $dirs);
}
foreach ($dirs as $key => $dir) {
if ($dir == '.') {
$dirs[$key] = $dirPath;
} else {
$dir = rtrim($dir, '\\/');
$dirs[$key] = $dir . DIRECTORY_SEPARATOR . $dirPath;
}
}
$file = basename($file);
self::loadFile($file, $dirs, true);
} else {
self::_securityCheck($file);
include_once $file;
}
if (!class_exists($class, false) && !interface_exists($class, false)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception("File \"$file\" does not exist or class \"$class\" was not found in the file");
}
}
/**
* Loads a PHP file. This is a wrapper for PHP's include() function.
*
* $filename must be the complete filename, including any
* extension such as ".php". Note that a security check is performed that
* does not permit extended characters in the filename. This method is
* intended for loading Zend Framework files.
*
* If $dirs is a string or an array, it will search the directories
* in the order supplied, and attempt to load the first matching file.
*
* If the file was not found in the $dirs, or if no $dirs were specified,
* it will attempt to load it from PHP's include_path.
*
* If $once is TRUE, it will use include_once() instead of include().
*
* @param string $filename
* @param string|array $dirs - OPTIONAL either a path or array of paths
* to search.
* @param boolean $once
* @return boolean
* @throws Zend_Exception
*/
public static function loadFile($filename, $dirs = null, $once = false)
{
self::_securityCheck($filename);
/**
* Search in provided directories, as well as include_path
*/
$incPath = false;
if (!empty($dirs) && (is_array($dirs) || is_string($dirs))) {
if (is_array($dirs)) {
$dirs = implode(PATH_SEPARATOR, $dirs);
}
$incPath = get_include_path();
set_include_path($dirs . PATH_SEPARATOR . $incPath);
}
/**
* Try finding for the plain filename in the include_path.
*/
if ($once) {
include_once $filename;
} else {
include $filename;
}
/**
* If searching in directories, reset include_path
*/
if ($incPath) {
set_include_path($incPath);
}
return true;
}
/**
* Returns TRUE if the $filename is readable, or FALSE otherwise.
* This function uses the PHP include_path, where PHP's is_readable()
* does not.
*
* @param string $filename
* @return boolean
*/
public static function isReadable($filename)
{
if (!$fh = @fopen($filename, 'r', true)) {
return false;
}
return true;
}
/**
* spl_autoload() suitable implementation for supporting class autoloading.
*
* Attach to spl_autoload() using the following:
* <code>
* spl_autoload_register(array('Zend_Loader', 'autoload'));
* </code>
*
* @param string $class
* @return string|false Class name on success; false on failure
*/
public static function autoload($class)
{
try {
self::loadClass($class);
return $class;
} catch (Exception $e) {
return false;
}
}
/**
* Register {@link autoload()} with spl_autoload()
*
* @param string $class (optional)
* @param boolean $enabled (optional)
* @return void
* @throws Zend_Exception if spl_autoload() is not found
* or if the specified class does not have an autoload() method.
*/
public static function registerAutoload($class = 'Zend_Loader', $enabled = true)
{
if (!function_exists('spl_autoload_register')) {
require_once 'Zend/Exception.php';
throw new Zend_Exception('spl_autoload does not exist in this PHP installation');
}
self::loadClass($class);
$methods = get_class_methods($class);
if (!in_array('autoload', (array) $methods)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception("The class \"$class\" does not have an autoload() method");
}
if ($enabled === true) {
spl_autoload_register(array($class, 'autoload'));
} else {
spl_autoload_unregister(array($class, 'autoload'));
}
}
/**
* Ensure that filename does not contain exploits
*
* @param string $filename
* @return void
* @throws Zend_Exception
*/
protected static function _securityCheck($filename)
{
/**
* Security check
*/
if (preg_match('/[^a-z0-9\\/\\\\_.-]/i', $filename)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception('Security check: Illegal character in filename');
}
}
/**
* Attempt to include() the file.
*
* include() is not prefixed with the @ operator because if
* the file is loaded and contains a parse error, execution
* will halt silently and this is difficult to debug.
*
* Always set display_errors = Off on production servers!
*
* @param string $filespec
* @param boolean $once
* @return boolean
* @deprecated Since 1.5.0; use loadFile() instead
*/
protected static function _includeFile($filespec, $once = false)
{
if ($once) {
return include_once $filespec;
} else {
return include $filespec ;
}
}
}

195
Zend/Registry.php Normal file
View file

@ -0,0 +1,195 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Registry
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Registry.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* Generic storage class helps to manage global data.
*
* @category Zend
* @package Zend_Registry
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Registry extends ArrayObject
{
/**
* Class name of the singleton registry object.
* @var string
*/
private static $_registryClassName = 'Zend_Registry';
/**
* Registry object provides storage for shared objects.
* @var Zend_Registry
*/
private static $_registry = null;
/**
* Retrieves the default registry instance.
*
* @return Zend_Registry
*/
public static function getInstance()
{
if (self::$_registry === null) {
self::init();
}
return self::$_registry;
}
/**
* Set the default registry instance to a specified instance.
*
* @param Zend_Registry $registry An object instance of type Zend_Registry,
* or a subclass.
* @return void
* @throws Zend_Exception if registry is already initialized.
*/
public static function setInstance(Zend_Registry $registry)
{
if (self::$_registry !== null) {
require_once 'Zend/Exception.php';
throw new Zend_Exception('Registry is already initialized');
}
self::setClassName(get_class($registry));
self::$_registry = $registry;
}
/**
* Initialize the default registry instance.
*
* @return void
*/
protected static function init()
{
self::setInstance(new self::$_registryClassName());
}
/**
* Set the class name to use for the default registry instance.
* Does not affect the currently initialized instance, it only applies
* for the next time you instantiate.
*
* @param string $registryClassName
* @return void
* @throws Zend_Exception if the registry is initialized or if the
* class name is not valid.
*/
public static function setClassName($registryClassName = 'Zend_Registry')
{
if (self::$_registry !== null) {
require_once 'Zend/Exception.php';
throw new Zend_Exception('Registry is already initialized');
}
if (!is_string($registryClassName)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception("Argument is not a class name");
}
/**
* @see Zend_Loader
*/
require_once 'Zend/Loader.php';
Zend_Loader::loadClass($registryClassName);
self::$_registryClassName = $registryClassName;
}
/**
* Unset the default registry instance.
* Primarily used in tearDown() in unit tests.
* @returns void
*/
public static function _unsetInstance()
{
self::$_registry = null;
}
/**
* getter method, basically same as offsetGet().
*
* This method can be called from an object of type Zend_Registry, or it
* can be called statically. In the latter case, it uses the default
* static instance stored in the class.
*
* @param string $index - get the value associated with $index
* @return mixed
* @throws Zend_Exception if no entry is registerd for $index.
*/
public static function get($index)
{
$instance = self::getInstance();
if (!$instance->offsetExists($index)) {
require_once 'Zend/Exception.php';
throw new Zend_Exception("No entry is registered for key '$index'");
}
return $instance->offsetGet($index);
}
/**
* setter method, basically same as offsetSet().
*
* This method can be called from an object of type Zend_Registry, or it
* can be called statically. In the latter case, it uses the default
* static instance stored in the class.
*
* @param string $index The location in the ArrayObject in which to store
* the value.
* @param mixed $value The object to store in the ArrayObject.
* @return void
*/
public static function set($index, $value)
{
$instance = self::getInstance();
$instance->offsetSet($index, $value);
}
/**
* Returns TRUE if the $index is a named value in the registry,
* or FALSE if $index was not found in the registry.
*
* @param string $index
* @return boolean
*/
public static function isRegistered($index)
{
if (self::$_registry === null) {
return false;
}
return self::$_registry->offsetExists($index);
}
/**
* @param string $index
* @returns mixed
*
* Workaround for http://bugs.php.net/bug.php?id=40442 (ZF-960).
*/
public function offsetExists($index)
{
return array_key_exists($index, $this);
}
}

158
Zend/Uri.php Normal file
View file

@ -0,0 +1,158 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Uri
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Uri.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Loader
*/
require_once 'Zend/Loader.php';
/**
* @category Zend
* @package Zend_Uri
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Uri
{
/**
* Scheme of this URI (http, ftp, etc.)
* @var string
*/
protected $_scheme = '';
/**
* Return a string representation of this URI.
*
* @see getUri()
* @return string
*/
public function __toString()
{
return $this->getUri();
}
/**
* Convenience function, checks that a $uri string is well-formed
* by validating it but not returning an object. Returns TRUE if
* $uri is a well-formed URI, or FALSE otherwise.
*
* @param string $uri
* @return boolean
*/
public static function check($uri)
{
try {
$uri = self::factory($uri);
} catch (Exception $e) {
return false;
}
return $uri->valid();
}
/**
* Create a new Zend_Uri object for a URI. If building a new URI, then $uri should contain
* only the scheme (http, ftp, etc). Otherwise, supply $uri with the complete URI.
*
* @param string $uri
* @throws Zend_Uri_Exception
* @return Zend_Uri
*/
public static function factory($uri = 'http')
{
/**
* Separate the scheme from the scheme-specific parts
* @link http://www.faqs.org/rfcs/rfc2396.html
*/
$uri = explode(':', $uri, 2);
$scheme = strtolower($uri[0]);
$schemeSpecific = isset($uri[1]) ? $uri[1] : '';
if (!strlen($scheme)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('An empty string was supplied for the scheme');
}
// Security check: $scheme is used to load a class file, so only alphanumerics are allowed.
if (!ctype_alnum($scheme)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted');
}
/**
* Create a new Zend_Uri object for the $uri. If a subclass of Zend_Uri exists for the
* scheme, return an instance of that class. Otherwise, a Zend_Uri_Exception is thrown.
*/
switch ($scheme) {
case 'http':
case 'https':
$className = 'Zend_Uri_Http';
break;
case 'mailto':
// @todo
default:
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("Scheme \"$scheme\" is not supported");
}
Zend_Loader::loadClass($className);
return new $className($scheme, $schemeSpecific);
}
/**
* Get the URI's scheme
*
* @return string|false Scheme or false if no scheme is set.
*/
public function getScheme()
{
if (!empty($this->_scheme)) {
return $this->_scheme;
} else {
return false;
}
}
/******************************************************************************
* Abstract Methods
*****************************************************************************/
/**
* Zend_Uri and its subclasses cannot be instantiated directly.
* Use Zend_Uri::factory() to return a new Zend_Uri object.
*/
abstract protected function __construct($scheme, $schemeSpecific = '');
/**
* Return a string representation of this URI.
*
* @return string
*/
abstract public function getUri();
/**
* Returns TRUE if this URI is valid, or FALSE otherwise.
*
* @return boolean
*/
abstract public function valid();
}

36
Zend/Uri/Exception.php Normal file
View file

@ -0,0 +1,36 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Uri
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
/**
* @see Zend_Exception
*/
require_once 'Zend/Exception.php';
/**
* @category Zend
* @package Zend_Uri
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Uri_Exception extends Zend_Exception
{}

631
Zend/Uri/Http.php Normal file
View file

@ -0,0 +1,631 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Uri
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Http.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Uri
*/
require_once 'Zend/Uri.php';
/**
* @see Zend_Validate_Hostname
*/
require_once 'Zend/Validate/Hostname.php';
/**
* @category Zend
* @package Zend_Uri
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Uri_Http extends Zend_Uri
{
/**
* URI parts are divided among these instance variables
*/
protected $_username = '';
protected $_password = '';
protected $_host = '';
protected $_port = '';
protected $_path = '';
protected $_query = '';
protected $_fragment = '';
/**
* Regular expression grammar rules for validation; values added by constructor
*/
protected $_regex = array();
/**
* Constructor accepts a string $scheme (e.g., http, https) and a scheme-specific part of the URI
* (e.g., example.com/path/to/resource?query=param#fragment)
*
* @param string $scheme
* @param string $schemeSpecific
* @throws Zend_Uri_Exception
* @return void
*/
protected function __construct($scheme, $schemeSpecific = '')
{
// Set the scheme
$this->_scheme = $scheme;
// Set up grammar rules for validation via regular expressions. These
// are to be used with slash-delimited regular expression strings.
$this->_regex['alphanum'] = '[^\W_]';
$this->_regex['escaped'] = '(?:%[\da-fA-F]{2})';
$this->_regex['mark'] = '[-_.!~*\'()\[\]]';
$this->_regex['reserved'] = '[;\/?:@&=+$,]';
$this->_regex['unreserved'] = '(?:' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . ')';
$this->_regex['segment'] = '(?:(?:' . $this->_regex['unreserved'] . '|' . $this->_regex['escaped']
. '|[:@&=+$,;])*)';
$this->_regex['path'] = '(?:\/' . $this->_regex['segment'] . '?)+';
$this->_regex['uric'] = '(?:' . $this->_regex['reserved'] . '|' . $this->_regex['unreserved'] . '|'
. $this->_regex['escaped'] . ')';
// If no scheme-specific part was supplied, the user intends to create
// a new URI with this object. No further parsing is required.
if (strlen($schemeSpecific) == 0) {
return;
}
// Parse the scheme-specific URI parts into the instance variables.
$this->_parseUri($schemeSpecific);
// Validate the URI
if (!$this->valid()) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Invalid URI supplied');
}
}
/**
* Parse the scheme-specific portion of the URI and place its parts into instance variables.
*
* @param string $schemeSpecific
* @throws Zend_Uri_Exception
* @return void
*/
protected function _parseUri($schemeSpecific)
{
// High-level decomposition parser
$pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~';
$status = @preg_match($pattern, $schemeSpecific, $matches);
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: scheme-specific decomposition failed');
}
// Failed decomposition; no further processing needed
if (!$status) {
return;
}
// Save URI components that need no further decomposition
$this->_path = isset($matches[4]) ? $matches[4] : '';
$this->_query = isset($matches[6]) ? $matches[6] : '';
$this->_fragment = isset($matches[8]) ? $matches[8] : '';
// Additional decomposition to get username, password, host, and port
$combo = isset($matches[3]) ? $matches[3] : '';
$pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~';
$status = @preg_match($pattern, $combo, $matches);
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: authority decomposition failed');
}
// Failed decomposition; no further processing needed
if (!$status) {
return;
}
// Save remaining URI components
$this->_username = isset($matches[2]) ? $matches[2] : '';
$this->_password = isset($matches[4]) ? $matches[4] : '';
$this->_host = isset($matches[5]) ? $matches[5] : '';
$this->_port = isset($matches[7]) ? $matches[7] : '';
}
/**
* Returns a URI based on current values of the instance variables. If any
* part of the URI does not pass validation, then an exception is thrown.
*
* @throws Zend_Uri_Exception
* @return string
*/
public function getUri()
{
if (!$this->valid()) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('One or more parts of the URI are invalid');
}
$password = strlen($this->_password) ? ":$this->_password" : '';
$auth = strlen($this->_username) ? "$this->_username$password@" : '';
$port = strlen($this->_port) ? ":$this->_port" : '';
$query = strlen($this->_query) ? "?$this->_query" : '';
$fragment = strlen($this->_fragment) ? "#$this->_fragment" : '';
return "$this->_scheme://$auth$this->_host$port$this->_path$query$fragment";
}
/**
* Validate the current URI from the instance variables. Returns true if and only if all
* parts pass validation.
*
* @return boolean
*/
public function valid()
{
/**
* Return true if and only if all parts of the URI have passed validation
*/
return $this->validateUsername()
&& $this->validatePassword()
&& $this->validateHost()
&& $this->validatePort()
&& $this->validatePath()
&& $this->validateQuery()
&& $this->validateFragment();
}
/**
* Returns the username portion of the URL, or FALSE if none.
*
* @return string
*/
public function getUsername()
{
return strlen($this->_username) ? $this->_username : false;
}
/**
* Returns true if and only if the username passes validation. If no username is passed,
* then the username contained in the instance variable is used.
*
* @param string $username
* @throws Zend_Uri_Exception
* @return boolean
*/
public function validateUsername($username = null)
{
if ($username === null) {
$username = $this->_username;
}
// If the username is empty, then it is considered valid
if (strlen($username) == 0) {
return true;
}
/**
* Check the username against the allowed values
*
* @link http://www.faqs.org/rfcs/rfc2396.html
*/
$status = @preg_match('/^(' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . '|'
. $this->_regex['escaped'] . '|[;:&=+$,])+$/', $username);
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: username validation failed');
}
return $status == 1;
}
/**
* Sets the username for the current URI, and returns the old username
*
* @param string $username
* @throws Zend_Uri_Exception
* @return string
*/
public function setUsername($username)
{
if (!$this->validateUsername($username)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("Username \"$username\" is not a valid HTTP username");
}
$oldUsername = $this->_username;
$this->_username = $username;
return $oldUsername;
}
/**
* Returns the password portion of the URL, or FALSE if none.
*
* @return string
*/
public function getPassword()
{
return strlen($this->_password) ? $this->_password : false;
}
/**
* Returns true if and only if the password passes validation. If no password is passed,
* then the password contained in the instance variable is used.
*
* @param string $password
* @throws Zend_Uri_Exception
* @return boolean
*/
public function validatePassword($password = null)
{
if ($password === null) {
$password = $this->_password;
}
// If the password is empty, then it is considered valid
if (strlen($password) == 0) {
return true;
}
// If the password is nonempty, but there is no username, then it is considered invalid
if (strlen($password) > 0 && strlen($this->_username) == 0) {
return false;
}
/**
* Check the password against the allowed values
*
* @link http://www.faqs.org/rfcs/rfc2396.html
*/
$status = @preg_match('/^(' . $this->_regex['alphanum'] . '|' . $this->_regex['mark'] . '|'
. $this->_regex['escaped'] . '|[;:&=+$,])+$/', $password);
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: password validation failed.');
}
return $status == 1;
}
/**
* Sets the password for the current URI, and returns the old password
*
* @param string $password
* @throws Zend_Uri_Exception
* @return string
*/
public function setPassword($password)
{
if (!$this->validatePassword($password)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("Password \"$password\" is not a valid HTTP password.");
}
$oldPassword = $this->_password;
$this->_password = $password;
return $oldPassword;
}
/**
* Returns the domain or host IP portion of the URL, or FALSE if none.
*
* @return string
*/
public function getHost()
{
return strlen($this->_host) ? $this->_host : false;
}
/**
* Returns true if and only if the host string passes validation. If no host is passed,
* then the host contained in the instance variable is used.
*
* @param string $host
* @return boolean
* @uses Zend_Filter
*/
public function validateHost($host = null)
{
if ($host === null) {
$host = $this->_host;
}
/**
* If the host is empty, then it is considered invalid
*/
if (strlen($host) == 0) {
return false;
}
/**
* Check the host against the allowed values; delegated to Zend_Filter.
*/
$validate = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_ALL);
return $validate->isValid($host);
}
/**
* Sets the host for the current URI, and returns the old host
*
* @param string $host
* @throws Zend_Uri_Exception
* @return string
*/
public function setHost($host)
{
if (!$this->validateHost($host)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("Host \"$host\" is not a valid HTTP host");
}
$oldHost = $this->_host;
$this->_host = $host;
return $oldHost;
}
/**
* Returns the TCP port, or FALSE if none.
*
* @return string
*/
public function getPort()
{
return strlen($this->_port) ? $this->_port : false;
}
/**
* Returns true if and only if the TCP port string passes validation. If no port is passed,
* then the port contained in the instance variable is used.
*
* @param string $port
* @return boolean
*/
public function validatePort($port = null)
{
if ($port === null) {
$port = $this->_port;
}
// If the port is empty, then it is considered valid
if (!strlen($port)) {
return true;
}
// Check the port against the allowed values
return ctype_digit((string)$port) && 1 <= $port && $port <= 65535;
}
/**
* Sets the port for the current URI, and returns the old port
*
* @param string $port
* @throws Zend_Uri_Exception
* @return string
*/
public function setPort($port)
{
if (!$this->validatePort($port)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("Port \"$port\" is not a valid HTTP port.");
}
$oldPort = $this->_port;
$this->_port = $port;
return $oldPort;
}
/**
* Returns the path and filename portion of the URL, or FALSE if none.
*
* @return string
*/
public function getPath()
{
return strlen($this->_path) ? $this->_path : '/';
}
/**
* Returns true if and only if the path string passes validation. If no path is passed,
* then the path contained in the instance variable is used.
*
* @param string $path
* @throws Zend_Uri_Exception
* @return boolean
*/
public function validatePath($path = null)
{
if ($path === null) {
$path = $this->_path;
}
/**
* If the path is empty, then it is considered valid
*/
if (strlen($path) == 0) {
return true;
}
/**
* Determine whether the path is well-formed
*/
$pattern = '/^' . $this->_regex['path'] . '$/';
$status = @preg_match($pattern, $path);
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: path validation failed');
}
return (boolean) $status;
}
/**
* Sets the path for the current URI, and returns the old path
*
* @param string $path
* @throws Zend_Uri_Exception
* @return string
*/
public function setPath($path)
{
if (!$this->validatePath($path)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("Path \"$path\" is not a valid HTTP path");
}
$oldPath = $this->_path;
$this->_path = $path;
return $oldPath;
}
/**
* Returns the query portion of the URL (after ?), or FALSE if none.
*
* @return string
*/
public function getQuery()
{
return strlen($this->_query) ? $this->_query : false;
}
/**
* Returns true if and only if the query string passes validation. If no query is passed,
* then the query string contained in the instance variable is used.
*
* @param string $query
* @throws Zend_Uri_Exception
* @return boolean
*/
public function validateQuery($query = null)
{
if ($query === null) {
$query = $this->_query;
}
// If query is empty, it is considered to be valid
if (strlen($query) == 0) {
return true;
}
/**
* Determine whether the query is well-formed
*
* @link http://www.faqs.org/rfcs/rfc2396.html
*/
$pattern = '/^' . $this->_regex['uric'] . '*$/';
$status = @preg_match($pattern, $query);
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: query validation failed');
}
return $status == 1;
}
/**
* Set the query string for the current URI, and return the old query
* string This method accepts both strings and arrays.
*
* @param string|array $query The query string or array
* @return string Old query string
*/
public function setQuery($query)
{
$oldQuery = $this->_query;
// If query is empty, set an empty string
if (empty($query)) {
$this->_query = '';
return $oldQuery;
}
// If query is an array, make a string out of it
if (is_array($query)) {
$query = http_build_query($query, '', '&');
// If it is a string, make sure it is valid. If not parse and encode it
} else {
$query = (string) $query;
if (! $this->validateQuery($query)) {
parse_str($query, $query_array);
$query = http_build_query($query_array, '', '&');
}
}
// Make sure the query is valid, and set it
if (! $this->validateQuery($query)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("'$query' is not a valid query string");
}
$this->_query = $query;
return $oldQuery;
}
/**
* Returns the fragment portion of the URL (after #), or FALSE if none.
*
* @return string|false
*/
public function getFragment()
{
return strlen($this->_fragment) ? $this->_fragment : false;
}
/**
* Returns true if and only if the fragment passes validation. If no fragment is passed,
* then the fragment contained in the instance variable is used.
*
* @param string $fragment
* @throws Zend_Uri_Exception
* @return boolean
*/
public function validateFragment($fragment = null)
{
if ($fragment === null) {
$fragment = $this->_fragment;
}
// If fragment is empty, it is considered to be valid
if (strlen($fragment) == 0) {
return true;
}
/**
* Determine whether the fragment is well-formed
*
* @link http://www.faqs.org/rfcs/rfc2396.html
*/
$pattern = '/^' . $this->_regex['uric'] . '*$/';
$status = @preg_match($pattern, $fragment);
if ($status === false) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception('Internal error: fragment validation failed');
}
return (boolean) $status;
}
/**
* Sets the fragment for the current URI, and returns the old fragment
*
* @param string $fragment
* @throws Zend_Uri_Exception
* @return string
*/
public function setFragment($fragment)
{
if (!$this->validateFragment($fragment)) {
require_once 'Zend/Uri/Exception.php';
throw new Zend_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment");
}
$oldFragment = $this->_fragment;
$this->_fragment = $fragment;
return $oldFragment;
}
}

346
Zend/Validate/Abstract.php Normal file
View file

@ -0,0 +1,346 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Abstract.php 8113 2008-02-18 13:15:27Z matthew $
*/
/**
* @see Zend_Validate_Interface
*/
require_once 'Zend/Validate/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Validate_Abstract implements Zend_Validate_Interface
{
/**
* The value to be validated
*
* @var mixed
*/
protected $_value;
/**
* Additional variables available for validation failure messages
*
* @var array
*/
protected $_messageVariables = array();
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array();
/**
* Array of validation failure messages
*
* @var array
*/
protected $_messages = array();
/**
* Flag indidcating whether or not value should be obfuscated in error
* messages
* @var bool
*/
protected $_obscureValue = false;
/**
* Array of validation failure message codes
*
* @var array
* @deprecated Since 1.5.0
*/
protected $_errors = array();
/**
* Translation object
* @var Zend_Translate
*/
protected $_translator;
/**
* Default translation object for all validate objects
* @var Zend_Translate
*/
protected static $_defaultTranslator;
/**
* Returns array of validation failure messages
*
* @return array
*/
public function getMessages()
{
return $this->_messages;
}
/**
* Returns an array of the names of variables that are used in constructing validation failure messages
*
* @return array
*/
public function getMessageVariables()
{
return array_keys($this->_messageVariables);
}
/**
* Sets the validation failure message template for a particular key
*
* @param string $messageString
* @param string $messageKey OPTIONAL
* @return Zend_Validate_Abstract Provides a fluent interface
* @throws Zend_Validate_Exception
*/
public function setMessage($messageString, $messageKey = null)
{
if ($messageKey === null) {
$keys = array_keys($this->_messageTemplates);
$messageKey = current($keys);
}
if (!isset($this->_messageTemplates[$messageKey])) {
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("No message template exists for key '$messageKey'");
}
$this->_messageTemplates[$messageKey] = $messageString;
return $this;
}
/**
* Sets validation failure message templates given as an array, where the array keys are the message keys,
* and the array values are the message template strings.
*
* @param array $messages
* @return Zend_Validate_Abstract
*/
public function setMessages(array $messages)
{
foreach ($messages as $key => $message) {
$this->setMessage($message, $key);
}
return $this;
}
/**
* Magic function returns the value of the requested property, if and only if it is the value or a
* message variable.
*
* @param string $property
* @return mixed
* @throws Zend_Validate_Exception
*/
public function __get($property)
{
if ($property == 'value') {
return $this->_value;
}
if (array_key_exists($property, $this->_messageVariables)) {
return $this->{$this->_messageVariables[$property]};
}
/**
* @see Zend_Validate_Exception
*/
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("No property exists by the name '$property'");
}
/**
* Constructs and returns a validation failure message with the given message key and value.
*
* Returns null if and only if $messageKey does not correspond to an existing template.
*
* If a translator is available and a translation exists for $messageKey,
* the translation will be used.
*
* @param string $messageKey
* @param string $value
* @return string
*/
protected function _createMessage($messageKey, $value)
{
if (!isset($this->_messageTemplates[$messageKey])) {
return null;
}
$message = $this->_messageTemplates[$messageKey];
if (null !== ($translator = $this->getTranslator())) {
if ($translator->isTranslated($messageKey)) {
$message = $translator->translate($messageKey);
}
}
if ($this->getObscureValue()) {
$value = str_repeat('*', strlen($value));
}
$message = str_replace('%value%', (string) $value, $message);
foreach ($this->_messageVariables as $ident => $property) {
$message = str_replace("%$ident%", $this->$property, $message);
}
return $message;
}
/**
* @param string $messageKey OPTIONAL
* @param string $value OPTIONAL
* @return void
*/
protected function _error($messageKey = null, $value = null)
{
if ($messageKey === null) {
$keys = array_keys($this->_messageTemplates);
$messageKey = current($keys);
}
if ($value === null) {
$value = $this->_value;
}
$this->_errors[] = $messageKey;
$this->_messages[$messageKey] = $this->_createMessage($messageKey, $value);
}
/**
* Sets the value to be validated and clears the messages and errors arrays
*
* @param mixed $value
* @return void
*/
protected function _setValue($value)
{
$this->_value = $value;
$this->_messages = array();
$this->_errors = array();
}
/**
* Returns array of validation failure message codes
*
* @return array
* @deprecated Since 1.5.0
*/
public function getErrors()
{
return $this->_errors;
}
/**
* Set flag indicating whether or not value should be obfuscated in messages
*
* @param bool $flag
* @return Zend_Validate_Abstract
*/
public function setObscureValue($flag)
{
$this->_obscureValue = (bool) $flag;
return $this;
}
/**
* Retrieve flag indicating whether or not value should be obfuscated in
* messages
*
* @return bool
*/
public function getObscureValue()
{
return $this->_obscureValue;
}
/**
* Set translation object
*
* @param Zend_Translate|Zend_Translate_Adapter|null $translator
* @return Zend_Validate_Abstract
*/
public function setTranslator($translator = null)
{
if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) {
$this->_translator = $translator;
} elseif ($translator instanceof Zend_Translate) {
$this->_translator = $translator->getAdapter();
} else {
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception('Invalid translator specified');
}
return $this;
}
/**
* Return translation object
*
* @return Zend_Translate_Adapter|null
*/
public function getTranslator()
{
if (null === $this->_translator) {
return self::getDefaultTranslator();
}
return $this->_translator;
}
/**
* Set default translation object for all validate objects
*
* @param Zend_Translate|Zend_Translate_Adapter|null $translator
* @return void
*/
public static function setDefaultTranslator($translator = null)
{
if ((null === $translator) || ($translator instanceof Zend_Translate_Adapter)) {
self::$_defaultTranslator = $translator;
} elseif ($translator instanceof Zend_Translate) {
self::$_defaultTranslator = $translator->getAdapter();
} else {
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception('Invalid translator specified');
}
}
/**
* Get default translation object for all validate objects
*
* @return Zend_Translate_Adapter|null
*/
public static function getDefaultTranslator()
{
if (null === self::$_defaultTranslator) {
require_once 'Zend/Registry.php';
if (Zend_Registry::isRegistered('Zend_Translate')) {
$translator = Zend_Registry::get('Zend_Translate');
if ($translator instanceof Zend_Translate_Adapter) {
return $translator;
} elseif ($translator instanceof Zend_Translate) {
return $translator->getAdapter();
}
}
}
return self::$_defaultTranslator;
}
}

120
Zend/Validate/Alnum.php Normal file
View file

@ -0,0 +1,120 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Alnum.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Alnum extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value contains non-alphabetic or non-digit characters
*/
const NOT_ALNUM = 'notAlnum';
/**
* Validation failure message key for when the value is an empty string
*/
const STRING_EMPTY = 'stringEmpty';
/**
* Whether to allow white space characters; off by default
*
* @var boolean
*/
public $allowWhiteSpace;
/**
* Alphanumeric filter used for validation
*
* @var Zend_Filter_Alnum
*/
protected static $_filter = null;
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::NOT_ALNUM => "'%value%' has not only alphabetic and digit characters",
self::STRING_EMPTY => "'%value%' is an empty string"
);
/**
* Sets default option values for this instance
*
* @param boolean $allowWhiteSpace
* @return void
*/
public function __construct($allowWhiteSpace = false)
{
$this->allowWhiteSpace = (boolean) $allowWhiteSpace;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value contains only alphabetic and digit characters
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if ('' === $valueString) {
$this->_error(self::STRING_EMPTY);
return false;
}
if (null === self::$_filter) {
/**
* @see Zend_Filter_Alnum
*/
require_once 'Zend/Filter/Alnum.php';
self::$_filter = new Zend_Filter_Alnum();
}
self::$_filter->allowWhiteSpace = $this->allowWhiteSpace;
if ($valueString !== self::$_filter->filter($valueString)) {
$this->_error(self::NOT_ALNUM);
return false;
}
return true;
}
}

120
Zend/Validate/Alpha.php Normal file
View file

@ -0,0 +1,120 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Alpha.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Alpha extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value contains non-alphabetic characters
*/
const NOT_ALPHA = 'notAlpha';
/**
* Validation failure message key for when the value is an empty string
*/
const STRING_EMPTY = 'stringEmpty';
/**
* Whether to allow white space characters; off by default
*
* @var boolean
*/
public $allowWhiteSpace;
/**
* Alphabetic filter used for validation
*
* @var Zend_Filter_Alpha
*/
protected static $_filter = null;
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::NOT_ALPHA => "'%value%' has not only alphabetic characters",
self::STRING_EMPTY => "'%value%' is an empty string"
);
/**
* Sets default option values for this instance
*
* @param boolean $allowWhiteSpace
* @return void
*/
public function __construct($allowWhiteSpace = false)
{
$this->allowWhiteSpace = (boolean) $allowWhiteSpace;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value contains only alphabetic characters
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if ('' === $valueString) {
$this->_error(self::STRING_EMPTY);
return false;
}
if (null === self::$_filter) {
/**
* @see Zend_Filter_Alpha
*/
require_once 'Zend/Filter/Alpha.php';
self::$_filter = new Zend_Filter_Alpha();
}
self::$_filter->allowWhiteSpace = $this->allowWhiteSpace;
if ($valueString !== self::$_filter->filter($valueString)) {
$this->_error(self::NOT_ALPHA);
return false;
}
return true;
}
}

99
Zend/Validate/Barcode.php Normal file
View file

@ -0,0 +1,99 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Barcode.php 8211 2008-02-20 14:29:24Z darby $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Barcode extends Zend_Validate_Abstract
{
/**
* Barcode validator
*
* @var Zend_Validate_Abstract
*/
protected $_barcodeValidator;
/**
* Generates the standard validator object
*
* @param string $barcodeType - Barcode validator to use
* @return void
* @throws Zend_Validate_Exception
*/
public function __construct($barcodeType)
{
$this->setType($barcodeType);
}
/**
* Sets a new barcode validator
*
* @param string $barcodeType - Barcode validator to use
* @return void
* @throws Zend_Validate_Exception
*/
public function setType($barcodeType)
{
switch (strtolower($barcodeType)) {
case 'upc':
case 'upc-a':
$className = 'UpcA';
break;
case 'ean13':
case 'ean-13':
$className = 'Ean13';
break;
default:
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("Barcode type '$barcodeType' is not supported'");
break;
}
require_once 'Zend/Validate/Barcode/' . $className . '.php';
$class = 'Zend_Validate_Barcode_' . $className;
$this->_barcodeValidator = new $class;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value contains a valid barcode
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
return call_user_func(array($this->_barcodeValidator, 'isValid'), $value);
}
}

View file

@ -0,0 +1,100 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Ean13.php 8210 2008-02-20 14:09:05Z andries $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Barcode_Ean13 extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value is
* an invalid barcode
*/
const INVALID = 'invalid';
/**
* Validation failure message key for when the value is
* not 13 characters long
*/
const INVALID_LENGTH = 'invalidLength';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::INVALID => "'%value%' is an invalid EAN-13 barcode",
self::INVALID_LENGTH => "'%value%' should be 13 characters",
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value contains a valid barcode
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if (strlen($valueString) !== 13) {
$this->_error(self::INVALID_LENGTH);
return false;
}
$barcode = strrev(substr($valueString, 0, -1));
$oddSum = 0;
$evenSum = 0;
for ($i = 0; $i < 12; $i++) {
if ($i % 2 === 0) {
$oddSum += $barcode[$i] * 3;
} elseif ($i % 2 === 1) {
$evenSum += $barcode[$i];
}
}
$calculation = ($oddSum + $evenSum) % 10;
$checksum = ($calculation === 0) ? 0 : 10 - $calculation;
if ($valueString[12] != $checksum) {
$this->_error(self::INVALID);
return false;
}
return true;
}
}

View file

@ -0,0 +1,100 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: UpcA.php 8210 2008-02-20 14:09:05Z andries $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Barcode_UpcA extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value is
* an invalid barcode
*/
const INVALID = 'invalid';
/**
* Validation failure message key for when the value is
* not 12 characters long
*/
const INVALID_LENGTH = 'invalidLength';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::INVALID => "'%value%' is an invalid UPC-A barcode",
self::INVALID_LENGTH => "'%value%' should be 12 characters",
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value contains a valid barcode
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if (strlen($valueString) !== 12) {
$this->_error(self::INVALID_LENGTH);
return false;
}
$barcode = substr($valueString, 0, -1);
$oddSum = 0;
$evenSum = 0;
for ($i = 0; $i < 11; $i++) {
if ($i % 2 === 0) {
$oddSum += $barcode[$i] * 3;
} elseif ($i % 2 === 1) {
$evenSum += $barcode[$i];
}
}
$calculation = ($oddSum + $evenSum) % 10;
$checksum = ($calculation === 0) ? 0 : 10 - $calculation;
if ($valueString[11] != $checksum) {
$this->_error(self::INVALID);
return false;
}
return true;
}
}

200
Zend/Validate/Between.php Normal file
View file

@ -0,0 +1,200 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Between.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Between extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value is not between the min and max, inclusively
*/
const NOT_BETWEEN = 'notBetween';
/**
* Validation failure message key for when the value is not strictly between the min and max
*/
const NOT_BETWEEN_STRICT = 'notBetweenStrict';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::NOT_BETWEEN => "'%value%' is not between '%min%' and '%max%', inclusively",
self::NOT_BETWEEN_STRICT => "'%value%' is not strictly between '%min%' and '%max%'"
);
/**
* Additional variables available for validation failure messages
*
* @var array
*/
protected $_messageVariables = array(
'min' => '_min',
'max' => '_max'
);
/**
* Minimum value
*
* @var mixed
*/
protected $_min;
/**
* Maximum value
*
* @var mixed
*/
protected $_max;
/**
* Whether to do inclusive comparisons, allowing equivalence to min and/or max
*
* If false, then strict comparisons are done, and the value may equal neither
* the min nor max options
*
* @var boolean
*/
protected $_inclusive;
/**
* Sets validator options
*
* @param mixed $min
* @param mixed $max
* @param boolean $inclusive
* @return void
*/
public function __construct($min, $max, $inclusive = true)
{
$this->setMin($min)
->setMax($max)
->setInclusive($inclusive);
}
/**
* Returns the min option
*
* @return mixed
*/
public function getMin()
{
return $this->_min;
}
/**
* Sets the min option
*
* @param mixed $min
* @return Zend_Validate_Between Provides a fluent interface
*/
public function setMin($min)
{
$this->_min = $min;
return $this;
}
/**
* Returns the max option
*
* @return mixed
*/
public function getMax()
{
return $this->_max;
}
/**
* Sets the max option
*
* @param mixed $max
* @return Zend_Validate_Between Provides a fluent interface
*/
public function setMax($max)
{
$this->_max = $max;
return $this;
}
/**
* Returns the inclusive option
*
* @return boolean
*/
public function getInclusive()
{
return $this->_inclusive;
}
/**
* Sets the inclusive option
*
* @param boolean $inclusive
* @return Zend_Validate_Between Provides a fluent interface
*/
public function setInclusive($inclusive)
{
$this->_inclusive = $inclusive;
return $this;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is between min and max options, inclusively
* if inclusive option is true.
*
* @param mixed $value
* @return boolean
*/
public function isValid($value)
{
$this->_setValue($value);
if ($this->_inclusive) {
if ($this->_min > $value || $value > $this->_max) {
$this->_error(self::NOT_BETWEEN);
return false;
}
} else {
if ($this->_min >= $value || $value >= $this->_max) {
$this->_error(self::NOT_BETWEEN_STRICT);
return false;
}
}
return true;
}
}

111
Zend/Validate/Ccnum.php Normal file
View file

@ -0,0 +1,111 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Ccnum.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Ccnum extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value is not of valid length
*/
const LENGTH = 'ccnumLength';
/**
* Validation failure message key for when the value fails the mod-10 checksum
*/
const CHECKSUM = 'ccnumChecksum';
/**
* Digits filter for input
*
* @var Zend_Filter_Digits
*/
protected static $_filter = null;
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::LENGTH => "'%value%' must contain between 13 and 19 digits",
self::CHECKSUM => "Luhn algorithm (mod-10 checksum) failed on '%value%'"
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value follows the Luhn algorithm (mod-10 checksum)
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$this->_setValue($value);
if (null === self::$_filter) {
/**
* @see Zend_Filter_Digits
*/
require_once 'Zend/Filter/Digits.php';
self::$_filter = new Zend_Filter_Digits();
}
$valueFiltered = self::$_filter->filter($value);
$length = strlen($valueFiltered);
if ($length < 13 || $length > 19) {
$this->_error(self::LENGTH);
return false;
}
$sum = 0;
$weight = 2;
for ($i = $length - 2; $i >= 0; $i--) {
$digit = $weight * $valueFiltered[$i];
$sum += floor($digit / 10) + $digit % 10;
$weight = $weight % 2 + 1;
}
if ((10 - $sum % 10) % 10 != $valueFiltered[$length - 1]) {
$this->_error(self::CHECKSUM, $valueFiltered);
return false;
}
return true;
}
}

181
Zend/Validate/Date.php Normal file
View file

@ -0,0 +1,181 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Date.php 8553 2008-03-05 16:39:50Z darby $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Date extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value does not follow the YYYY-MM-DD format
*/
const NOT_YYYY_MM_DD = 'dateNotYYYY-MM-DD';
/**
* Validation failure message key for when the value does not appear to be a valid date
*/
const INVALID = 'dateInvalid';
/**
* Validation failure message key for when the value does not fit the given dateformat or locale
*/
const FALSEFORMAT = 'dateFalseFormat';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::NOT_YYYY_MM_DD => "'%value%' is not of the format YYYY-MM-DD",
self::INVALID => "'%value%' does not appear to be a valid date",
self::FALSEFORMAT => "'%value%' does not fit given date format"
);
/**
* Optional format
*
* @var string|null
*/
protected $_format;
/**
* Optional locale
*
* @var string|Zend_Locale|null
*/
protected $_locale;
/**
* Sets validator options
*
* @param string $format OPTIONAL
* @param string|Zend_Locale $locale OPTIONAL
* @return void
*/
public function __construct($format = null, $locale = null)
{
$this->setFormat($format);
$this->setLocale($locale);
}
/**
* Returns the locale option
*
* @return string|Zend_Locale|null
*/
public function getLocale()
{
return $this->_locale;
}
/**
* Sets the locale option
*
* @param string|Zend_Locale $locale
* @return Zend_Validate_Date provides a fluent interface
*/
public function setLocale($locale = null)
{
if ($locale !== null) {
require_once 'Zend/Locale.php';
if (!Zend_Locale::isLocale($locale)) {
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("The locale '$locale' is no known locale");
}
}
$this->_locale = $locale;
return $this;
}
/**
* Returns the locale option
*
* @return string|null
*/
public function getFormat()
{
return $this->_format;
}
/**
* Sets the format option
*
* @param string $format
* @return Zend_Validate_Date provides a fluent interface
*/
public function setFormat($format = null)
{
$this->_format = $format;
return $this;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if $value is a valid date of the format YYYY-MM-DD
* If optional $format or $locale is set the date format is checked
* according to Zend_Date, see Zend_Date::isDate()
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if (($this->_format !== null) or ($this->_locale !== null)) {
require_once 'Zend/Date.php';
if (!Zend_Date::isDate($value, $this->_format, $this->_locale)) {
$this->_error(self::FALSEFORMAT);
return false;
}
} else {
if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $valueString)) {
$this->_error(self::NOT_YYYY_MM_DD);
return false;
}
list($year, $month, $day) = sscanf($valueString, '%d-%d-%d');
if (!checkdate($month, $day, $year)) {
$this->_error(self::INVALID);
return false;
}
}
return true;
}
}

100
Zend/Validate/Digits.php Normal file
View file

@ -0,0 +1,100 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Digits.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Digits extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value contains non-digit characters
*/
const NOT_DIGITS = 'notDigits';
/**
* Validation failure message key for when the value is an empty string
*/
const STRING_EMPTY = 'stringEmpty';
/**
* Digits filter used for validation
*
* @var Zend_Filter_Digits
*/
protected static $_filter = null;
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::NOT_DIGITS => "'%value%' contains not only digit characters",
self::STRING_EMPTY => "'%value%' is an empty string"
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value only contains digit characters
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if ('' === $valueString) {
$this->_error(self::STRING_EMPTY);
return false;
}
if (null === self::$_filter) {
/**
* @see Zend_Filter_Digits
*/
require_once 'Zend/Filter/Digits.php';
self::$_filter = new Zend_Filter_Digits();
}
if ($valueString !== self::$_filter->filter($valueString)) {
$this->_error(self::NOT_DIGITS);
return false;
}
return true;
}
}

View file

@ -0,0 +1,245 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: EmailAddress.php 8986 2008-03-21 21:38:32Z matthew $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @see Zend_Validate_Hostname
*/
require_once 'Zend/Validate/Hostname.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_EmailAddress extends Zend_Validate_Abstract
{
const INVALID = 'emailAddressInvalid';
const INVALID_HOSTNAME = 'emailAddressInvalidHostname';
const INVALID_MX_RECORD = 'emailAddressInvalidMxRecord';
const DOT_ATOM = 'emailAddressDotAtom';
const QUOTED_STRING = 'emailAddressQuotedString';
const INVALID_LOCAL_PART = 'emailAddressInvalidLocalPart';
/**
* @var array
*/
protected $_messageTemplates = array(
self::INVALID => "'%value%' is not a valid email address in the basic format local-part@hostname",
self::INVALID_HOSTNAME => "'%hostname%' is not a valid hostname for email address '%value%'",
self::INVALID_MX_RECORD => "'%hostname%' does not appear to have a valid MX record for the email address '%value%'",
self::DOT_ATOM => "'%localPart%' not matched against dot-atom format",
self::QUOTED_STRING => "'%localPart%' not matched against quoted-string format",
self::INVALID_LOCAL_PART => "'%localPart%' is not a valid local part for email address '%value%'"
);
/**
* @var array
*/
protected $_messageVariables = array(
'hostname' => '_hostname',
'localPart' => '_localPart'
);
/**
* Local object for validating the hostname part of an email address
*
* @var Zend_Validate_Hostname
*/
public $hostnameValidator;
/**
* Whether we check for a valid MX record via DNS
*
* @var boolean
*/
protected $_validateMx = false;
/**
* @var string
*/
protected $_hostname;
/**
* @var string
*/
protected $_localPart;
/**
* Instantiates hostname validator for local use
*
* You can pass a bitfield to determine what types of hostnames are allowed.
* These bitfields are defined by the ALLOW_* constants in Zend_Validate_Hostname
* The default is to allow DNS hostnames only
*
* @param integer $allow OPTIONAL
* @param bool $validateMx OPTIONAL
* @param Zend_Validate_Hostname $hostnameValidator OPTIONAL
* @return void
*/
public function __construct($allow = Zend_Validate_Hostname::ALLOW_DNS, $validateMx = false, Zend_Validate_Hostname $hostnameValidator = null)
{
$this->setValidateMx($validateMx);
$this->setHostnameValidator($hostnameValidator, $allow);
}
/**
* @param Zend_Validate_Hostname $hostnameValidator OPTIONAL
* @param int $allow OPTIONAL
* @return void
*/
public function setHostnameValidator(Zend_Validate_Hostname $hostnameValidator = null, $allow = Zend_Validate_Hostname::ALLOW_DNS)
{
if ($hostnameValidator === null) {
$hostnameValidator = new Zend_Validate_Hostname($allow);
}
$this->hostnameValidator = $hostnameValidator;
}
/**
* Whether MX checking via dns_get_mx is supported or not
*
* This currently only works on UNIX systems
*
* @return boolean
*/
public function validateMxSupported()
{
return function_exists('dns_get_mx');
}
/**
* Set whether we check for a valid MX record via DNS
*
* This only applies when DNS hostnames are validated
*
* @param boolean $allowed Set allowed to true to validate for MX records, and false to not validate them
*/
public function setValidateMx($allowed)
{
$this->_validateMx = (bool) $allowed;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is a valid email address
* according to RFC2822
*
* @link http://www.ietf.org/rfc/rfc2822.txt RFC2822
* @link http://www.columbia.edu/kermit/ascii.html US-ASCII characters
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
// Split email address up
if (!preg_match('/^(.+)@([^@]+)$/', $valueString, $matches)) {
$this->_error(self::INVALID);
return false;
}
$this->_localPart = $matches[1];
$this->_hostname = $matches[2];
// Match hostname part
$hostnameResult = $this->hostnameValidator->setTranslator($this->getTranslator())
->isValid($this->_hostname);
if (!$hostnameResult) {
$this->_error(self::INVALID_HOSTNAME);
// Get messages and errors from hostnameValidator
foreach ($this->hostnameValidator->getMessages() as $message) {
$this->_messages[] = $message;
}
foreach ($this->hostnameValidator->getErrors() as $error) {
$this->_errors[] = $error;
}
}
// MX check on hostname via dns_get_record()
if ($this->_validateMx) {
if ($this->validateMxSupported()) {
$result = dns_get_mx($this->_hostname, $mxHosts);
if (count($mxHosts) < 1) {
$hostnameResult = false;
$this->_error(self::INVALID_MX_RECORD);
}
} else {
/**
* MX checks are not supported by this system
* @see Zend_Validate_Exception
*/
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception('Internal error: MX checking not available on this system');
}
}
// First try to match the local part on the common dot-atom format
$localResult = false;
// Dot-atom characters are: 1*atext *("." 1*atext)
// atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
// "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
$atext = 'a-zA-Z0-9\x21\x23\x24\x25\x26\x27\x2a\x2b\x2d\x2f\x3d\x3f\x5e\x5f\x60\x7b\x7c\x7d';
if (preg_match('/^[' . $atext . ']+(\x2e+[' . $atext . ']+)*$/', $this->_localPart)) {
$localResult = true;
} else {
// Try quoted string format
// Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE
// qtext: Non white space controls, and the rest of the US-ASCII characters not
// including "\" or the quote character
$noWsCtl = '\x01-\x08\x0b\x0c\x0e-\x1f\x7f';
$qtext = $noWsCtl . '\x21\x23-\x5b\x5d-\x7e';
$ws = '\x20\x09';
if (preg_match('/^\x22([' . $ws . $qtext . '])*[$ws]?\x22$/', $this->_localPart)) {
$localResult = true;
} else {
$this->_error(self::DOT_ATOM);
$this->_error(self::QUOTED_STRING);
$this->_error(self::INVALID_LOCAL_PART);
}
}
// If both parts valid, return true
if ($localResult && $hostnameResult) {
return true;
} else {
return false;
}
}
}

View file

@ -0,0 +1,37 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Exception.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Exception
*/
require_once 'Zend/Exception.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Exception extends Zend_Exception
{}

75
Zend/Validate/Float.php Normal file
View file

@ -0,0 +1,75 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Float.php 8910 2008-03-19 20:19:23Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Float extends Zend_Validate_Abstract
{
const NOT_FLOAT = 'notFloat';
/**
* @var array
*/
protected $_messageTemplates = array(
self::NOT_FLOAT => "'%value%' does not appear to be a float"
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is a floating-point value
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
$locale = localeconv();
$valueFiltered = str_replace($locale['thousands_sep'], '', $valueString);
$valueFiltered = str_replace($locale['decimal_point'], '.', $valueFiltered);
if (strval(floatval($valueFiltered)) != $valueFiltered) {
$this->_error();
return false;
}
return true;
}
}

View file

@ -0,0 +1,114 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: GreaterThan.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_GreaterThan extends Zend_Validate_Abstract
{
const NOT_GREATER = 'notGreaterThan';
/**
* @var array
*/
protected $_messageTemplates = array(
self::NOT_GREATER => "'%value%' is not greater than '%min%'"
);
/**
* @var array
*/
protected $_messageVariables = array(
'min' => '_min'
);
/**
* Minimum value
*
* @var mixed
*/
protected $_min;
/**
* Sets validator options
*
* @param mixed $min
* @return void
*/
public function __construct($min)
{
$this->setMin($min);
}
/**
* Returns the min option
*
* @return mixed
*/
public function getMin()
{
return $this->_min;
}
/**
* Sets the min option
*
* @param mixed $min
* @return Zend_Validate_GreaterThan Provides a fluent interface
*/
public function setMin($min)
{
$this->_min = $min;
return $this;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is greater than min option
*
* @param mixed $value
* @return boolean
*/
public function isValid($value)
{
$this->_setValue($value);
if ($this->_min >= $value) {
$this->_error();
return false;
}
return true;
}
}

74
Zend/Validate/Hex.php Normal file
View file

@ -0,0 +1,74 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Hex.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hex extends Zend_Validate_Abstract
{
/**
* Validation failure message key for when the value contains characters other than hexadecimal digits
*/
const NOT_HEX = 'notHex';
/**
* Validation failure message template definitions
*
* @var array
*/
protected $_messageTemplates = array(
self::NOT_HEX => "'%value%' has not only hexadecimal digit characters"
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value contains only hexadecimal digit characters
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if (!ctype_xdigit($valueString)) {
$this->_error();
return false;
}
return true;
}
}

444
Zend/Validate/Hostname.php Normal file
View file

@ -0,0 +1,444 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Hostname.php 8986 2008-03-21 21:38:32Z matthew $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @see Zend_Loader
*/
require_once 'Zend/Loader.php';
/**
* @see Zend_Validate_Ip
*/
require_once 'Zend/Validate/Ip.php';
/**
* Please note there are two standalone test scripts for testing IDN characters due to problems
* with file encoding.
*
* The first is tests/Zend/Validate/HostnameTestStandalone.php which is designed to be run on
* the command line.
*
* The second is tests/Zend/Validate/HostnameTestForm.php which is designed to be run via HTML
* to allow users to test entering UTF-8 characters in a form.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname extends Zend_Validate_Abstract
{
const IP_ADDRESS_NOT_ALLOWED = 'hostnameIpAddressNotAllowed';
const UNKNOWN_TLD = 'hostnameUnknownTld';
const INVALID_DASH = 'hostnameDashCharacter';
const INVALID_HOSTNAME_SCHEMA = 'hostnameInvalidHostnameSchema';
const UNDECIPHERABLE_TLD = 'hostnameUndecipherableTld';
const INVALID_HOSTNAME = 'hostnameInvalidHostname';
const INVALID_LOCAL_NAME = 'hostnameInvalidLocalName';
const LOCAL_NAME_NOT_ALLOWED = 'hostnameLocalNameNotAllowed';
/**
* @var array
*/
protected $_messageTemplates = array(
self::IP_ADDRESS_NOT_ALLOWED => "'%value%' appears to be an IP address, but IP addresses are not allowed",
self::UNKNOWN_TLD => "'%value%' appears to be a DNS hostname but cannot match TLD against known list",
self::INVALID_DASH => "'%value%' appears to be a DNS hostname but contains a dash (-) in an invalid position",
self::INVALID_HOSTNAME_SCHEMA => "'%value%' appears to be a DNS hostname but cannot match against hostname schema for TLD '%tld%'",
self::UNDECIPHERABLE_TLD => "'%value%' appears to be a DNS hostname but cannot extract TLD part",
self::INVALID_HOSTNAME => "'%value%' does not match the expected structure for a DNS hostname",
self::INVALID_LOCAL_NAME => "'%value%' does not appear to be a valid local network name",
self::LOCAL_NAME_NOT_ALLOWED => "'%value%' appears to be a local network name but local network names are not allowed"
);
/**
* @var array
*/
protected $_messageVariables = array(
'tld' => '_tld'
);
/**
* Allows Internet domain names (e.g., example.com)
*/
const ALLOW_DNS = 1;
/**
* Allows IP addresses
*/
const ALLOW_IP = 2;
/**
* Allows local network names (e.g., localhost, www.localdomain)
*/
const ALLOW_LOCAL = 4;
/**
* Allows all types of hostnames
*/
const ALLOW_ALL = 7;
/**
* Whether IDN domains are validated
*
* @var boolean
*/
private $_validateIdn = true;
/**
* Whether TLDs are validated against a known list
*
* @var boolean
*/
private $_validateTld = true;
/**
* Bit field of ALLOW constants; determines which types of hostnames are allowed
*
* @var integer
*/
protected $_allow;
/**
* Bit field of CHECK constants; determines what additional hostname checks to make
*
* @var unknown_type
*/
// protected $_check;
/**
* Array of valid top-level-domains
*
* @var array
* @see ftp://data.iana.org/TLD/tlds-alpha-by-domain.txt List of all TLDs by domain
*/
protected $_validTlds = array(
'ac', 'ad', 'ae', 'aero', 'af', 'ag', 'ai', 'al', 'am', 'an', 'ao',
'aq', 'ar', 'arpa', 'as', 'asia', 'at', 'au', 'aw', 'ax', 'az', 'ba', 'bb',
'bd', 'be', 'bf', 'bg', 'bh', 'bi', 'biz', 'bj', 'bm', 'bn', 'bo',
'br', 'bs', 'bt', 'bv', 'bw', 'by', 'bz', 'ca', 'cat', 'cc', 'cd',
'cf', 'cg', 'ch', 'ci', 'ck', 'cl', 'cm', 'cn', 'co', 'com', 'coop',
'cr', 'cu', 'cv', 'cx', 'cy', 'cz', 'de', 'dj', 'dk', 'dm', 'do',
'dz', 'ec', 'edu', 'ee', 'eg', 'er', 'es', 'et', 'eu', 'fi', 'fj',
'fk', 'fm', 'fo', 'fr', 'ga', 'gb', 'gd', 'ge', 'gf', 'gg', 'gh',
'gi', 'gl', 'gm', 'gn', 'gov', 'gp', 'gq', 'gr', 'gs', 'gt', 'gu',
'gw', 'gy', 'hk', 'hm', 'hn', 'hr', 'ht', 'hu', 'id', 'ie', 'il',
'im', 'in', 'info', 'int', 'io', 'iq', 'ir', 'is', 'it', 'je', 'jm',
'jo', 'jobs', 'jp', 'ke', 'kg', 'kh', 'ki', 'km', 'kn', 'kp', 'kr', 'kw',
'ky', 'kz', 'la', 'lb', 'lc', 'li', 'lk', 'lr', 'ls', 'lt', 'lu',
'lv', 'ly', 'ma', 'mc', 'md', 'me', 'mg', 'mh', 'mil', 'mk', 'ml', 'mm',
'mn', 'mo', 'mobi', 'mp', 'mq', 'mr', 'ms', 'mt', 'mu', 'museum', 'mv',
'mw', 'mx', 'my', 'mz', 'na', 'name', 'nc', 'ne', 'net', 'nf', 'ng',
'ni', 'nl', 'no', 'np', 'nr', 'nu', 'nz', 'om', 'org', 'pa', 'pe',
'pf', 'pg', 'ph', 'pk', 'pl', 'pm', 'pn', 'pr', 'pro', 'ps', 'pt',
'pw', 'py', 'qa', 're', 'ro', 'rs', 'ru', 'rw', 'sa', 'sb', 'sc', 'sd',
'se', 'sg', 'sh', 'si', 'sj', 'sk', 'sl', 'sm', 'sn', 'so', 'sr',
'st', 'su', 'sv', 'sy', 'sz', 'tc', 'td', 'tel', 'tf', 'tg', 'th', 'tj',
'tk', 'tl', 'tm', 'tn', 'to', 'tp', 'tr', 'travel', 'tt', 'tv', 'tw',
'tz', 'ua', 'ug', 'uk', 'um', 'us', 'uy', 'uz', 'va', 'vc', 've',
'vg', 'vi', 'vn', 'vu', 'wf', 'ws', 'ye', 'yt', 'yu', 'za', 'zm',
'zw'
);
/**
* @var string
*/
protected $_tld;
/**
* Sets validator options
*
* @param integer $allow OPTIONAL Set what types of hostname to allow (default ALLOW_DNS)
* @param boolean $validateIdn OPTIONAL Set whether IDN domains are validated (default true)
* @param boolean $validateTld OPTIONAL Set whether the TLD element of a hostname is validated (default true)
* @param Zend_Validate_Ip $ipValidator OPTIONAL
* @return void
* @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm Technical Specifications for ccTLDs
*/
public function __construct($allow = self::ALLOW_DNS, $validateIdn = true, $validateTld = true, Zend_Validate_Ip $ipValidator = null)
{
// Set allow options
$this->setAllow($allow);
// Set validation options
$this->_validateIdn = $validateIdn;
$this->_validateTld = $validateTld;
$this->setIpValidator($ipValidator);
}
/**
* @param Zend_Validate_Ip $ipValidator OPTIONAL
* @return void;
*/
public function setIpValidator(Zend_Validate_Ip $ipValidator = null)
{
if ($ipValidator === null) {
$ipValidator = new Zend_Validate_Ip();
}
$this->_ipValidator = $ipValidator;
}
/**
* Returns the allow option
*
* @return integer
*/
public function getAllow()
{
return $this->_allow;
}
/**
* Sets the allow option
*
* @param integer $allow
* @return Zend_Validate_Hostname Provides a fluent interface
*/
public function setAllow($allow)
{
$this->_allow = $allow;
return $this;
}
/**
* Set whether IDN domains are validated
*
* This only applies when DNS hostnames are validated
*
* @param boolean $allowed Set allowed to true to validate IDNs, and false to not validate them
*/
public function setValidateIdn ($allowed)
{
$this->_validateIdn = (bool) $allowed;
}
/**
* Set whether the TLD element of a hostname is validated
*
* This only applies when DNS hostnames are validated
*
* @param boolean $allowed Set allowed to true to validate TLDs, and false to not validate them
*/
public function setValidateTld ($allowed)
{
$this->_validateTld = (bool) $allowed;
}
/**
* Sets the check option
*
* @param integer $check
* @return Zend_Validate_Hostname Provides a fluent interface
*/
/*
public function setCheck($check)
{
$this->_check = $check;
return $this;
}
*/
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if the $value is a valid hostname with respect to the current allow option
*
* @param string $value
* @throws Zend_Validate_Exception if a fatal error occurs for validation process
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
// Check input against IP address schema
if ($this->_ipValidator->setTranslator($this->getTranslator())->isValid($valueString)) {
if (!($this->_allow & self::ALLOW_IP)) {
$this->_error(self::IP_ADDRESS_NOT_ALLOWED);
return false;
} else{
return true;
}
}
// Check input against DNS hostname schema
$domainParts = explode('.', $valueString);
if ((count($domainParts) > 1) && (strlen($valueString) >= 4) && (strlen($valueString) <= 254)) {
$status = false;
do {
// First check TLD
if (preg_match('/([a-z]{2,10})$/i', end($domainParts), $matches)) {
reset($domainParts);
// Hostname characters are: *(label dot)(label dot label); max 254 chars
// label: id-prefix [*ldh{61} id-prefix]; max 63 chars
// id-prefix: alpha / digit
// ldh: alpha / digit / dash
// Match TLD against known list
$this->_tld = strtolower($matches[1]);
if ($this->_validateTld) {
if (!in_array($this->_tld, $this->_validTlds)) {
$this->_error(self::UNKNOWN_TLD);
$status = false;
break;
}
}
/**
* Match against IDN hostnames
* @see Zend_Validate_Hostname_Interface
*/
$labelChars = 'a-z0-9';
$utf8 = false;
$classFile = 'Zend/Validate/Hostname/' . ucfirst($this->_tld) . '.php';
if ($this->_validateIdn) {
if (Zend_Loader::isReadable($classFile)) {
// Load additional characters
$className = 'Zend_Validate_Hostname_' . ucfirst($this->_tld);
Zend_Loader::loadClass($className);
$labelChars .= call_user_func(array($className, 'getCharacters'));
$utf8 = true;
}
}
// Keep label regex short to avoid issues with long patterns when matching IDN hostnames
$regexLabel = '/^[' . $labelChars . '\x2d]{1,63}$/i';
if ($utf8) {
$regexLabel .= 'u';
}
// Check each hostname part
$valid = true;
foreach ($domainParts as $domainPart) {
// Check dash (-) does not start, end or appear in 3rd and 4th positions
if (strpos($domainPart, '-') === 0 ||
(strlen($domainPart) > 2 && strpos($domainPart, '-', 2) == 2 && strpos($domainPart, '-', 3) == 3) ||
strrpos($domainPart, '-') === strlen($domainPart) - 1) {
$this->_error(self::INVALID_DASH);
$status = false;
break 2;
}
// Check each domain part
$status = @preg_match($regexLabel, $domainPart);
if ($status === false) {
/**
* Regex error
* @see Zend_Validate_Exception
*/
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception('Internal error: DNS validation failed');
} elseif ($status === 0) {
$valid = false;
}
}
// If all labels didn't match, the hostname is invalid
if (!$valid) {
$this->_error(self::INVALID_HOSTNAME_SCHEMA);
$status = false;
}
} else {
// Hostname not long enough
$this->_error(self::UNDECIPHERABLE_TLD);
$status = false;
}
} while (false);
// If the input passes as an Internet domain name, and domain names are allowed, then the hostname
// passes validation
if ($status && ($this->_allow & self::ALLOW_DNS)) {
return true;
}
} else {
$this->_error(self::INVALID_HOSTNAME);
}
// Check input against local network name schema; last chance to pass validation
$regexLocal = '/^(([a-zA-Z0-9\x2d]{1,63}\x2e)*[a-zA-Z0-9\x2d]{1,63}){1,254}$/';
$status = @preg_match($regexLocal, $valueString);
if (false === $status) {
/**
* Regex error
* @see Zend_Validate_Exception
*/
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception('Internal error: local network name validation failed');
}
// If the input passes as a local network name, and local network names are allowed, then the
// hostname passes validation
$allowLocal = $this->_allow & self::ALLOW_LOCAL;
if ($status && $allowLocal) {
return true;
}
// If the input does not pass as a local network name, add a message
if (!$status) {
$this->_error(self::INVALID_LOCAL_NAME);
}
// If local network names are not allowed, add a message
if (!$allowLocal) {
$this->_error(self::LOCAL_NAME_NOT_ALLOWED);
}
return false;
}
/**
* Throws an exception if a regex for $type does not exist
*
* @param string $type
* @throws Zend_Validate_Exception
* @return Zend_Validate_Hostname Provides a fluent interface
*/
/*
protected function _checkRegexType($type)
{
if (!isset($this->_regex[$type])) {
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("'$type' must be one of ('" . implode(', ', array_keys($this->_regex))
. "')");
}
return $this;
}
*/
}

View file

@ -0,0 +1,50 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: At.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_At implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see http://www.nic.at/en/service/technical_information/idn/charset_converter/ Austria (.AT)
* @return string
*/
static function getCharacters()
{
return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}\x{0161}\x{017E}';
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Ch.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_Ch implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 Switzerland (.CH)
* @return string
*/
static function getCharacters()
{
return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}';
}
}

View file

@ -0,0 +1,58 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: De.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_De implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see http://www.denic.de/en/domains/idns/liste.html Germany (.DE) alllowed characters
* @return string
*/
static function getCharacters()
{
return '\x{00E1}\x{00E0}\x{0103}\x{00E2}\x{00E5}\x{00E4}\x{00E3}\x{0105}\x{0101}\x{00E6}\x{0107}' .
'\x{0109}\x{010D}\x{010B}\x{00E7}\x{010F}\x{0111}\x{00E9}\x{00E8}\x{0115}\x{00EA}\x{011B}' .
'\x{00EB}\x{0117}\x{0119}\x{0113}\x{011F}\x{011D}\x{0121}\x{0123}\x{0125}\x{0127}\x{00ED}' .
'\x{00EC}\x{012D}\x{00EE}\x{00EF}\x{0129}\x{012F}\x{012B}\x{0131}\x{0135}\x{0137}\x{013A}' .
'\x{013E}\x{013C}\x{0142}\x{0144}\x{0148}\x{00F1}\x{0146}\x{014B}\x{00F3}\x{00F2}\x{014F}' .
'\x{00F4}\x{00F6}\x{0151}\x{00F5}\x{00F8}\x{014D}\x{0153}\x{0138}\x{0155}\x{0159}\x{0157}' .
'\x{015B}\x{015D}\x{0161}\x{015F}\x{0165}\x{0163}\x{0167}\x{00FA}\x{00F9}\x{016D}\x{00FB}' .
'\x{016F}\x{00FC}\x{0171}\x{0169}\x{0173}\x{016B}\x{0175}\x{00FD}\x{0177}\x{00FF}\x{017A}' .
'\x{017E}\x{017C}\x{00F0}\x{00FE}';
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Fi.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_Fi implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see http://www.ficora.fi/en/index/palvelut/fiverkkotunnukset/aakkostenkaytto.html Finland (.FI)
* @return string
*/
static function getCharacters()
{
return '\x{00E5}\x{00E4}\x{00F6}';
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Hu.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_Hu implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see http://www.domain.hu/domain/English/szabalyzat.html Hungary (.HU)
* @return string
*/
static function getCharacters()
{
return '\x{00E1}\x{00E9}\x{00ED}\x{00F3}\x{00F6}\x{0151}\x{00FA}\x{00FC}\x{0171}';
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* UTF-8 characters should be written as four character hex codes \x{XXXX}
* For example é (lowercase e with acute) is represented by the hex code \x{00E9}
*
* You only need to include lower-case equivalents of characters since the hostname
* check is case-insensitive
*
* Please document the supported TLDs in the documentation file at:
* manual/en/module_specs/Zend_Validate-Hostname.xml
*
* @see http://en.wikipedia.org/wiki/Internationalized_domain_name
* @see http://www.iana.org/cctld/ Country-Code Top-Level Domains (TLDs)
* @see http://www.columbia.edu/kermit/utf8-t1.html UTF-8 characters
* @return string
*/
static function getCharacters();
}

View file

@ -0,0 +1,50 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Li.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_Li implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see https://nic.switch.ch/reg/ocView.action?res=EF6GW2JBPVTG67DLNIQXU234MN6SC33JNQQGI7L6#anhang1 Liechtenstein (.LI)
* @return string
*/
static function getCharacters()
{
return '\x{00EO}-\x{00F6}\x{00F8}-\x{00FF}\x{0153}';
}
}

View file

@ -0,0 +1,52 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: No.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_No implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see http://www.norid.no/domeneregistrering/idn/idn_nyetegn.en.html Norway (.NO)
* @return string
*/
static function getCharacters()
{
return '\x00E1\x00E0\x00E4\x010D\x00E7\x0111\x00E9\x00E8\x00EA\x\x014B' .
'\x0144\x00F1\x00F3\x00F2\x00F4\x00F6\x0161\x0167\x00FC\x017E\x00E6' .
'\x00F8\x00E5';
}
}

View file

@ -0,0 +1,50 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Se.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Hostname_Interface
*/
require_once 'Zend/Validate/Hostname/Interface.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Hostname_Se implements Zend_Validate_Hostname_Interface
{
/**
* Returns UTF-8 characters allowed in DNS hostnames for the specified Top-Level-Domain
*
* @see http://www.iis.se/english/IDN_campaignsite.shtml?lang=en Sweden (.SE)
* @return string
*/
static function getCharacters()
{
return '\x{00E5}\x{00E4}\x{00F6}\x{00FC}\x{00E9}';
}
}

117
Zend/Validate/Identical.php Normal file
View file

@ -0,0 +1,117 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Identical.php 8118 2008-02-18 16:10:32Z matthew $
*/
/** Zend_Validate_Abstract */
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Identical extends Zend_Validate_Abstract
{
/**#@+
* Error codes
* @const string
*/
const NOT_SAME = 'notSame';
const MISSING_TOKEN = 'missingToken';
/**#@-*/
/**
* Error messages
* @var array
*/
protected $_messageTemplates = array(
self::NOT_SAME => 'Tokens do not match',
self::MISSING_TOKEN => 'No token was provided to match against',
);
/**
* Original token against which to validate
* @var string
*/
protected $_token;
/**
* Sets validator options
*
* @param string $token
* @return void
*/
public function __construct($token = null)
{
if (null !== $token) {
$this->setToken($token);
}
}
/**
* Set token against which to compare
*
* @param string $token
* @return Zend_Validate_Identical
*/
public function setToken($token)
{
$this->_token = (string) $token;
return $this;
}
/**
* Retrieve token
*
* @return string
*/
public function getToken()
{
return $this->_token;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if a token has been set and the provided value
* matches that token.
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$this->_setValue($value);
$token = $this->getToken();
if (empty($token)) {
$this->_error(self::MISSING_TOKEN);
return false;
}
if ($value !== $token) {
$this->_error(self::NOT_SAME);
return false;
}
return true;
}
}

138
Zend/Validate/InArray.php Normal file
View file

@ -0,0 +1,138 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: InArray.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_InArray extends Zend_Validate_Abstract
{
const NOT_IN_ARRAY = 'notInArray';
/**
* @var array
*/
protected $_messageTemplates = array(
self::NOT_IN_ARRAY => "'%value%' was not found in the haystack"
);
/**
* Haystack of possible values
*
* @var array
*/
protected $_haystack;
/**
* Whether a strict in_array() invocation is used
*
* @var boolean
*/
protected $_strict;
/**
* Sets validator options
*
* @param array $haystack
* @param boolean $strict
* @return void
*/
public function __construct(array $haystack, $strict = false)
{
$this->setHaystack($haystack)
->setStrict($strict);
}
/**
* Returns the haystack option
*
* @return mixed
*/
public function getHaystack()
{
return $this->_haystack;
}
/**
* Sets the haystack option
*
* @param mixed $haystack
* @return Zend_Validate_InArray Provides a fluent interface
*/
public function setHaystack(array $haystack)
{
$this->_haystack = $haystack;
return $this;
}
/**
* Returns the strict option
*
* @return boolean
*/
public function getStrict()
{
return $this->_strict;
}
/**
* Sets the strict option
*
* @param boolean $strict
* @return Zend_Validate_InArray Provides a fluent interface
*/
public function setStrict($strict)
{
$this->_strict = $strict;
return $this;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is contained in the haystack option. If the strict
* option is true, then the type of $value is also checked.
*
* @param mixed $value
* @return boolean
*/
public function isValid($value)
{
$this->_setValue($value);
if (!in_array($value, $this->_haystack, $this->_strict)) {
$this->_error();
return false;
}
return true;
}
}

75
Zend/Validate/Int.php Normal file
View file

@ -0,0 +1,75 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Int.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Int extends Zend_Validate_Abstract
{
const NOT_INT = 'notInt';
/**
* @var array
*/
protected $_messageTemplates = array(
self::NOT_INT => "'%value%' does not appear to be an integer"
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is a valid integer
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
$locale = localeconv();
$valueFiltered = str_replace($locale['decimal_point'], '.', $valueString);
$valueFiltered = str_replace($locale['thousands_sep'], '', $valueFiltered);
if (strval(intval($valueFiltered)) != $valueFiltered) {
$this->_error();
return false;
}
return true;
}
}

View file

@ -0,0 +1,71 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Interface.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
interface Zend_Validate_Interface
{
/**
* Returns true if and only if $value meets the validation requirements
*
* If $value fails validation, then this method returns false, and
* getMessages() will return an array of messages that explain why the
* validation failed.
*
* @param mixed $value
* @return boolean
* @throws Zend_Valid_Exception If validation of $value is impossible
*/
public function isValid($value);
/**
* Returns an array of messages that explain why the most recent isValid()
* call returned false. The array keys are validation failure message identifiers,
* and the array values are the corresponding human-readable message strings.
*
* If isValid() was never called or if the most recent isValid() call
* returned true, then this method returns an empty array.
*
* @return array
*/
public function getMessages();
/**
* Returns an array of message codes that explain why a previous isValid() call
* returned false.
*
* If isValid() was never called or if the most recent isValid() call
* returned true, then this method returns an empty array.
*
* This is now the same as calling array_keys() on the return value from getMessages().
*
* @return array
* @deprecated Since 1.5.0
*/
public function getErrors();
}

70
Zend/Validate/Ip.php Normal file
View file

@ -0,0 +1,70 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Ip.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Ip extends Zend_Validate_Abstract
{
const NOT_IP_ADDRESS = 'notIpAddress';
/**
* @var array
*/
protected $_messageTemplates = array(
self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address"
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is a valid IP address
*
* @param mixed $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if (ip2long($valueString) === false) {
$this->_error();
return false;
}
return true;
}
}

113
Zend/Validate/LessThan.php Normal file
View file

@ -0,0 +1,113 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: LessThan.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_LessThan extends Zend_Validate_Abstract
{
const NOT_LESS = 'notLessThan';
/**
* @var array
*/
protected $_messageTemplates = array(
self::NOT_LESS => "'%value%' is not less than '%max%'"
);
/**
* @var array
*/
protected $_messageVariables = array(
'max' => '_max'
);
/**
* Maximum value
*
* @var mixed
*/
protected $_max;
/**
* Sets validator options
*
* @param mixed $max
* @return void
*/
public function __construct($max)
{
$this->setMax($max);
}
/**
* Returns the max option
*
* @return mixed
*/
public function getMax()
{
return $this->_max;
}
/**
* Sets the max option
*
* @param mixed $max
* @return Zend_Validate_LessThan Provides a fluent interface
*/
public function setMax($max)
{
$this->_max = $max;
return $this;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is less than max option
*
* @param mixed $value
* @return boolean
*/
public function isValid($value)
{
$this->_setValue($value);
if ($this->_max <= $value) {
$this->_error();
return false;
}
return true;
}
}

View file

@ -0,0 +1,70 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: NotEmpty.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_NotEmpty extends Zend_Validate_Abstract
{
const IS_EMPTY = 'isEmpty';
/**
* @var array
*/
protected $_messageTemplates = array(
self::IS_EMPTY => "Value is empty, but a non-empty value is required"
);
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value is not an empty value.
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
if (empty($value)) {
$this->_error();
return false;
}
return true;
}
}

125
Zend/Validate/Regex.php Normal file
View file

@ -0,0 +1,125 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: Regex.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_Regex extends Zend_Validate_Abstract
{
const NOT_MATCH = 'regexNotMatch';
/**
* @var array
*/
protected $_messageTemplates = array(
self::NOT_MATCH => "'%value%' does not match against pattern '%pattern%'"
);
/**
* @var array
*/
protected $_messageVariables = array(
'pattern' => '_pattern'
);
/**
* Regular expression pattern
*
* @var string
*/
protected $_pattern;
/**
* Sets validator options
*
* @param string $pattern
* @return void
*/
public function __construct($pattern)
{
$this->setPattern($pattern);
}
/**
* Returns the pattern option
*
* @return string
*/
public function getPattern()
{
return $this->_pattern;
}
/**
* Sets the pattern option
*
* @param string $pattern
* @return Zend_Validate_Regex Provides a fluent interface
*/
public function setPattern($pattern)
{
$this->_pattern = (string) $pattern;
return $this;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if $value matches against the pattern option
*
* @param string $value
* @throws Zend_Validate_Exception if there is a fatal error in pattern matching
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
$status = @preg_match($this->_pattern, $valueString);
if (false === $status) {
/**
* @see Zend_Validate_Exception
*/
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("Internal error matching pattern '$this->_pattern' against value '$valueString'");
}
if (!$status) {
$this->_error();
return false;
}
return true;
}
}

View file

@ -0,0 +1,180 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id: StringLength.php 8064 2008-02-16 10:58:39Z thomas $
*/
/**
* @see Zend_Validate_Abstract
*/
require_once 'Zend/Validate/Abstract.php';
/**
* @category Zend
* @package Zend_Validate
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
class Zend_Validate_StringLength extends Zend_Validate_Abstract
{
const TOO_SHORT = 'stringLengthTooShort';
const TOO_LONG = 'stringLengthTooLong';
/**
* @var array
*/
protected $_messageTemplates = array(
self::TOO_SHORT => "'%value%' is less than %min% characters long",
self::TOO_LONG => "'%value%' is greater than %max% characters long"
);
/**
* @var array
*/
protected $_messageVariables = array(
'min' => '_min',
'max' => '_max'
);
/**
* Minimum length
*
* @var integer
*/
protected $_min;
/**
* Maximum length
*
* If null, there is no maximum length
*
* @var integer|null
*/
protected $_max;
/**
* Sets validator options
*
* @param integer $min
* @param integer $max
* @return void
*/
public function __construct($min = 0, $max = null)
{
$this->setMin($min);
$this->setMax($max);
}
/**
* Returns the min option
*
* @return integer
*/
public function getMin()
{
return $this->_min;
}
/**
* Sets the min option
*
* @param integer $min
* @throws Zend_Validate_Exception
* @return Zend_Validate_StringLength Provides a fluent interface
*/
public function setMin($min)
{
if (null !== $this->_max && $min > $this->_max) {
/**
* @see Zend_Validate_Exception
*/
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("The minimum must be less than or equal to the maximum length, but $min >"
. " $this->_max");
}
$this->_min = max(0, (integer) $min);
return $this;
}
/**
* Returns the max option
*
* @return integer|null
*/
public function getMax()
{
return $this->_max;
}
/**
* Sets the max option
*
* @param integer|null $max
* @throws Zend_Validate_Exception
* @return Zend_Validate_StringLength Provides a fluent interface
*/
public function setMax($max)
{
if (null === $max) {
$this->_max = null;
} else if ($max < $this->_min) {
/**
* @see Zend_Validate_Exception
*/
require_once 'Zend/Validate/Exception.php';
throw new Zend_Validate_Exception("The maximum must be greater than or equal to the minimum length, but "
. "$max < $this->_min");
} else {
$this->_max = (integer) $max;
}
return $this;
}
/**
* Defined by Zend_Validate_Interface
*
* Returns true if and only if the string length of $value is at least the min option and
* no greater than the max option (when the max option is not null).
*
* @param string $value
* @return boolean
*/
public function isValid($value)
{
$valueString = (string) $value;
$this->_setValue($valueString);
$length = iconv_strlen($valueString);
if ($length < $this->_min) {
$this->_error(self::TOO_SHORT);
}
if (null !== $this->_max && $this->_max < $length) {
$this->_error(self::TOO_LONG);
}
if (count($this->_messages)) {
return false;
} else {
return true;
}
}
}

74
feed_merge.php Normal file
View file

@ -0,0 +1,74 @@
<?php
// source : http://devzone.zend.com/article/3208-Using-Zend_Feed-to-Merge-Multiple-RSS-Feeds
require_once 'Zend/Feed.php';
function loadFeed ($url) {
try {
$feed = Zend_Feed::import($url);
} catch (Zend_Feed_Exception $e) {
// feed import failed
return null;
}
return $feed;
}
// Feed → array
function getEntriesAsArray ($feed) {
$entries = array();
foreach ($feed as $entry) {
$entries[] = array (
'title' => $entry->title(),
'link' => $entry->link(),
'guid' => $entry->guid(),
'lastUpdate' =>strtotime($entry->pubDate()),
'description' => $entry->description(),
'pubDate' => $entry->pubDate(),
);
// TODO ajouter les champs qui manquent
// TODO vérifier que les deux RSS n'aient pas de champs différents
}
return $entries;
}
// sorting operator
function cmpEntries ($a , $b) {
$a_time = $a['lastUpdate'];
$b_time = $b['lastUpdate'];
if ($a_time == $b_time) {
return 0;
}
return ($a_time > $b_time) ? -1 : 1;
}
// Feed for merge
$merged_feed = array (
'title' => 'Test merge feed',
'link' => 'http://localhost/~nojhan/feed_merge.php',
'charset' => 'UTF-8',
'entries' => array (),
);
$feed1 = loadFeed( "http://www.nojhan.net/geekscottes/rss.php?limit=10" );
$feed2 = loadFeed( "http://www.nojhan.net/geekscottes/forum/extern.php?action=new&fid=5&type=rss" );
$merged_feed['entries'] = array_merge (
getEntriesAsArray ($feed1),
getEntriesAsArray ($feed2)
);
usort ($merged_feed['entries'], 'cmpEntries');
// create an object
$rssFeedFromArray = Zend_Feed::importArray($merged_feed, 'rss');
// outut
$rssFeedFromArray->send();
?>