]> git.mxchange.org Git - friendica.git/blob - vendor/smarty/smarty/libs/sysplugins/smarty_internal_compile_private_foreachsection.php
Add Smarty to Composer
[friendica.git] / vendor / smarty / smarty / libs / sysplugins / smarty_internal_compile_private_foreachsection.php
1 <?php
2 /**
3  * Smarty Internal Plugin Compile ForeachSection
4  * Shared methods for {foreach} {section} tags
5  *
6  * @package    Smarty
7  * @subpackage Compiler
8  * @author     Uwe Tews
9  */
10
11 /**
12  * Smarty Internal Plugin Compile ForeachSection Class
13  *
14  * @package    Smarty
15  * @subpackage Compiler
16  */
17 class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_CompileBase
18 {
19
20     /**
21      * Preg search pattern
22      *
23      * @var string
24      */
25     private $propertyPreg = '';
26
27     /**
28      * Offsets in preg match result
29      *
30      * @var array
31      */
32     private $resultOffsets = array();
33
34     /**
35      * Start offset
36      *
37      * @var int
38      */
39     private $startOffset = 0;
40
41     /**
42      * Name of this tag
43      *
44      * @var string
45      */
46     public $tagName = '';
47
48     /**
49      * Valid properties of $smarty.xxx variable
50      *
51      * @var array
52      */
53     public $nameProperties = array();
54
55     /**
56      * {section} tag has no item properties
57      *
58      * @var array
59      */
60     public $itemProperties = null;
61
62     /**
63      * {section} tag has always name attribute
64      *
65      * @var bool
66      */
67     public $isNamed = true;
68
69     /**
70      * @var array
71      */
72     public $matchResults = array();
73
74     /**
75      * Scan sources for used tag attributes
76      *
77      * @param  array                                $attributes
78      * @param \Smarty_Internal_TemplateCompilerBase $compiler
79      */
80     public function scanForProperties($attributes, Smarty_Internal_TemplateCompilerBase $compiler)
81     {
82         $this->propertyPreg = '~(';
83         $this->startOffset = 0;
84         $this->resultOffsets = array();
85         $this->matchResults = array('named' => array(), 'item' => array());
86         if ($this->isNamed) {
87             $this->buildPropertyPreg(true, $attributes);
88         }
89         if (isset($this->itemProperties)) {
90             if ($this->isNamed) {
91                 $this->propertyPreg .= '|';
92             }
93             $this->buildPropertyPreg(false, $attributes);
94         }
95         $this->propertyPreg .= ')\W~i';
96         // Template source
97         $this->matchTemplateSource($compiler);
98         // Parent template source
99         $this->matchParentTemplateSource($compiler);
100         // {block} source
101         $this->matchBlockSource($compiler);
102     }
103
104     /**
105      * Build property preg string
106      *
107      * @param bool  $named
108      * @param array $attributes
109      */
110     public function buildPropertyPreg($named, $attributes)
111     {
112         if ($named) {
113             $this->resultOffsets[ 'named' ] = $this->startOffset + 3;
114             $this->propertyPreg .= "([\$]smarty[.]{$this->tagName}[.]{$attributes['name']}[.](";
115             $properties = $this->nameProperties;
116         } else {
117             $this->resultOffsets[ 'item' ] = $this->startOffset + 3;
118             $this->propertyPreg .= "([\$]{$attributes['item']}[@](";
119             $properties = $this->itemProperties;
120         }
121         $this->startOffset += count($properties) + 2;
122         $propName = reset($properties);
123         while ($propName) {
124             $this->propertyPreg .= "({$propName})";
125             $propName = next($properties);
126             if ($propName) {
127                 $this->propertyPreg .= '|';
128             }
129         }
130         $this->propertyPreg .= '))';
131     }
132
133     /**
134      * Find matches in source string
135      *
136      * @param string $source
137      */
138     public function matchProperty($source)
139     {
140         preg_match_all($this->propertyPreg, $source, $match, PREG_SET_ORDER);
141         foreach ($this->resultOffsets as $key => $offset) {
142             foreach ($match as $m) {
143                 if (isset($m[ $offset ]) && !empty($m[ $offset ])) {
144                     $this->matchResults[ $key ][ strtolower($m[ $offset ]) ] = true;
145                 }
146             }
147         }
148     }
149
150     /**
151      * Find matches in template source
152      *
153      * @param \Smarty_Internal_TemplateCompilerBase $compiler
154      */
155     public function matchTemplateSource(Smarty_Internal_TemplateCompilerBase $compiler)
156     {
157         $this->matchProperty($compiler->parser->lex->data);
158     }
159
160     /**
161      * Find matches in all parent template source
162      *
163      * @param \Smarty_Internal_TemplateCompilerBase $compiler
164      */
165     public function matchParentTemplateSource(Smarty_Internal_TemplateCompilerBase $compiler)
166     {
167         // search parent compiler template source
168         $nextCompiler = $compiler;
169         while ($nextCompiler !== $nextCompiler->parent_compiler) {
170             $nextCompiler = $nextCompiler->parent_compiler;
171             if ($compiler !== $nextCompiler) {
172                 // get template source
173                 $_content = $nextCompiler->template->source->getContent();
174                 if ($_content != '') {
175                     // run pre filter if required
176                     if ((isset($nextCompiler->smarty->autoload_filters[ 'pre' ]) ||
177                          isset($nextCompiler->smarty->registered_filters[ 'pre' ]))
178                     ) {
179                         $_content = $nextCompiler->smarty->ext->_filterHandler->runFilter('pre', $_content,
180                                                                                           $nextCompiler->template);
181                     }
182                     $this->matchProperty($_content);
183                 }
184             }
185         }
186     }
187
188     /**
189      * Find matches in {block} tag source
190      *
191      * @param \Smarty_Internal_TemplateCompilerBase $compiler
192      */
193     public function matchBlockSource(Smarty_Internal_TemplateCompilerBase $compiler)
194     {
195     }
196
197     /**
198      * Compiles code for the {$smarty.foreach.xxx} or {$smarty.section.xxx}tag
199      *
200      * @param  array                                $args      array with attributes from parser
201      * @param \Smarty_Internal_TemplateCompilerBase $compiler  compiler object
202      * @param  array                                $parameter array with compilation parameter
203      *
204      * @return string compiled code
205      * @throws \SmartyCompilerException
206      */
207     public function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
208     {
209         $tag = strtolower(trim($parameter[ 0 ], '"\''));
210         $name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
211         if (!$name) {
212             $compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
213         }
214         $property = isset($parameter[ 2 ]) ? strtolower($compiler->getId($parameter[ 2 ])) : false;
215         if (!$property || !in_array($property, $this->nameProperties)) {
216             $compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", null, true);
217         }
218         $tagVar = "'__smarty_{$tag}_{$name}'";
219         return "(isset(\$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}']) ? \$_smarty_tpl->tpl_vars[{$tagVar}]->value['{$property}'] : null)";
220     }
221 }