[44] | 1 | <?php
|
---|
| 2 |
|
---|
| 3 | /**
|
---|
| 4 | * Zend Framework
|
---|
| 5 | *
|
---|
| 6 | * LICENSE
|
---|
| 7 | *
|
---|
| 8 | * This source file is subject to the new BSD license that is bundled
|
---|
| 9 | * with this package in the file LICENSE.txt.
|
---|
| 10 | * It is also available through the world-wide-web at this URL:
|
---|
| 11 | * http://framework.zend.com/license/new-bsd
|
---|
| 12 | * If you did not receive a copy of the license and are unable to
|
---|
| 13 | * obtain it through the world-wide-web, please send an email
|
---|
| 14 | * to license@zend.com so we can send you a copy immediately.
|
---|
| 15 | *
|
---|
| 16 | * @category Zend
|
---|
| 17 | * @package Zend_Gdata
|
---|
| 18 | * @subpackage App
|
---|
| 19 | * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
---|
| 20 | * @license http://framework.zend.com/license/new-bsd New BSD License
|
---|
| 21 | */
|
---|
| 22 |
|
---|
| 23 | /**
|
---|
| 24 | * @see Zend_Gdata_App_Util
|
---|
| 25 | */
|
---|
| 26 | require_once 'Zend/Gdata/App/Util.php';
|
---|
| 27 |
|
---|
| 28 | /**
|
---|
| 29 | * Abstract class for all XML elements
|
---|
| 30 | *
|
---|
| 31 | * @category Zend
|
---|
| 32 | * @package Zend_Gdata
|
---|
| 33 | * @subpackage App
|
---|
| 34 | * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
|
---|
| 35 | * @license http://framework.zend.com/license/new-bsd New BSD License
|
---|
| 36 | */
|
---|
| 37 | abstract class Zend_Gdata_App_Base
|
---|
| 38 | {
|
---|
| 39 |
|
---|
| 40 | /**
|
---|
| 41 | * @var string The XML element name, including prefix if desired
|
---|
| 42 | */
|
---|
| 43 | protected $_rootElement = null;
|
---|
| 44 |
|
---|
| 45 | /**
|
---|
| 46 | * @var string The XML namespace prefix
|
---|
| 47 | */
|
---|
| 48 | protected $_rootNamespace = 'atom';
|
---|
| 49 |
|
---|
| 50 | /**
|
---|
| 51 | * @var string The XML namespace URI - takes precedence over lookup up the
|
---|
| 52 | * corresponding URI for $_rootNamespace
|
---|
| 53 | */
|
---|
| 54 | protected $_rootNamespaceURI = null;
|
---|
| 55 |
|
---|
| 56 | /**
|
---|
| 57 | * @var array Leftover elements which were not handled
|
---|
| 58 | */
|
---|
| 59 | protected $_extensionElements = array();
|
---|
| 60 |
|
---|
| 61 | /**
|
---|
| 62 | * @var array Leftover attributes which were not handled
|
---|
| 63 | */
|
---|
| 64 | protected $_extensionAttributes = array();
|
---|
| 65 |
|
---|
| 66 | /**
|
---|
| 67 | * @var string XML child text node content
|
---|
| 68 | */
|
---|
| 69 | protected $_text = null;
|
---|
| 70 |
|
---|
| 71 | /**
|
---|
| 72 | * @var array Memoized results from calls to lookupNamespace() to avoid
|
---|
| 73 | * expensive calls to getGreatestBoundedValue(). The key is in the
|
---|
| 74 | * form 'prefix-majorVersion-minorVersion', and the value is the
|
---|
| 75 | * output from getGreatestBoundedValue().
|
---|
| 76 | */
|
---|
| 77 | protected static $_namespaceLookupCache = array();
|
---|
| 78 |
|
---|
| 79 | /**
|
---|
| 80 | * List of namespaces, as a three-dimensional array. The first dimension
|
---|
| 81 | * represents the namespace prefix, the second dimension represents the
|
---|
| 82 | * minimum major protocol version, and the third dimension is the minimum
|
---|
| 83 | * minor protocol version. Null keys are NOT allowed.
|
---|
| 84 | *
|
---|
| 85 | * When looking up a namespace for a given prefix, the greatest version
|
---|
| 86 | * number (both major and minor) which is less than the effective version
|
---|
| 87 | * should be used.
|
---|
| 88 | *
|
---|
| 89 | * @see lookupNamespace()
|
---|
| 90 | * @see registerNamespace()
|
---|
| 91 | * @see registerAllNamespaces()
|
---|
| 92 | * @var array
|
---|
| 93 | */
|
---|
| 94 | protected $_namespaces = array(
|
---|
| 95 | 'atom' => array(
|
---|
| 96 | 1 => array(
|
---|
| 97 | 0 => 'http://www.w3.org/2005/Atom'
|
---|
| 98 | )
|
---|
| 99 | ),
|
---|
| 100 | 'app' => array(
|
---|
| 101 | 1 => array(
|
---|
| 102 | 0 => 'http://purl.org/atom/app#'
|
---|
| 103 | ),
|
---|
| 104 | 2 => array(
|
---|
| 105 | 0 => 'http://www.w3.org/2007/app'
|
---|
| 106 | )
|
---|
| 107 | )
|
---|
| 108 | );
|
---|
| 109 |
|
---|
| 110 | public function __construct()
|
---|
| 111 | {
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | /**
|
---|
| 115 | * Returns the child text node of this element
|
---|
| 116 | * This represents any raw text contained within the XML element
|
---|
| 117 | *
|
---|
| 118 | * @return string Child text node
|
---|
| 119 | */
|
---|
| 120 | public function getText($trim = true)
|
---|
| 121 | {
|
---|
| 122 | if ($trim) {
|
---|
| 123 | return trim($this->_text);
|
---|
| 124 | } else {
|
---|
| 125 | return $this->_text;
|
---|
| 126 | }
|
---|
| 127 | }
|
---|
| 128 |
|
---|
| 129 | /**
|
---|
| 130 | * Sets the child text node of this element
|
---|
| 131 | * This represents any raw text contained within the XML element
|
---|
| 132 | *
|
---|
| 133 | * @param string $value Child text node
|
---|
| 134 | * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
|
---|
| 135 | */
|
---|
| 136 | public function setText($value)
|
---|
| 137 | {
|
---|
| 138 | $this->_text = $value;
|
---|
| 139 | return $this;
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | /**
|
---|
| 143 | * Returns an array of all elements not matched to data model classes
|
---|
| 144 | * during the parsing of the XML
|
---|
| 145 | *
|
---|
| 146 | * @return array All elements not matched to data model classes during parsing
|
---|
| 147 | */
|
---|
| 148 | public function getExtensionElements()
|
---|
| 149 | {
|
---|
| 150 | return $this->_extensionElements;
|
---|
| 151 | }
|
---|
| 152 |
|
---|
| 153 | /**
|
---|
| 154 | * Sets an array of all elements not matched to data model classes
|
---|
| 155 | * during the parsing of the XML. This method can be used to add arbitrary
|
---|
| 156 | * child XML elements to any data model class.
|
---|
| 157 | *
|
---|
| 158 | * @param array $value All extension elements
|
---|
| 159 | * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
|
---|
| 160 | */
|
---|
| 161 | public function setExtensionElements($value)
|
---|
| 162 | {
|
---|
| 163 | $this->_extensionElements = $value;
|
---|
| 164 | return $this;
|
---|
| 165 | }
|
---|
| 166 |
|
---|
| 167 | /**
|
---|
| 168 | * Returns an array of all extension attributes not transformed into data
|
---|
| 169 | * model properties during parsing of the XML. Each element of the array
|
---|
| 170 | * is a hashed array of the format:
|
---|
| 171 | * array('namespaceUri' => string, 'name' => string, 'value' => string);
|
---|
| 172 | *
|
---|
| 173 | * @return array All extension attributes
|
---|
| 174 | */
|
---|
| 175 | public function getExtensionAttributes()
|
---|
| 176 | {
|
---|
| 177 | return $this->_extensionAttributes;
|
---|
| 178 | }
|
---|
| 179 |
|
---|
| 180 | /**
|
---|
| 181 | * Sets an array of all extension attributes not transformed into data
|
---|
| 182 | * model properties during parsing of the XML. Each element of the array
|
---|
| 183 | * is a hashed array of the format:
|
---|
| 184 | * array('namespaceUri' => string, 'name' => string, 'value' => string);
|
---|
| 185 | * This can be used to add arbitrary attributes to any data model element
|
---|
| 186 | *
|
---|
| 187 | * @param array $value All extension attributes
|
---|
| 188 | * @return Zend_Gdata_App_Base Returns an object of the same type as 'this' to provide a fluent interface.
|
---|
| 189 | */
|
---|
| 190 | public function setExtensionAttributes($value)
|
---|
| 191 | {
|
---|
| 192 | $this->_extensionAttributes = $value;
|
---|
| 193 | return $this;
|
---|
| 194 | }
|
---|
| 195 |
|
---|
| 196 | /**
|
---|
| 197 | * Retrieves a DOMElement which corresponds to this element and all
|
---|
| 198 | * child properties. This is used to build an entry back into a DOM
|
---|
| 199 | * and eventually XML text for sending to the server upon updates, or
|
---|
| 200 | * for application storage/persistence.
|
---|
| 201 | *
|
---|
| 202 | * @param DOMDocument $doc The DOMDocument used to construct DOMElements
|
---|
| 203 | * @return DOMElement The DOMElement representing this element and all
|
---|
| 204 | * child properties.
|
---|
| 205 | */
|
---|
| 206 | public function getDOM($doc = null, $majorVersion = 1, $minorVersion = null)
|
---|
| 207 | {
|
---|
| 208 | if ($doc === null) {
|
---|
| 209 | $doc = new DOMDocument('1.0', 'utf-8');
|
---|
| 210 | }
|
---|
| 211 | if ($this->_rootNamespaceURI != null) {
|
---|
| 212 | $element = $doc->createElementNS($this->_rootNamespaceURI, $this->_rootElement);
|
---|
| 213 | } elseif ($this->_rootNamespace !== null) {
|
---|
| 214 | if (strpos($this->_rootElement, ':') === false) {
|
---|
| 215 | $elementName = $this->_rootNamespace . ':' . $this->_rootElement;
|
---|
| 216 | } else {
|
---|
| 217 | $elementName = $this->_rootElement;
|
---|
| 218 | }
|
---|
| 219 | $element = $doc->createElementNS($this->lookupNamespace($this->_rootNamespace), $elementName);
|
---|
| 220 | } else {
|
---|
| 221 | $element = $doc->createElement($this->_rootElement);
|
---|
| 222 | }
|
---|
| 223 | if ($this->_text != null) {
|
---|
| 224 | $element->appendChild($element->ownerDocument->createTextNode($this->_text));
|
---|
| 225 | }
|
---|
| 226 | foreach ($this->_extensionElements as $extensionElement) {
|
---|
| 227 | $element->appendChild($extensionElement->getDOM($element->ownerDocument));
|
---|
| 228 | }
|
---|
| 229 | foreach ($this->_extensionAttributes as $attribute) {
|
---|
| 230 | $element->setAttribute($attribute['name'], $attribute['value']);
|
---|
| 231 | }
|
---|
| 232 | return $element;
|
---|
| 233 | }
|
---|
| 234 |
|
---|
| 235 | /**
|
---|
| 236 | * Given a child DOMNode, tries to determine how to map the data into
|
---|
| 237 | * object instance members. If no mapping is defined, Extension_Element
|
---|
| 238 | * objects are created and stored in an array.
|
---|
| 239 | *
|
---|
| 240 | * @param DOMNode $child The DOMNode needed to be handled
|
---|
| 241 | */
|
---|
| 242 | protected function takeChildFromDOM($child)
|
---|
| 243 | {
|
---|
| 244 | if ($child->nodeType == XML_TEXT_NODE) {
|
---|
| 245 | $this->_text = $child->nodeValue;
|
---|
| 246 | } else {
|
---|
| 247 | $extensionElement = new Zend_Gdata_App_Extension_Element();
|
---|
| 248 | $extensionElement->transferFromDOM($child);
|
---|
| 249 | $this->_extensionElements[] = $extensionElement;
|
---|
| 250 | }
|
---|
| 251 | }
|
---|
| 252 |
|
---|
| 253 | /**
|
---|
| 254 | * Given a DOMNode representing an attribute, tries to map the data into
|
---|
| 255 | * instance members. If no mapping is defined, the name and value are
|
---|
| 256 | * stored in an array.
|
---|
| 257 | *
|
---|
| 258 | * @param DOMNode $attribute The DOMNode attribute needed to be handled
|
---|
| 259 | */
|
---|
| 260 | protected function takeAttributeFromDOM($attribute)
|
---|
| 261 | {
|
---|
| 262 | $arrayIndex = ($attribute->namespaceURI != '')?(
|
---|
| 263 | $attribute->namespaceURI . ':' . $attribute->name):
|
---|
| 264 | $attribute->name;
|
---|
| 265 | $this->_extensionAttributes[$arrayIndex] =
|
---|
| 266 | array('namespaceUri' => $attribute->namespaceURI,
|
---|
| 267 | 'name' => $attribute->localName,
|
---|
| 268 | 'value' => $attribute->nodeValue);
|
---|
| 269 | }
|
---|
| 270 |
|
---|
| 271 | /**
|
---|
| 272 | * Transfers each child and attribute into member variables.
|
---|
| 273 | * This is called when XML is received over the wire and the data
|
---|
| 274 | * model needs to be built to represent this XML.
|
---|
| 275 | *
|
---|
| 276 | * @param DOMNode $node The DOMNode that represents this object's data
|
---|
| 277 | */
|
---|
| 278 | public function transferFromDOM($node)
|
---|
| 279 | {
|
---|
| 280 | foreach ($node->childNodes as $child) {
|
---|
| 281 | $this->takeChildFromDOM($child);
|
---|
| 282 | }
|
---|
| 283 | foreach ($node->attributes as $attribute) {
|
---|
| 284 | $this->takeAttributeFromDOM($attribute);
|
---|
| 285 | }
|
---|
| 286 | }
|
---|
| 287 |
|
---|
| 288 | /**
|
---|
| 289 | * Parses the provided XML text and generates data model classes for
|
---|
| 290 | * each know element by turning the XML text into a DOM tree and calling
|
---|
| 291 | * transferFromDOM($element). The first data model element with the same
|
---|
| 292 | * name as $this->_rootElement is used and the child elements are
|
---|
| 293 | * recursively parsed.
|
---|
| 294 | *
|
---|
| 295 | * @param string $xml The XML text to parse
|
---|
| 296 | */
|
---|
| 297 | public function transferFromXML($xml)
|
---|
| 298 | {
|
---|
| 299 | if ($xml) {
|
---|
| 300 | // Load the feed as an XML DOMDocument object
|
---|
| 301 | @ini_set('track_errors', 1);
|
---|
| 302 | $doc = new DOMDocument();
|
---|
| 303 | $success = @$doc->loadXML($xml);
|
---|
| 304 | @ini_restore('track_errors');
|
---|
| 305 | if (!$success) {
|
---|
| 306 | require_once 'Zend/Gdata/App/Exception.php';
|
---|
| 307 | throw new Zend_Gdata_App_Exception("DOMDocument cannot parse XML: $php_errormsg");
|
---|
| 308 | }
|
---|
| 309 | $element = $doc->getElementsByTagName($this->_rootElement)->item(0);
|
---|
| 310 | if (!$element) {
|
---|
| 311 | require_once 'Zend/Gdata/App/Exception.php';
|
---|
| 312 | throw new Zend_Gdata_App_Exception('No root <' . $this->_rootElement . '> element');
|
---|
| 313 | }
|
---|
| 314 | $this->transferFromDOM($element);
|
---|
| 315 | } else {
|
---|
| 316 | require_once 'Zend/Gdata/App/Exception.php';
|
---|
| 317 | throw new Zend_Gdata_App_Exception('XML passed to transferFromXML cannot be null');
|
---|
| 318 | }
|
---|
| 319 | }
|
---|
| 320 |
|
---|
| 321 | /**
|
---|
| 322 | * Converts this element and all children into XML text using getDOM()
|
---|
| 323 | *
|
---|
| 324 | * @return string XML content
|
---|
| 325 | */
|
---|
| 326 | public function saveXML()
|
---|
| 327 | {
|
---|
| 328 | $element = $this->getDOM();
|
---|
| 329 | return $element->ownerDocument->saveXML($element);
|
---|
| 330 | }
|
---|
| 331 |
|
---|
| 332 | /**
|
---|
| 333 | * Alias for saveXML() returns XML content for this element and all
|
---|
| 334 | * children
|
---|
| 335 | *
|
---|
| 336 | * @return string XML content
|
---|
| 337 | */
|
---|
| 338 | public function getXML()
|
---|
| 339 | {
|
---|
| 340 | return $this->saveXML();
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | /**
|
---|
| 344 | * Alias for saveXML()
|
---|
| 345 | *
|
---|
| 346 | * Can be overridden by children to provide more complex representations
|
---|
| 347 | * of entries.
|
---|
| 348 | *
|
---|
| 349 | * @return string Encoded string content
|
---|
| 350 | */
|
---|
| 351 | public function encode()
|
---|
| 352 | {
|
---|
| 353 | return $this->saveXML();
|
---|
| 354 | }
|
---|
| 355 |
|
---|
| 356 | /**
|
---|
| 357 | * Get the full version of a namespace prefix
|
---|
| 358 | *
|
---|
| 359 | * Looks up a prefix (atom:, etc.) in the list of registered
|
---|
| 360 | * namespaces and returns the full namespace URI if
|
---|
| 361 | * available. Returns the prefix, unmodified, if it's not
|
---|
| 362 | * registered.
|
---|
| 363 | *
|
---|
| 364 | * @param string $prefix The namespace prefix to lookup.
|
---|
| 365 | * @param integer $majorVersion The major protocol version in effect.
|
---|
| 366 | * Defaults to '1'.
|
---|
| 367 | * @param integer $minorVersion The minor protocol version in effect.
|
---|
| 368 | * Defaults to null (use latest).
|
---|
| 369 | * @return string
|
---|
| 370 | */
|
---|
| 371 | public function lookupNamespace($prefix,
|
---|
| 372 | $majorVersion = 1,
|
---|
| 373 | $minorVersion = null)
|
---|
| 374 | {
|
---|
| 375 | // Check for a memoized result
|
---|
| 376 | $key = $prefix . ' ' .
|
---|
| 377 | (is_null($majorVersion) ? 'NULL' : $majorVersion) .
|
---|
| 378 | ' '. (is_null($minorVersion) ? 'NULL' : $minorVersion);
|
---|
| 379 | if (array_key_exists($key, self::$_namespaceLookupCache))
|
---|
| 380 | return self::$_namespaceLookupCache[$key];
|
---|
| 381 | // If no match, return the prefix by default
|
---|
| 382 | $result = $prefix;
|
---|
| 383 |
|
---|
| 384 | // Find tuple of keys that correspond to the namespace we should use
|
---|
| 385 | if (isset($this->_namespaces[$prefix])) {
|
---|
| 386 | // Major version search
|
---|
| 387 | $nsData = $this->_namespaces[$prefix];
|
---|
| 388 | $foundMajorV = Zend_Gdata_App_Util::findGreatestBoundedValue(
|
---|
| 389 | $majorVersion, $nsData);
|
---|
| 390 | // Minor version search
|
---|
| 391 | $nsData = $nsData[$foundMajorV];
|
---|
| 392 | $foundMinorV = Zend_Gdata_App_Util::findGreatestBoundedValue(
|
---|
| 393 | $minorVersion, $nsData);
|
---|
| 394 | // Extract NS
|
---|
| 395 | $result = $nsData[$foundMinorV];
|
---|
| 396 | }
|
---|
| 397 |
|
---|
| 398 | // Memoize result
|
---|
| 399 | self::$_namespaceLookupCache[$key] = $result;
|
---|
| 400 |
|
---|
| 401 | return $result;
|
---|
| 402 | }
|
---|
| 403 |
|
---|
| 404 | /**
|
---|
| 405 | * Add a namespace and prefix to the registered list
|
---|
| 406 | *
|
---|
| 407 | * Takes a prefix and a full namespace URI and adds them to the
|
---|
| 408 | * list of registered namespaces for use by
|
---|
| 409 | * $this->lookupNamespace().
|
---|
| 410 | *
|
---|
| 411 | * WARNING: Currently, registering a namespace will NOT invalidate any
|
---|
| 412 | * memoized data stored in $_namespaceLookupCache. Under normal
|
---|
| 413 | * use, this behavior is acceptable. If you are adding
|
---|
| 414 | * contradictory data to the namespace lookup table, you must
|
---|
| 415 | * call flushNamespaceLookupCache().
|
---|
| 416 | *
|
---|
| 417 | * @param string $prefix The namespace prefix
|
---|
| 418 | * @param string $namespaceUri The full namespace URI
|
---|
| 419 | * @param integer $majorVersion The major protocol version in effect.
|
---|
| 420 | * Defaults to '1'.
|
---|
| 421 | * @param integer $minorVersion The minor protocol version in effect.
|
---|
| 422 | * Defaults to null (use latest).
|
---|
| 423 | * @return void
|
---|
| 424 | */
|
---|
| 425 | public function registerNamespace($prefix,
|
---|
| 426 | $namespaceUri,
|
---|
| 427 | $majorVersion = 1,
|
---|
| 428 | $minorVersion = 0)
|
---|
| 429 | {
|
---|
| 430 | $this->_namespaces[$prefix][$majorVersion][$minorVersion] =
|
---|
| 431 | $namespaceUri;
|
---|
| 432 | }
|
---|
| 433 |
|
---|
| 434 | /**
|
---|
| 435 | * Flush namespace lookup cache.
|
---|
| 436 | *
|
---|
| 437 | * Empties the namespace lookup cache. Call this function if you have
|
---|
| 438 | * added data to the namespace lookup table that contradicts values that
|
---|
| 439 | * may have been cached during a previous call to lookupNamespace().
|
---|
| 440 | */
|
---|
| 441 | public static function flushNamespaceLookupCache()
|
---|
| 442 | {
|
---|
| 443 | self::$_namespaceLookupCache = array();
|
---|
| 444 | }
|
---|
| 445 |
|
---|
| 446 | /**
|
---|
| 447 | * Add an array of namespaces to the registered list.
|
---|
| 448 | *
|
---|
| 449 | * Takes an array in the format of:
|
---|
| 450 | * namespace prefix, namespace URI, major protocol version,
|
---|
| 451 | * minor protocol version and adds them with calls to ->registerNamespace()
|
---|
| 452 | *
|
---|
| 453 | * @param array $namespaceArray An array of namespaces.
|
---|
| 454 | * @return void
|
---|
| 455 | */
|
---|
| 456 | public function registerAllNamespaces($namespaceArray)
|
---|
| 457 | {
|
---|
| 458 | foreach($namespaceArray as $namespace) {
|
---|
| 459 | $this->registerNamespace(
|
---|
| 460 | $namespace[0], $namespace[1], $namespace[2], $namespace[3]);
|
---|
| 461 | }
|
---|
| 462 | }
|
---|
| 463 |
|
---|
| 464 |
|
---|
| 465 | /**
|
---|
| 466 | * Magic getter to allow access like $entry->foo to call $entry->getFoo()
|
---|
| 467 | * Alternatively, if no getFoo() is defined, but a $_foo protected variable
|
---|
| 468 | * is defined, this is returned.
|
---|
| 469 | *
|
---|
| 470 | * TODO Remove ability to bypass getFoo() methods??
|
---|
| 471 | *
|
---|
| 472 | * @param string $name The variable name sought
|
---|
| 473 | */
|
---|
| 474 | public function __get($name)
|
---|
| 475 | {
|
---|
| 476 | $method = 'get'.ucfirst($name);
|
---|
| 477 | if (method_exists($this, $method)) {
|
---|
| 478 | return call_user_func(array(&$this, $method));
|
---|
| 479 | } else if (property_exists($this, "_${name}")) {
|
---|
| 480 | return $this->{'_' . $name};
|
---|
| 481 | } else {
|
---|
| 482 | require_once 'Zend/Gdata/App/InvalidArgumentException.php';
|
---|
| 483 | throw new Zend_Gdata_App_InvalidArgumentException(
|
---|
| 484 | 'Property ' . $name . ' does not exist');
|
---|
| 485 | }
|
---|
| 486 | }
|
---|
| 487 |
|
---|
| 488 | /**
|
---|
| 489 | * Magic setter to allow acces like $entry->foo='bar' to call
|
---|
| 490 | * $entry->setFoo('bar') automatically.
|
---|
| 491 | *
|
---|
| 492 | * Alternatively, if no setFoo() is defined, but a $_foo protected variable
|
---|
| 493 | * is defined, this is returned.
|
---|
| 494 | *
|
---|
| 495 | * TODO Remove ability to bypass getFoo() methods??
|
---|
| 496 | *
|
---|
| 497 | * @param string $name
|
---|
| 498 | * @param string $value
|
---|
| 499 | */
|
---|
| 500 | public function __set($name, $val)
|
---|
| 501 | {
|
---|
| 502 | $method = 'set'.ucfirst($name);
|
---|
| 503 | if (method_exists($this, $method)) {
|
---|
| 504 | return call_user_func(array(&$this, $method), $val);
|
---|
| 505 | } else if (isset($this->{'_' . $name}) || ($this->{'_' . $name} === null)) {
|
---|
| 506 | $this->{'_' . $name} = $val;
|
---|
| 507 | } else {
|
---|
| 508 | require_once 'Zend/Gdata/App/InvalidArgumentException.php';
|
---|
| 509 | throw new Zend_Gdata_App_InvalidArgumentException(
|
---|
| 510 | 'Property ' . $name . ' does not exist');
|
---|
| 511 | }
|
---|
| 512 | }
|
---|
| 513 |
|
---|
| 514 | /**
|
---|
| 515 | * Magic __isset method
|
---|
| 516 | *
|
---|
| 517 | * @param string $name
|
---|
| 518 | */
|
---|
| 519 | public function __isset($name)
|
---|
| 520 | {
|
---|
| 521 | $rc = new ReflectionClass(get_class($this));
|
---|
| 522 | $privName = '_' . $name;
|
---|
| 523 | if (!($rc->hasProperty($privName))) {
|
---|
| 524 | require_once 'Zend/Gdata/App/InvalidArgumentException.php';
|
---|
| 525 | throw new Zend_Gdata_App_InvalidArgumentException(
|
---|
| 526 | 'Property ' . $name . ' does not exist');
|
---|
| 527 | } else {
|
---|
| 528 | if (isset($this->{$privName})) {
|
---|
| 529 | if (is_array($this->{$privName})) {
|
---|
| 530 | if (count($this->{$privName}) > 0) {
|
---|
| 531 | return true;
|
---|
| 532 | } else {
|
---|
| 533 | return false;
|
---|
| 534 | }
|
---|
| 535 | } else {
|
---|
| 536 | return true;
|
---|
| 537 | }
|
---|
| 538 | } else {
|
---|
| 539 | return false;
|
---|
| 540 | }
|
---|
| 541 | }
|
---|
| 542 | }
|
---|
| 543 |
|
---|
| 544 | /**
|
---|
| 545 | * Magic __unset method
|
---|
| 546 | *
|
---|
| 547 | * @param string $name
|
---|
| 548 | */
|
---|
| 549 | public function __unset($name)
|
---|
| 550 | {
|
---|
| 551 | if (isset($this->{'_' . $name})) {
|
---|
| 552 | if (is_array($this->{'_' . $name})) {
|
---|
| 553 | $this->{'_' . $name} = array();
|
---|
| 554 | } else {
|
---|
| 555 | $this->{'_' . $name} = null;
|
---|
| 556 | }
|
---|
| 557 | }
|
---|
| 558 | }
|
---|
| 559 |
|
---|
| 560 | /**
|
---|
| 561 | * Magic toString method allows using this directly via echo
|
---|
| 562 | * Works best in PHP >= 4.2.0
|
---|
| 563 | *
|
---|
| 564 | * @return string The text representation of this object
|
---|
| 565 | */
|
---|
| 566 | public function __toString()
|
---|
| 567 | {
|
---|
| 568 | return $this->getText();
|
---|
| 569 | }
|
---|
| 570 |
|
---|
| 571 | }
|
---|