Subversion Repositories ALCASAR

Rev

Details | Last modification | View Log

Rev Author Line No. Line
2809 rexy 1
<?php
2
/**
3
 * Smarty Internal Plugin Compile Break
4
 * Compiles the {break} tag
5
 *
6
 * @package    Smarty
7
 * @subpackage Compiler
8
 * @author     Uwe Tews
9
 */
10
 
11
/**
12
 * Smarty Internal Plugin Compile Break Class
13
 *
14
 * @package    Smarty
15
 * @subpackage Compiler
16
 */
17
class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
18
{
19
    /**
20
     * Attribute definition: Overwrites base class.
21
     *
22
     * @var array
23
     * @see Smarty_Internal_CompileBase
24
     */
25
    public $optional_attributes = array('levels');
26
 
27
    /**
28
     * Attribute definition: Overwrites base class.
29
     *
30
     * @var array
31
     * @see Smarty_Internal_CompileBase
32
     */
33
    public $shorttag_order = array('levels');
34
 
35
    /**
36
     * Tag name may be overloaded by Smarty_Internal_Compile_Continue
37
     *
38
     * @var string
39
     */
40
    public $tag = 'break';
41
 
42
    /**
43
     * Compiles code for the {break} tag
44
     *
45
     * @param array                                 $args     array with attributes from parser
46
     * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
47
     *
48
     * @return string compiled code
49
     * @throws \SmartyCompilerException
50
     */
51
    public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler)
52
    {
53
        list($levels, $foreachLevels) = $this->checkLevels($args, $compiler);
54
        $output = "<?php ";
55
        if ($foreachLevels > 0 && $this->tag === 'continue') {
56
            $foreachLevels--;
57
        }
58
        if ($foreachLevels > 0) {
59
            /* @var Smarty_Internal_Compile_Foreach $foreachCompiler */
60
            $foreachCompiler = $compiler->getTagCompiler('foreach');
61
            $output .= $foreachCompiler->compileRestore($foreachLevels);
62
        }
63
        $output .= "{$this->tag} {$levels};?>";
64
        return $output;
65
    }
66
 
67
    /**
68
     * check attributes and return array of break and foreach levels
69
     *
70
     * @param array                                 $args     array with attributes from parser
71
     * @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
72
     *
73
     * @return array
74
     * @throws \SmartyCompilerException
75
     */
76
    public function checkLevels($args, Smarty_Internal_TemplateCompilerBase $compiler)
77
    {
78
        static $_is_loopy = array('for' => true, 'foreach' => true, 'while' => true, 'section' => true);
79
        // check and get attributes
80
        $_attr = $this->getAttributes($compiler, $args);
81
        if ($_attr[ 'nocache' ] === true) {
82
            $compiler->trigger_template_error('nocache option not allowed', null, true);
83
        }
84
        if (isset($_attr[ 'levels' ])) {
85
            if (!is_numeric($_attr[ 'levels' ])) {
86
                $compiler->trigger_template_error('level attribute must be a numeric constant', null, true);
87
            }
88
            $levels = $_attr[ 'levels' ];
89
        } else {
90
            $levels = 1;
91
        }
92
        $level_count = $levels;
93
        $stack_count = count($compiler->_tag_stack) - 1;
94
        $foreachLevels = 0;
95
        $lastTag = '';
96
        while ($level_count > 0 && $stack_count >= 0) {
97
            if (isset($_is_loopy[ $compiler->_tag_stack[ $stack_count ][ 0 ] ])) {
98
                $lastTag = $compiler->_tag_stack[ $stack_count ][ 0 ];
99
                if ($level_count === 0) {
100
                    break;
101
                }
102
                $level_count--;
103
                if ($compiler->_tag_stack[ $stack_count ][ 0 ] === 'foreach') {
104
                    $foreachLevels++;
105
                }
106
            }
107
            $stack_count--;
108
        }
109
        if ($level_count !== 0) {
110
            $compiler->trigger_template_error("cannot {$this->tag} {$levels} level(s)", null, true);
111
        }
112
        if ($lastTag === 'foreach' && $this->tag === 'break' && $foreachLevels > 0) {
113
            $foreachLevels--;
114
        }
115
        return array($levels, $foreachLevels);
116
    }
117
}