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
/**
4
 * Smarty Resource Data Object
5
 * Meta Data Container for Template Files
6
 *
7
 * @package    Smarty
8
 * @subpackage TemplateResources
9
 * @author     Rodney Rehm
10
 * @property   string $content compiled content
11
 */
12
class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
13
{
14
    /**
15
     * nocache hash
16
     *
17
     * @var string|null
18
     */
19
    public $nocache_hash = null;
20
 
21
    /**
22
     * get a Compiled Object of this source
23
     *
24
     * @param Smarty_Internal_Template $_template template object
25
     *
26
     * @return Smarty_Template_Compiled compiled object
27
     */
28
    public static function load($_template)
29
    {
30
        $compiled = new Smarty_Template_Compiled();
31
        if ($_template->source->handler->hasCompiledHandler) {
32
            $_template->source->handler->populateCompiledFilepath($compiled, $_template);
33
        } else {
34
            $compiled->populateCompiledFilepath($_template);
35
        }
36
        return $compiled;
37
    }
38
 
39
    /**
40
     * populate Compiled Object with compiled filepath
41
     *
42
     * @param Smarty_Internal_Template $_template template object
43
     **/
44
    public function populateCompiledFilepath(Smarty_Internal_Template $_template)
45
    {
46
        $source = &$_template->source;
47
        $smarty = &$_template->smarty;
48
        $this->filepath = $smarty->getCompileDir();
49
        if (isset($_template->compile_id)) {
50
            $this->filepath .= preg_replace('![^\w]+!', '_', $_template->compile_id) .
51
                               ($smarty->use_sub_dirs ? DIRECTORY_SEPARATOR : '^');
52
        }
53
        // if use_sub_dirs, break file into directories
54
        if ($smarty->use_sub_dirs) {
55
            $this->filepath .= $source->uid[ 0 ] . $source->uid[ 1 ] . DIRECTORY_SEPARATOR . $source->uid[ 2 ] .
56
                               $source->uid[ 3 ] . DIRECTORY_SEPARATOR . $source->uid[ 4 ] . $source->uid[ 5 ] .
57
                               DIRECTORY_SEPARATOR;
58
        }
59
        $this->filepath .= $source->uid . '_';
60
        if ($source->isConfig) {
61
            $this->filepath .= (int)$smarty->config_read_hidden + (int)$smarty->config_booleanize * 2 +
62
                               (int)$smarty->config_overwrite * 4;
63
        } else {
64
            $this->filepath .= (int)$smarty->merge_compiled_includes + (int)$smarty->escape_html * 2 +
65
                               (($smarty->merge_compiled_includes && $source->type === 'extends') ?
66
                                   (int)$smarty->extends_recursion * 4 : 0);
67
        }
68
        $this->filepath .= '.' . $source->type;
69
        $basename = $source->handler->getBasename($source);
70
        if (!empty($basename)) {
71
            $this->filepath .= '.' . $basename;
72
        }
73
        if ($_template->caching) {
74
            $this->filepath .= '.cache';
75
        }
76
        $this->filepath .= '.php';
77
        $this->timestamp = $this->exists = is_file($this->filepath);
78
        if ($this->exists) {
79
            $this->timestamp = filemtime($this->filepath);
80
        }
81
    }
82
 
83
    /**
84
     * render compiled template code
85
     *
86
     * @param Smarty_Internal_Template $_template
87
     *
88
     * @return string
89
     * @throws Exception
90
     */
91
    public function render(Smarty_Internal_Template $_template)
92
    {
93
        // checks if template exists
94
        if (!$_template->source->exists) {
95
            $type = $_template->source->isConfig ? 'config' : 'template';
96
            throw new SmartyException("Unable to load {$type} '{$_template->source->type}:{$_template->source->name}'");
97
        }
98
        if ($_template->smarty->debugging) {
99
            if (!isset($_template->smarty->_debug)) {
100
                $_template->smarty->_debug = new Smarty_Internal_Debug();
101
            }
102
            $_template->smarty->_debug->start_render($_template);
103
        }
104
        if (!$this->processed) {
105
            $this->process($_template);
106
        }
107
        if (isset($_template->cached)) {
108
            $_template->cached->file_dependency =
109
                array_merge($_template->cached->file_dependency, $this->file_dependency);
110
        }
111
        if ($_template->source->handler->uncompiled) {
112
            $_template->source->handler->renderUncompiled($_template->source, $_template);
113
        } else {
114
            $this->getRenderedTemplateCode($_template);
115
        }
116
        if ($_template->caching && $this->has_nocache_code) {
117
            $_template->cached->hashes[ $this->nocache_hash ] = true;
118
        }
119
        if ($_template->smarty->debugging) {
120
            $_template->smarty->_debug->end_render($_template);
121
        }
122
    }
123
 
124
    /**
125
     * load compiled template or compile from source
126
     *
127
     * @param Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
128
     *
129
     * @throws Exception
130
     */
131
    public function process(Smarty_Internal_Template $_smarty_tpl)
132
    {
133
        $source = &$_smarty_tpl->source;
134
        $smarty = &$_smarty_tpl->smarty;
135
        if ($source->handler->recompiled) {
136
            $source->handler->process($_smarty_tpl);
137
        } elseif (!$source->handler->uncompiled) {
138
            if (!$this->exists || $smarty->force_compile
139
                || ($_smarty_tpl->compile_check && $source->getTimeStamp() > $this->getTimeStamp())
140
            ) {
141
                $this->compileTemplateSource($_smarty_tpl);
142
                $compileCheck = $_smarty_tpl->compile_check;
143
                $_smarty_tpl->compile_check = Smarty::COMPILECHECK_OFF;
144
                $this->loadCompiledTemplate($_smarty_tpl);
145
                $_smarty_tpl->compile_check = $compileCheck;
146
            } else {
147
                $_smarty_tpl->mustCompile = true;
148
                @include $this->filepath;
149
                if ($_smarty_tpl->mustCompile) {
150
                    $this->compileTemplateSource($_smarty_tpl);
151
                    $compileCheck = $_smarty_tpl->compile_check;
152
                    $_smarty_tpl->compile_check = Smarty::COMPILECHECK_OFF;
153
                    $this->loadCompiledTemplate($_smarty_tpl);
154
                    $_smarty_tpl->compile_check = $compileCheck;
155
                }
156
            }
157
            $_smarty_tpl->_subTemplateRegister();
158
            $this->processed = true;
159
        }
160
    }
161
 
162
    /**
163
     * compile template from source
164
     *
165
     * @param Smarty_Internal_Template $_template
166
     *
167
     * @throws Exception
168
     */
169
    public function compileTemplateSource(Smarty_Internal_Template $_template)
170
    {
171
        $this->file_dependency = array();
172
        $this->includes = array();
173
        $this->nocache_hash = null;
174
        $this->unifunc = null;
175
        // compile locking
176
        if ($saved_timestamp = (!$_template->source->handler->recompiled && is_file($this->filepath))) {
177
            $saved_timestamp = $this->getTimeStamp();
178
            touch($this->filepath);
179
        }
180
        // compile locking
181
        try {
182
            // call compiler
183
            $_template->loadCompiler();
184
            $this->write($_template, $_template->compiler->compileTemplate($_template));
185
        } catch (Exception $e) {
186
            // restore old timestamp in case of error
187
            if ($saved_timestamp && is_file($this->filepath)) {
188
                touch($this->filepath, $saved_timestamp);
189
            }
190
            unset($_template->compiler);
191
            throw $e;
192
        }
193
        // release compiler object to free memory
194
        unset($_template->compiler);
195
    }
196
 
197
    /**
198
     * Write compiled code by handler
199
     *
200
     * @param Smarty_Internal_Template $_template template object
201
     * @param string                   $code      compiled code
202
     *
203
     * @return bool success
204
     * @throws \SmartyException
205
     */
206
    public function write(Smarty_Internal_Template $_template, $code)
207
    {
208
        if (!$_template->source->handler->recompiled) {
209
            if ($_template->smarty->ext->_writeFile->writeFile($this->filepath, $code, $_template->smarty) === true) {
210
                $this->timestamp = $this->exists = is_file($this->filepath);
211
                if ($this->exists) {
212
                    $this->timestamp = filemtime($this->filepath);
213
                    return true;
214
                }
215
            }
216
            return false;
217
        }
218
        return true;
219
    }
220
 
221
    /**
222
     * Read compiled content from handler
223
     *
224
     * @param Smarty_Internal_Template $_template template object
225
     *
226
     * @return string content
227
     */
228
    public function read(Smarty_Internal_Template $_template)
229
    {
230
        if (!$_template->source->handler->recompiled) {
231
            return file_get_contents($this->filepath);
232
        }
233
        return isset($this->content) ? $this->content : false;
234
    }
235
 
236
    /**
237
     * Load fresh compiled template by including the PHP file
238
     * HHVM requires a work around because of a PHP incompatibility
239
     *
240
     * @param \Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
241
     */
242
    private function loadCompiledTemplate(Smarty_Internal_Template $_smarty_tpl)
243
    {
244
        if (function_exists('opcache_invalidate')
245
            && (!function_exists('ini_get') || strlen(ini_get("opcache.restrict_api")) < 1)
246
        ) {
247
            opcache_invalidate($this->filepath, true);
248
        } elseif (function_exists('apc_compile_file')) {
249
            apc_compile_file($this->filepath);
250
        }
251
        if (defined('HHVM_VERSION')) {
252
            eval('?>' . file_get_contents($this->filepath));
253
        } else {
254
            include $this->filepath;
255
        }
256
    }
257
}