web/lib/Zend/Feed/Abstract.php
changeset 64 162c1de6545a
parent 19 1c2f13fd785c
child 68 ecaf28ffe26e
equal deleted inserted replaced
63:5b37998e522e 64:162c1de6545a
       
     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_Feed
       
    18  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    19  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    20  * @version    $Id: Abstract.php 20096 2010-01-06 02:05:09Z bkarwin $
       
    21  */
       
    22 
       
    23 
       
    24 /**
       
    25  * @see Zend_Feed_Element
       
    26  */
       
    27 require_once 'Zend/Feed/Element.php';
       
    28 
       
    29 
       
    30 /**
       
    31  * The Zend_Feed_Abstract class is an abstract class representing feeds.
       
    32  *
       
    33  * Zend_Feed_Abstract implements two core PHP 5 interfaces: ArrayAccess and
       
    34  * Iterator. In both cases the collection being treated as an array is
       
    35  * considered to be the entry collection, such that iterating over the
       
    36  * feed takes you through each of the feed.s entries.
       
    37  *
       
    38  * @category   Zend
       
    39  * @package    Zend_Feed
       
    40  * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
       
    41  * @license    http://framework.zend.com/license/new-bsd     New BSD License
       
    42  */
       
    43 abstract class Zend_Feed_Abstract extends Zend_Feed_Element implements Iterator, Countable
       
    44 {
       
    45     /**
       
    46      * Current index on the collection of feed entries for the
       
    47      * Iterator implementation.
       
    48      *
       
    49      * @var integer
       
    50      */
       
    51     protected $_entryIndex = 0;
       
    52 
       
    53     /**
       
    54      * Cache of feed entries.
       
    55      *
       
    56      * @var array
       
    57      */
       
    58     protected $_entries;
       
    59 
       
    60     /**
       
    61      * Feed constructor
       
    62      *
       
    63      * The Zend_Feed_Abstract constructor takes the URI of a feed or a
       
    64      * feed represented as a string and loads it as XML.
       
    65      *
       
    66      * @param  string $uri The full URI of the feed to load, or NULL if not retrieved via HTTP or as an array.
       
    67      * @param  string $string The feed as a string, or NULL if retrieved via HTTP or as an array.
       
    68      * @param  Zend_Feed_Builder_Interface $builder The feed as a builder instance or NULL if retrieved as a string or via HTTP.
       
    69      * @return void
       
    70      * @throws Zend_Feed_Exception If loading the feed failed.
       
    71      */
       
    72     public function __construct($uri = null, $string = null, Zend_Feed_Builder_Interface $builder = null)
       
    73     {
       
    74         if ($uri !== null) {
       
    75             // Retrieve the feed via HTTP
       
    76             $client = Zend_Feed::getHttpClient();
       
    77             $client->setUri($uri);
       
    78             $response = $client->request('GET');
       
    79             if ($response->getStatus() !== 200) {
       
    80                 /**
       
    81                  * @see Zend_Feed_Exception
       
    82                  */
       
    83                 require_once 'Zend/Feed/Exception.php';
       
    84                 throw new Zend_Feed_Exception('Feed failed to load, got response code ' . $response->getStatus());
       
    85             }
       
    86             $this->_element = $response->getBody();
       
    87             $this->__wakeup();
       
    88         } elseif ($string !== null) {
       
    89             // Retrieve the feed from $string
       
    90             $this->_element = $string;
       
    91             $this->__wakeup();
       
    92         } else {
       
    93             // Generate the feed from the array
       
    94             $header = $builder->getHeader();
       
    95             $this->_element = new DOMDocument('1.0', $header['charset']);
       
    96             $root = $this->_mapFeedHeaders($header);
       
    97             $this->_mapFeedEntries($root, $builder->getEntries());
       
    98             $this->_element = $root;
       
    99             $this->_buildEntryCache();
       
   100         }
       
   101     }
       
   102 
       
   103 
       
   104     /**
       
   105      * Load the feed as an XML DOMDocument object
       
   106      *
       
   107      * @return void
       
   108      * @throws Zend_Feed_Exception
       
   109      */
       
   110     public function __wakeup()
       
   111     {
       
   112         @ini_set('track_errors', 1);
       
   113         $doc = new DOMDocument;
       
   114         $status = @$doc->loadXML($this->_element);
       
   115         @ini_restore('track_errors');
       
   116 
       
   117         if (!$status) {
       
   118             // prevent the class to generate an undefined variable notice (ZF-2590)
       
   119             if (!isset($php_errormsg)) {
       
   120                 if (function_exists('xdebug_is_enabled')) {
       
   121                     $php_errormsg = '(error message not available, when XDebug is running)';
       
   122                 } else {
       
   123                     $php_errormsg = '(error message not available)';
       
   124                 }
       
   125             }
       
   126 
       
   127             /**
       
   128              * @see Zend_Feed_Exception
       
   129              */
       
   130             require_once 'Zend/Feed/Exception.php';
       
   131             throw new Zend_Feed_Exception("DOMDocument cannot parse XML: $php_errormsg");
       
   132         }
       
   133 
       
   134         $this->_element = $doc;
       
   135     }
       
   136 
       
   137 
       
   138     /**
       
   139      * Prepare for serialiation
       
   140      *
       
   141      * @return array
       
   142      */
       
   143     public function __sleep()
       
   144     {
       
   145         $this->_element = $this->saveXML();
       
   146 
       
   147         return array('_element');
       
   148     }
       
   149 
       
   150 
       
   151     /**
       
   152      * Cache the individual feed elements so they don't need to be
       
   153      * searched for on every operation.
       
   154      *
       
   155      * @return void
       
   156      */
       
   157     protected function _buildEntryCache()
       
   158     {
       
   159         $this->_entries = array();
       
   160         foreach ($this->_element->childNodes as $child) {
       
   161             if ($child->localName == $this->_entryElementName) {
       
   162                 $this->_entries[] = $child;
       
   163             }
       
   164         }
       
   165     }
       
   166 
       
   167 
       
   168     /**
       
   169      * Get the number of entries in this feed object.
       
   170      *
       
   171      * @return integer Entry count.
       
   172      */
       
   173     public function count()
       
   174     {
       
   175         return count($this->_entries);
       
   176     }
       
   177 
       
   178 
       
   179     /**
       
   180      * Required by the Iterator interface.
       
   181      *
       
   182      * @return void
       
   183      */
       
   184     public function rewind()
       
   185     {
       
   186         $this->_entryIndex = 0;
       
   187     }
       
   188 
       
   189 
       
   190     /**
       
   191      * Required by the Iterator interface.
       
   192      *
       
   193      * @return mixed The current row, or null if no rows.
       
   194      */
       
   195     public function current()
       
   196     {
       
   197         return new $this->_entryClassName(
       
   198             null,
       
   199             $this->_entries[$this->_entryIndex]);
       
   200     }
       
   201 
       
   202 
       
   203     /**
       
   204      * Required by the Iterator interface.
       
   205      *
       
   206      * @return mixed The current row number (starts at 0), or NULL if no rows
       
   207      */
       
   208     public function key()
       
   209     {
       
   210         return $this->_entryIndex;
       
   211     }
       
   212 
       
   213 
       
   214     /**
       
   215      * Required by the Iterator interface.
       
   216      *
       
   217      * @return mixed The next row, or null if no more rows.
       
   218      */
       
   219     public function next()
       
   220     {
       
   221         ++$this->_entryIndex;
       
   222     }
       
   223 
       
   224 
       
   225     /**
       
   226      * Required by the Iterator interface.
       
   227      *
       
   228      * @return boolean Whether the iteration is valid
       
   229      */
       
   230     public function valid()
       
   231     {
       
   232         return 0 <= $this->_entryIndex && $this->_entryIndex < $this->count();
       
   233     }
       
   234 
       
   235     /**
       
   236      * Generate the header of the feed when working in write mode
       
   237      *
       
   238      * @param  array $array the data to use
       
   239      * @return DOMElement root node
       
   240      */
       
   241     abstract protected function _mapFeedHeaders($array);
       
   242 
       
   243     /**
       
   244      * Generate the entries of the feed when working in write mode
       
   245      *
       
   246      * @param  DOMElement $root the root node to use
       
   247      * @param  array $array the data to use
       
   248      * @return DOMElement root node
       
   249      */
       
   250     abstract protected function _mapFeedEntries(DOMElement $root, $array);
       
   251 
       
   252     /**
       
   253      * Send feed to a http client with the correct header
       
   254      *
       
   255      * @throws Zend_Feed_Exception if headers have already been sent
       
   256      * @return void
       
   257      */
       
   258     abstract public function send();
       
   259 }