Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/*
4
 * This file is part of Mustache.php.
5
 *
6
 * (c) 2010-2017 Justin Hileman
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
 
12
/**
13
 * Mustache Template rendering Context.
14
 */
15
class Mustache_Context
16
{
17
    private $stack      = array();
18
    private $blockStack = array();
19
 
20
    /**
21
     * Mustache rendering Context constructor.
22
     *
23
     * @param mixed $context Default rendering context (default: null)
24
     */
25
    public function __construct($context = null)
26
    {
27
        if ($context !== null) {
28
            $this->stack = array($context);
29
        }
30
    }
31
 
32
    /**
33
     * Push a new Context frame onto the stack.
34
     *
35
     * @param mixed $value Object or array to use for context
36
     */
37
    public function push($value)
38
    {
39
        array_push($this->stack, $value);
40
    }
41
 
42
    /**
43
     * Push a new Context frame onto the block context stack.
44
     *
45
     * @param mixed $value Object or array to use for block context
46
     */
47
    public function pushBlockContext($value)
48
    {
49
        array_push($this->blockStack, $value);
50
    }
51
 
52
    /**
53
     * Pop the last Context frame from the stack.
54
     *
55
     * @return mixed Last Context frame (object or array)
56
     */
57
    public function pop()
58
    {
59
        return array_pop($this->stack);
60
    }
61
 
62
    /**
63
     * Pop the last block Context frame from the stack.
64
     *
65
     * @return mixed Last block Context frame (object or array)
66
     */
67
    public function popBlockContext()
68
    {
69
        return array_pop($this->blockStack);
70
    }
71
 
72
    /**
73
     * Get the last Context frame.
74
     *
75
     * @return mixed Last Context frame (object or array)
76
     */
77
    public function last()
78
    {
79
        return end($this->stack);
80
    }
81
 
82
    /**
83
     * Find a variable in the Context stack.
84
     *
85
     * Starting with the last Context frame (the context of the innermost section), and working back to the top-level
86
     * rendering context, look for a variable with the given name:
87
     *
88
     *  * If the Context frame is an associative array which contains the key $id, returns the value of that element.
89
     *  * If the Context frame is an object, this will check first for a public method, then a public property named
90
     *    $id. Failing both of these, it will try `__isset` and `__get` magic methods.
91
     *  * If a value named $id is not found in any Context frame, returns an empty string.
92
     *
93
     * @param string $id Variable name
94
     *
95
     * @return mixed Variable value, or '' if not found
96
     */
97
    public function find($id)
98
    {
99
        return $this->findVariableInStack($id, $this->stack);
100
    }
101
 
102
    /**
103
     * Find a 'dot notation' variable in the Context stack.
104
     *
105
     * Note that dot notation traversal bubbles through scope differently than the regular find method. After finding
106
     * the initial chunk of the dotted name, each subsequent chunk is searched for only within the value of the previous
107
     * result. For example, given the following context stack:
108
     *
109
     *     $data = array(
110
     *         'name' => 'Fred',
111
     *         'child' => array(
112
     *             'name' => 'Bob'
113
     *         ),
114
     *     );
115
     *
116
     * ... and the Mustache following template:
117
     *
118
     *     {{ child.name }}
119
     *
120
     * ... the `name` value is only searched for within the `child` value of the global Context, not within parent
121
     * Context frames.
122
     *
123
     * @param string $id Dotted variable selector
124
     *
125
     * @return mixed Variable value, or '' if not found
126
     */
127
    public function findDot($id)
128
    {
129
        $chunks = explode('.', $id);
130
        $first  = array_shift($chunks);
131
        $value  = $this->findVariableInStack($first, $this->stack);
132
 
133
        foreach ($chunks as $chunk) {
134
            if ($value === '') {
135
                return $value;
136
            }
137
 
138
            $value = $this->findVariableInStack($chunk, array($value));
139
        }
140
 
141
        return $value;
142
    }
143
 
144
    /**
145
     * Find an 'anchored dot notation' variable in the Context stack.
146
     *
147
     * This is the same as findDot(), except it looks in the top of the context
148
     * stack for the first value, rather than searching the whole context stack
149
     * and starting from there.
150
     *
151
     * @see Mustache_Context::findDot
152
     *
153
     * @throws Mustache_Exception_InvalidArgumentException if given an invalid anchored dot $id
154
     *
155
     * @param string $id Dotted variable selector
156
     *
157
     * @return mixed Variable value, or '' if not found
158
     */
159
    public function findAnchoredDot($id)
160
    {
161
        $chunks = explode('.', $id);
162
        $first  = array_shift($chunks);
163
        if ($first !== '') {
164
            throw new Mustache_Exception_InvalidArgumentException(sprintf('Unexpected id for findAnchoredDot: %s', $id));
165
        }
166
 
167
        $value  = $this->last();
168
 
169
        foreach ($chunks as $chunk) {
170
            if ($value === '') {
171
                return $value;
172
            }
173
 
174
            $value = $this->findVariableInStack($chunk, array($value));
175
        }
176
 
177
        return $value;
178
    }
179
 
180
    /**
181
     * Find an argument in the block context stack.
182
     *
183
     * @param string $id
184
     *
185
     * @return mixed Variable value, or '' if not found
186
     */
187
    public function findInBlock($id)
188
    {
189
        foreach ($this->blockStack as $context) {
190
            if (array_key_exists($id, $context)) {
191
                return $context[$id];
192
            }
193
        }
194
 
195
        return '';
196
    }
197
 
198
    /**
199
     * Helper function to find a variable in the Context stack.
200
     *
201
     * @see Mustache_Context::find
202
     *
203
     * @param string $id    Variable name
204
     * @param array  $stack Context stack
205
     *
206
     * @return mixed Variable value, or '' if not found
207
     */
208
    private function findVariableInStack($id, array $stack)
209
    {
210
        for ($i = count($stack) - 1; $i >= 0; $i--) {
211
            $frame = &$stack[$i];
212
 
213
            switch (gettype($frame)) {
214
                case 'object':
215
                    if (!($frame instanceof Closure)) {
216
                        // Note that is_callable() *will not work here*
217
                        // See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
218
                        if (method_exists($frame, $id)) {
219
                            return $frame->$id();
220
                        }
221
 
222
                        if (isset($frame->$id)) {
223
                            return $frame->$id;
224
                        }
225
 
226
                        if ($frame instanceof ArrayAccess && isset($frame[$id])) {
227
                            return $frame[$id];
228
                        }
229
                    }
230
                    break;
231
 
232
                case 'array':
233
                    if (array_key_exists($id, $frame)) {
234
                        return $frame[$id];
235
                    }
236
                    break;
237
            }
238
        }
239
 
240
        return '';
241
    }
242
}