]> git.mxchange.org Git - friendica.git/blob - vendor/smarty/smarty/libs/sysplugins/smarty_internal_runtime_foreach.php
Add Smarty to Composer
[friendica.git] / vendor / smarty / smarty / libs / sysplugins / smarty_internal_runtime_foreach.php
1 <?php
2
3 /**
4  * Foreach Runtime Methods count(), init(), restore()
5  *
6  * @package    Smarty
7  * @subpackage PluginsInternal
8  * @author     Uwe Tews
9  *
10  */
11 class Smarty_Internal_Runtime_Foreach
12 {
13
14     /**
15      * Stack of saved variables
16      *
17      * @var array
18      */
19     private $stack = array();
20
21     /**
22      * Init foreach loop
23      *  - save item and key variables, named foreach property data if defined
24      *  - init item and key variables, named foreach property data if required
25      *  - count total if required
26      *
27      * @param \Smarty_Internal_Template $tpl
28      * @param mixed                     $from       values to loop over
29      * @param string                    $item       variable name
30      * @param bool                      $needTotal  flag if we need to count values
31      * @param null|string               $key        variable name
32      * @param null|string               $name       of named foreach
33      * @param array                     $properties of named foreach
34      *
35      * @return mixed $from
36      */
37     public function init(Smarty_Internal_Template $tpl, $from, $item, $needTotal = false, $key = null, $name = null,
38                          $properties = array())
39     {
40         $saveVars = array();
41         $total = null;
42         if (!is_array($from)) {
43             if (is_object($from)) {
44                 $total = $this->count($from);
45             } else {
46                 settype($from, 'array');
47             }
48         }
49         if (!isset($total)) {
50             $total = empty($from) ? 0 : (($needTotal || isset($properties[ 'total' ])) ? count($from) : 1);
51         }
52         if (isset($tpl->tpl_vars[ $item ])) {
53             $saveVars[ 'item' ] = array($item, $tpl->tpl_vars[ $item ]);
54         }
55         $tpl->tpl_vars[ $item ] = new Smarty_Variable(null, $tpl->isRenderingCache);
56         if ($total === 0) {
57             $from = null;
58         } else {
59             if ($key) {
60                 if (isset($tpl->tpl_vars[ $key ])) {
61                     $saveVars[ 'key' ] = array($key, $tpl->tpl_vars[ $key ]);
62                 }
63                 $tpl->tpl_vars[ $key ] = new Smarty_Variable(null, $tpl->isRenderingCache);
64             }
65         }
66         if ($needTotal) {
67             $tpl->tpl_vars[ $item ]->total = $total;
68         }
69         if ($name) {
70             $namedVar = "__smarty_foreach_{$name}";
71             if (isset($tpl->tpl_vars[ $namedVar ])) {
72                 $saveVars[ 'named' ] = array($namedVar, $tpl->tpl_vars[ $namedVar ]);
73             }
74             $namedProp = array();
75             if (isset($properties[ 'total' ])) {
76                 $namedProp[ 'total' ] = $total;
77             }
78             if (isset($properties[ 'iteration' ])) {
79                 $namedProp[ 'iteration' ] = 0;
80             }
81             if (isset($properties[ 'index' ])) {
82                 $namedProp[ 'index' ] = - 1;
83             }
84             if (isset($properties[ 'show' ])) {
85                 $namedProp[ 'show' ] = ($total > 0);
86             }
87             $tpl->tpl_vars[ $namedVar ] = new Smarty_Variable($namedProp);
88         }
89         $this->stack[] = $saveVars;
90         return $from;
91     }
92
93     /**
94      * Restore saved variables
95      *
96      * will be called by {break n} or {continue n} for the required number of levels
97      *
98      * @param \Smarty_Internal_Template $tpl
99      * @param int                       $levels number of levels
100      */
101     public function restore(Smarty_Internal_Template $tpl, $levels = 1)
102     {
103         while ($levels) {
104             $saveVars = array_pop($this->stack);
105             if (!empty($saveVars)) {
106                 if (isset($saveVars[ 'item' ])) {
107                     $item = &$saveVars[ 'item' ];
108                     $tpl->tpl_vars[ $item[ 0 ] ]->value = $item[ 1 ]->value;
109                 }
110                 if (isset($saveVars[ 'key' ])) {
111                     $tpl->tpl_vars[ $saveVars[ 'key' ][ 0 ] ] = $saveVars[ 'key' ][ 1 ];
112                 }
113                 if (isset($saveVars[ 'named' ])) {
114                     $tpl->tpl_vars[ $saveVars[ 'named' ][ 0 ] ] = $saveVars[ 'named' ][ 1 ];
115                 }
116             }
117             $levels--;
118         }
119     }
120
121     /*
122     *
123      * [util function] counts an array, arrayAccess/traversable or PDOStatement object
124      *
125      * @param  mixed $value
126      *
127      * @return int   the count for arrays and objects that implement countable, 1 for other objects that don't, and 0
128      *               for empty elements
129      */
130     public function count($value)
131     {
132         if ($value instanceof Countable) {
133             return count($value);
134         } elseif ($value instanceof IteratorAggregate) {
135             // Note: getIterator() returns a Traversable, not an Iterator
136             // thus rewind() and valid() methods may not be present
137             return iterator_count($value->getIterator());
138         } elseif ($value instanceof Iterator) {
139             return $value instanceof Generator ? 1 : iterator_count($value);
140         } elseif ($value instanceof PDOStatement) {
141             return $value->rowCount();
142         } elseif ($value instanceof Traversable) {
143             return iterator_count($value);
144         } elseif ($value instanceof ArrayAccess) {
145             return $value->offsetExists(0) ? 1 : 0;
146         }
147         return count((array) $value);
148     }
149 }