1<?php
2/**
3 * @author   Chuck Hagenbuch <chuck@horde.org>
4 * @license  http://www.horde.org/licenses/bsd BSD
5 * @category Horde
6 * @package  Xml_Element
7 */
8
9/**
10 * @author   Chuck Hagenbuch <chuck@horde.org>
11 * @license  http://www.horde.org/licenses/bsd BSD
12 * @category Horde
13 * @package  Xml_Element
14 */
15abstract class Horde_Xml_Element_List extends Horde_Xml_Element implements Countable, Iterator
16{
17    /**
18     * Cache of list items.
19     * @var array
20     */
21    protected $_listItems;
22
23    /**
24     * Current index on the collection of list items for the Iterator
25     * implementation.
26     * @var integer
27     */
28    protected $_listItemIndex = 0;
29
30    /**
31     * The classname for individual list items.
32     * @var string
33     */
34    protected $_listItemClassName = 'Horde_Xml_Element';
35
36    /**
37     * Ensure that $_listItems is populated by calling the concrete implementation's
38     * _buildItemsCache() method.
39     */
40    public function __wakeup()
41    {
42        parent::__wakeup();
43
44        $this->_listItems = $this->_buildListItemCache();
45    }
46
47    /**
48     * Called by __wakeup to cache list items. Must be implemented in the
49     * extending class to return the array of list items.
50     * @return array
51     */
52    abstract protected function _buildListItemCache();
53
54    /**
55     * Get the number of items in this list.
56     *
57     * @return integer Item count.
58     */
59    public function count()
60    {
61        return count($this->_listItems);
62    }
63
64    /**
65     * Required by the Iterator interface.
66     *
67     * @internal
68     */
69    public function rewind()
70    {
71        $this->_listItemIndex = 0;
72    }
73
74    /**
75     * Required by the Iterator interface.
76     *
77     * @internal
78     *
79     * @return mixed The current row, or null if no rows.
80     */
81    public function current()
82    {
83        return new $this->_listItemClassName(
84            $this->_listItems[$this->_listItemIndex]);
85    }
86
87    /**
88     * Required by the Iterator interface.
89     *
90     * @internal
91     *
92     * @return mixed The current row number (starts at 0), or null if no rows
93     */
94    public function key()
95    {
96        return $this->_listItemIndex;
97    }
98
99    /**
100     * Required by the Iterator interface.
101     *
102     * @internal
103     *
104     * @return mixed The next row, or null if no more rows.
105     */
106    public function next()
107    {
108        ++$this->_listItemIndex;
109    }
110
111    /**
112     * Required by the Iterator interface.
113     *
114     * @internal
115     *
116     * @return boolean Whether the iteration is valid
117     */
118    public function valid()
119    {
120        return (0 <= $this->_listItemIndex && $this->_listItemIndex < count($this->_listItems));
121    }
122
123}
124