Subversion Repositories ALCASAR

Rev

Go to most recent revision | Details | Last modification | View Log

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