/lib/zend/Zend/Gdata/App/Base.php
PHP | 572 lines | 258 code | 40 blank | 274 comment | 40 complexity | b5f95804285dfa947e1e39679d53663c MD5 | raw file
Possible License(s): MIT, AGPL-3.0, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, Apache-2.0, LGPL-2.1, BSD-3-Clause
- <?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_Gdata
- * @subpackage App
- * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- * @version $Id$
- */
- /**
- * @see Zend_Gdata_App_Util
- */
- require_once 'Zend/Gdata/App/Util.php';
- /**
- * Abstract class for all XML elements
- *
- * @category Zend
- * @package Zend_Gdata
- * @subpackage App
- * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
- * @license http://framework.zend.com/license/new-bsd New BSD License
- */
- abstract class Zend_Gdata_App_Base
- {
- /**
- * @var string The XML element name, including prefix if desired
- */
- protected $_rootElement = null;
- /**
- * @var string The XML namespace prefix
- */
- protected $_rootNamespace = 'atom';
- /**
- * @var string The XML namespace URI - takes precedence over lookup up the
- * corresponding URI for $_rootNamespace
- */
- protected $_rootNamespaceURI = null;
- /**
- * @var array Leftover elements which were not handled
- */
- protected $_extensionElements = array();
- /**
- * @var array Leftover attributes which were not handled
- */
- protected $_extensionAttributes = array();
- /**
- * @var string XML child text node content
- */
- protected $_text = null;
- /**
- * @var array Memoized results from calls to lookupNamespace() to avoid
- * expensive calls to getGreatestBoundedValue(). The key is in the
- * form 'prefix-majorVersion-minorVersion', and the value is the
- * output from getGreatestBoundedValue().
- */
- protected static $_namespaceLookupCache = array();
- /**
- * List of namespaces, as a three-dimensional array. The first dimension
- * represents the namespace prefix, the second dimension represents the
- * minimum major protocol version, and the third dimension is the minimum
- * minor protocol version. Null keys are NOT allowed.
- *
- * When looking up a namespace for a given prefix, the greatest version
- * number (both major and minor) which is less than the effective version
- * should be used.
- *
- * @see lookupNamespace()
- * @see registerNamespace()
- * @see registerAllNamespaces()
- * @var array
- */
- protected $_namespaces = array(
- 'atom' => array(
- 1 => array(
- 0 => 'http://www.w3.org/2005/Atom'
- )
- ),
- 'app' => array(
- 1 => array(
- 0 => 'http://purl.org/atom/app#'
- ),
- 2 => array(
- 0 => 'http://www.w3.org/2007/app'
- )
- )
- );
- public function __construct()
- {
- }
- /**
- * Returns the child text node of this element
- * This represents any raw text contained within the XML element
- *
- * @return string Child text node
- */
- public function getText($trim = true)
- {
- if ($trim) {
- return trim($this->_text);
- } else {
- return $this->_text;
- }
- }
- /**
- * Sets the child text node of this element
- * This represents any raw text contained within the XML element
- *
- * @param string $value Child text node
- * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
- */
- public function setText($value)
- {
- $this->_text = $value;
- return $this;
- }
- /**
- * Returns an array of all elements not matched to data model classes
- * during the parsing of the XML
- *
- * @return array All elements not matched to data model classes during parsing
- */
- public function getExtensionElements()
- {
- return $this->_extensionElements;
- }
- /**
- * Sets an array of all elements not matched to data model classes
- * during the parsing of the XML. This method can be used to add arbitrary
- * child XML elements to any data model class.
- *
- * @param array $value All extension elements
- * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
- */
- public function setExtensionElements($value)
- {
- $this->_extensionElements = $value;
- return $this;
- }
- /**
- * Returns an array of all extension attributes not transformed into data
- * model properties during parsing of the XML. Each element of the array
- * is a hashed array of the format:
- * array('namespaceUri' => string, 'name' => string, 'value' => string);
- *
- * @return array All extension attributes
- */
- public function getExtensionAttributes()
- {
- return $this->_extensionAttributes;
- }
- /**
- * Sets an array of all extension attributes not transformed into data
- * model properties during parsing of the XML. Each element of the array
- * is a hashed array of the format:
- * array('namespaceUri' => string, 'name' => string, 'value' => string);
- * This can be used to add arbitrary attributes to any data model element
- *
- * @param array $value All extension attributes
- * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
- */
- public function setExtensionAttributes($value)
- {
- $this->_extensionAttributes = $value;
- return $this;
- }
- /**
- * Retrieves a DOMElement which corresponds to this element and all
- * child properties. This is used to build an entry back into a DOM
- * and eventually XML text for sending to the server upon updates, or
- * for application storage/persistence.
- *
- * @param DOMDocument $doc The DOMDocument used to construct DOMElements
- * @return DOMElement The DOMElement representing this element and all
- * child properties.
- */
- public function getDOM($doc = null, $majorVersion = 1, $minorVersion = null)
- {
- if ($doc === null) {
- $doc = new DOMDocument('1.0', 'utf-8');
- }
- if ($this->_rootNamespaceURI != null) {
- $element = $doc->createElementNS($this->_rootNamespaceURI, $this->_rootElement);
- } elseif ($this->_rootNamespace !== null) {
- if (strpos($this->_rootElement, ':') === false) {
- $elementName = $this->_rootNamespace . ':' . $this->_rootElement;
- } else {
- $elementName = $this->_rootElement;
- }
- $element = $doc->createElementNS($this->lookupNamespace($this->_rootNamespace), $elementName);
- } else {
- $element = $doc->createElement($this->_rootElement);
- }
- if ($this->_text != null) {
- $element->appendChild($element->ownerDocument->createTextNode($this->_text));
- }
- foreach ($this->_extensionElements as $extensionElement) {
- $element->appendChild($extensionElement->getDOM($element->ownerDocument));
- }
- foreach ($this->_extensionAttributes as $attribute) {
- $element->setAttribute($attribute['name'], $attribute['value']);
- }
- return $element;
- }
- /**
- * Given a child DOMNode, tries to determine how to map the data into
- * object instance members. If no mapping is defined, Extension_Element
- * objects are created and stored in an array.
- *
- * @param DOMNode $child The DOMNode needed to be handled
- */
- protected function takeChildFromDOM($child)
- {
- if ($child->nodeType == XML_TEXT_NODE) {
- $this->_text = $child->nodeValue;
- } else {
- $extensionElement = new Zend_Gdata_App_Extension_Element();
- $extensionElement->transferFromDOM($child);
- $this->_extensionElements[] = $extensionElement;
- }
- }
- /**
- * Given a DOMNode representing an attribute, tries to map the data into
- * instance members. If no mapping is defined, the name and value are
- * stored in an array.
- *
- * @param DOMNode $attribute The DOMNode attribute needed to be handled
- */
- protected function takeAttributeFromDOM($attribute)
- {
- $arrayIndex = ($attribute->namespaceURI != '')?(
- $attribute->namespaceURI . ':' . $attribute->name):
- $attribute->name;
- $this->_extensionAttributes[$arrayIndex] =
- array('namespaceUri' => $attribute->namespaceURI,
- 'name' => $attribute->localName,
- 'value' => $attribute->nodeValue);
- }
- /**
- * Transfers each child and attribute into member variables.
- * This is called when XML is received over the wire and the data
- * model needs to be built to represent this XML.
- *
- * @param DOMNode $node The DOMNode that represents this object's data
- */
- public function transferFromDOM($node)
- {
- foreach ($node->childNodes as $child) {
- $this->takeChildFromDOM($child);
- }
- foreach ($node->attributes as $attribute) {
- $this->takeAttributeFromDOM($attribute);
- }
- }
- /**
- * Parses the provided XML text and generates data model classes for
- * each know element by turning the XML text into a DOM tree and calling
- * transferFromDOM($element). The first data model element with the same
- * name as $this->_rootElement is used and the child elements are
- * recursively parsed.
- *
- * @param string $xml The XML text to parse
- */
- public function transferFromXML($xml)
- {
- if ($xml) {
- // Load the feed as an XML DOMDocument object
- @ini_set('track_errors', 1);
- $doc = new DOMDocument();
- $success = @$doc->loadXML($xml);
- @ini_restore('track_errors');
- if (!$success) {
- require_once 'Zend/Gdata/App/Exception.php';
- throw new Zend_Gdata_App_Exception("DOMDocument cannot parse XML: $php_errormsg");
- }
- $element = $doc->getElementsByTagName($this->_rootElement)->item(0);
- if (!$element) {
- require_once 'Zend/Gdata/App/Exception.php';
- throw new Zend_Gdata_App_Exception('No root <' . $this->_rootElement . '> element');
- }
- $this->transferFromDOM($element);
- } else {
- require_once 'Zend/Gdata/App/Exception.php';
- throw new Zend_Gdata_App_Exception('XML passed to transferFromXML cannot be null');
- }
- }
- /**
- * Converts this element and all children into XML text using getDOM()
- *
- * @return string XML content
- */
- public function saveXML()
- {
- $element = $this->getDOM();
- return $element->ownerDocument->saveXML($element);
- }
- /**
- * Alias for saveXML() returns XML content for this element and all
- * children
- *
- * @return string XML content
- */
- public function getXML()
- {
- return $this->saveXML();
- }
- /**
- * Alias for saveXML()
- *
- * Can be overridden by children to provide more complex representations
- * of entries.
- *
- * @return string Encoded string content
- */
- public function encode()
- {
- return $this->saveXML();
- }
- /**
- * 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.
- *
- * @param string $prefix The namespace prefix to lookup.
- * @param integer $majorVersion The major protocol version in effect.
- * Defaults to '1'.
- * @param integer $minorVersion The minor protocol version in effect.
- * Defaults to null (use latest).
- * @return string
- */
- public function lookupNamespace($prefix,
- $majorVersion = 1,
- $minorVersion = null)
- {
- // Check for a memoized result
- $key = $prefix . ' ' .
- (is_null($majorVersion) ? 'NULL' : $majorVersion) .
- ' '. (is_null($minorVersion) ? 'NULL' : $minorVersion);
- if (array_key_exists($key, self::$_namespaceLookupCache))
- return self::$_namespaceLookupCache[$key];
- // If no match, return the prefix by default
- $result = $prefix;
- // Find tuple of keys that correspond to the namespace we should use
- if (isset($this->_namespaces[$prefix])) {
- // Major version search
- $nsData = $this->_namespaces[$prefix];
- $foundMajorV = Zend_Gdata_App_Util::findGreatestBoundedValue(
- $majorVersion, $nsData);
- // Minor version search
- $nsData = $nsData[$foundMajorV];
- $foundMinorV = Zend_Gdata_App_Util::findGreatestBoundedValue(
- $minorVersion, $nsData);
- // Extract NS
- $result = $nsData[$foundMinorV];
- }
- // Memoize result
- self::$_namespaceLookupCache[$key] = $result;
- return $result;
- }
- /**
- * 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
- * $this->lookupNamespace().
- *
- * WARNING: Currently, registering a namespace will NOT invalidate any
- * memoized data stored in $_namespaceLookupCache. Under normal
- * use, this behavior is acceptable. If you are adding
- * contradictory data to the namespace lookup table, you must
- * call flushNamespaceLookupCache().
- *
- * @param string $prefix The namespace prefix
- * @param string $namespaceUri The full namespace URI
- * @param integer $majorVersion The major protocol version in effect.
- * Defaults to '1'.
- * @param integer $minorVersion The minor protocol version in effect.
- * Defaults to null (use latest).
- * @return void
- */
- public function registerNamespace($prefix,
- $namespaceUri,
- $majorVersion = 1,
- $minorVersion = 0)
- {
- $this->_namespaces[$prefix][$majorVersion][$minorVersion] =
- $namespaceUri;
- }
- /**
- * Flush namespace lookup cache.
- *
- * Empties the namespace lookup cache. Call this function if you have
- * added data to the namespace lookup table that contradicts values that
- * may have been cached during a previous call to lookupNamespace().
- */
- public static function flushNamespaceLookupCache()
- {
- self::$_namespaceLookupCache = array();
- }
- /**
- * Add an array of namespaces to the registered list.
- *
- * Takes an array in the format of:
- * namespace prefix, namespace URI, major protocol version,
- * minor protocol version and adds them with calls to ->registerNamespace()
- *
- * @param array $namespaceArray An array of namespaces.
- * @return void
- */
- public function registerAllNamespaces($namespaceArray)
- {
- foreach($namespaceArray as $namespace) {
- $this->registerNamespace(
- $namespace[0], $namespace[1], $namespace[2], $namespace[3]);
- }
- }
- /**
- * Magic getter to allow access like $entry->foo to call $entry->getFoo()
- * Alternatively, if no getFoo() is defined, but a $_foo protected variable
- * is defined, this is returned.
- *
- * TODO Remove ability to bypass getFoo() methods??
- *
- * @param string $name The variable name sought
- */
- public function __get($name)
- {
- $method = 'get'.ucfirst($name);
- if (method_exists($this, $method)) {
- return call_user_func(array(&$this, $method));
- } else if (property_exists($this, "_${name}")) {
- return $this->{'_' . $name};
- } else {
- require_once 'Zend/Gdata/App/InvalidArgumentException.php';
- throw new Zend_Gdata_App_InvalidArgumentException(
- 'Property ' . $name . ' does not exist');
- }
- }
- /**
- * Magic setter to allow acces like $entry->foo='bar' to call
- * $entry->setFoo('bar') automatically.
- *
- * Alternatively, if no setFoo() is defined, but a $_foo protected variable
- * is defined, this is returned.
- *
- * TODO Remove ability to bypass getFoo() methods??
- *
- * @param string $name
- * @param string $value
- */
- public function __set($name, $val)
- {
- $method = 'set'.ucfirst($name);
- if (method_exists($this, $method)) {
- return call_user_func(array(&$this, $method), $val);
- } else if (isset($this->{'_' . $name}) || ($this->{'_' . $name} === null)) {
- $this->{'_' . $name} = $val;
- } else {
- require_once 'Zend/Gdata/App/InvalidArgumentException.php';
- throw new Zend_Gdata_App_InvalidArgumentException(
- 'Property ' . $name . ' does not exist');
- }
- }
- /**
- * Magic __isset method
- *
- * @param string $name
- */
- public function __isset($name)
- {
- $rc = new ReflectionClass(get_class($this));
- $privName = '_' . $name;
- if (!($rc->hasProperty($privName))) {
- require_once 'Zend/Gdata/App/InvalidArgumentException.php';
- throw new Zend_Gdata_App_InvalidArgumentException(
- 'Property ' . $name . ' does not exist');
- } else {
- if (isset($this->{$privName})) {
- if (is_array($this->{$privName})) {
- if (count($this->{$privName}) > 0) {
- return true;
- } else {
- return false;
- }
- } else {
- return true;
- }
- } else {
- return false;
- }
- }
- }
- /**
- * Magic __unset method
- *
- * @param string $name
- */
- public function __unset($name)
- {
- if (isset($this->{'_' . $name})) {
- if (is_array($this->{'_' . $name})) {
- $this->{'_' . $name} = array();
- } else {
- $this->{'_' . $name} = null;
- }
- }
- }
- /**
- * Magic toString method allows using this directly via echo
- * Works best in PHP >= 4.2.0
- *
- * @return string The text representation of this object
- */
- public function __toString()
- {
- return $this->getText();
- }
- }