Completed
Branch master (e379bd)
by Pierre-Henry
33:06
created

Smarty_Template_Compiled::process()   C

Complexity

Conditions 8
Paths 5

Size

Total Lines 30
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 24
nc 5
nop 1
dl 0
loc 30
rs 5.3846
c 0
b 0
f 0
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
    /**
16
     * nocache hash
17
     *
18
     * @var string|null
19
     */
20
    public $nocache_hash = null;
21
22
    /**
23
     * get a Compiled Object of this source
24
     *
25
     * @param  Smarty_Internal_Template $_template template object
26
     *
27
     * @return Smarty_Template_Compiled compiled object
28
     */
29
    static function load($_template)
30
    {
31
        $compiled = new Smarty_Template_Compiled();
32
        if ($_template->source->handler->hasCompiledHandler) {
33
            $_template->source->handler->populateCompiledFilepath($compiled, $_template);
34
        } else {
35
            $compiled->populateCompiledFilepath($_template);
36
        }
37
        return $compiled;
38
    }
39
40
    /**
41
     * populate Compiled Object with compiled filepath
42
     *
43
     * @param Smarty_Internal_Template $_template template object
44
     **/
45
    public function populateCompiledFilepath(Smarty_Internal_Template $_template)
46
    {
47
        $source = &$_template->source;
48
        $smarty = &$_template->smarty;
49
        $this->filepath = $smarty->getCompileDir();
50
        if (isset($_template->compile_id)) {
51
            $this->filepath .= preg_replace('![^\w]+!', '_', $_template->compile_id) .
52
                               ($smarty->use_sub_dirs ? $smarty->ds : '^');
53
        }
54
        // if use_sub_dirs, break file into directories
55
        if ($smarty->use_sub_dirs) {
56
            $this->filepath .= $source->uid[ 0 ] . $source->uid[ 1 ] . $smarty->ds . $source->uid[ 2 ] .
57
                               $source->uid[ 3 ] . $smarty->ds . $source->uid[ 4 ] . $source->uid[ 5 ] . $smarty->ds;
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
     * load compiled template or compile from source
85
     *
86
     * @param Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
87
     *
88
     * @throws Exception
89
     */
90
    public function process(Smarty_Internal_Template $_smarty_tpl)
91
    {
92
        $source = &$_smarty_tpl->source;
93
        $smarty = &$_smarty_tpl->smarty;
94
        if ($source->handler->recompiled) {
95
            $source->handler->process($_smarty_tpl);
96
        } elseif (!$source->handler->uncompiled) {
97
            if (!$this->exists || $smarty->force_compile ||
98
                ($smarty->compile_check && $source->getTimeStamp() > $this->getTimeStamp())
99
            ) {
100
                $this->compileTemplateSource($_smarty_tpl);
101
                $compileCheck = $smarty->compile_check;
102
                $smarty->compile_check = false;
103
                $this->loadCompiledTemplate($_smarty_tpl);
104
                $smarty->compile_check = $compileCheck;
105
            } else {
106
                $_smarty_tpl->mustCompile = true;
107
                @include($this->filepath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
108
                if ($_smarty_tpl->mustCompile) {
109
                    $this->compileTemplateSource($_smarty_tpl);
110
                    $compileCheck = $smarty->compile_check;
111
                    $smarty->compile_check = false;
112
                    $this->loadCompiledTemplate($_smarty_tpl);
113
                    $smarty->compile_check = $compileCheck;
114
                }
115
            }
116
            $_smarty_tpl->_subTemplateRegister();
117
            $this->processed = true;
118
        }
119
    }
120
121
    /**
122
     * Load fresh compiled template by including the PHP file
123
     * HHVM requires a work around because of a PHP incompatibility
124
     *
125
     * @param \Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template
126
     */
127
    private function loadCompiledTemplate(Smarty_Internal_Template $_smarty_tpl)
128
    {
129
        if (function_exists('opcache_invalidate') && strlen(ini_get("opcache.restrict_api")) < 1) {
130
            opcache_invalidate($this->filepath, true);
131
        } elseif (function_exists('apc_compile_file')) {
132
            apc_compile_file($this->filepath);
133
        }
134
        if (defined('HHVM_VERSION')) {
135
            eval("?>" . file_get_contents($this->filepath));
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
136
        } else {
137
            include($this->filepath);
138
        }
139
    }
140
141
    /**
142
     * render compiled template code
143
     *
144
     * @param Smarty_Internal_Template $_template
145
     *
146
     * @return string
147
     * @throws Exception
148
     */
149
    public function render(Smarty_Internal_Template $_template)
150
    {
151
        // checks if template exists
152
        if (!$_template->source->exists) {
153
            $type = $_template->source->isConfig ? 'config' : 'template';
154
            throw new SmartyException("Unable to load {$type} '{$_template->source->type}:{$_template->source->name}'");
155
        }
156
        if ($_template->smarty->debugging) {
157
            if (!isset($_template->smarty->_debug)) {
158
                $_template->smarty->_debug = new Smarty_Internal_Debug();
159
            }
160
            $_template->smarty->_debug->start_render($_template);
161
        }
162
        if (!$this->processed) {
163
            $this->process($_template);
164
        }
165
        if (isset($_template->cached)) {
166
            $_template->cached->file_dependency =
167
                array_merge($_template->cached->file_dependency, $this->file_dependency);
168
        }
169
        if ($_template->source->handler->uncompiled) {
170
            $_template->source->handler->renderUncompiled($_template->source, $_template);
171
        } else {
172
            $this->getRenderedTemplateCode($_template);
173
        }
174
        if ($_template->caching && $this->has_nocache_code) {
175
            $_template->cached->hashes[ $this->nocache_hash ] = true;
176
        }
177
        if ($_template->smarty->debugging) {
178
            $_template->smarty->_debug->end_render($_template);
179
        }
180
    }
181
182
    /**
183
     * compile template from source
184
     *
185
     * @param Smarty_Internal_Template $_template
186
     *
187
     * @throws Exception
188
     */
189
    public function compileTemplateSource(Smarty_Internal_Template $_template)
190
    {
191
        $this->file_dependency = array();
192
        $this->includes = array();
193
        $this->nocache_hash = null;
194
        $this->unifunc = null;
195
        // compile locking
196
        $saved_timestamp = $_template->source->handler->recompiled ? false : $this->getTimeStamp();
197
        if ($saved_timestamp) {
198
            touch($this->filepath);
199
        }
200
        // compile locking
201
        try {
202
            // call compiler
203
            $_template->loadCompiler();
204
            $this->write($_template, $_template->compiler->compileTemplate($_template));
205
        }
206
        catch (Exception $e) {
207
            // restore old timestamp in case of error
208
            if ($saved_timestamp) {
209
                touch($this->filepath, $saved_timestamp);
210
            }
211
            unset($_template->compiler);
212
            throw $e;
213
        }
214
        // release compiler object to free memory
215
        unset($_template->compiler);
216
    }
217
218
    /**
219
     * Write compiled code by handler
220
     *
221
     * @param Smarty_Internal_Template $_template template object
222
     * @param string                   $code      compiled code
223
     *
224
     * @return boolean success
225
     */
226
    public function write(Smarty_Internal_Template $_template, $code)
227
    {
228
        if (!$_template->source->handler->recompiled) {
229
            if ($_template->smarty->ext->_writeFile->writeFile($this->filepath, $code, $_template->smarty) === true) {
230
                $this->timestamp = $this->exists = is_file($this->filepath);
231
                if ($this->exists) {
232
                    $this->timestamp = filemtime($this->filepath);
233
                    return true;
234
                }
235
            }
236
            return false;
237
        }
238
        return true;
239
    }
240
241
    /**
242
     * Read compiled content from handler
243
     *
244
     * @param Smarty_Internal_Template $_template template object
245
     *
246
     * @return string content
247
     */
248
    public function read(Smarty_Internal_Template $_template)
249
    {
250
        if (!$_template->source->handler->recompiled) {
251
            return file_get_contents($this->filepath);
252
        }
253
        return isset($this->content) ? $this->content : false;
254
    }
255
}
256