root/branches/release-37/php/lib/function.mtinclude.php @ 2196

Revision 2196, 10.5 kB (checked in by takayama, 19 months ago)

Fixed BugId:79627
* Always returns contents from include file if cache settings was disabled and include file exists

  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
3# This program is distributed under the terms of the
4# GNU General Public License, version 2.
5#
6# $Id$
7
8global $restricted_include_filenames;
9$restricted_include_filenames = array('mt-config.cgi' => 1, 'passwd' => 1);
10
11function smarty_function_mtinclude($args, &$ctx) {
12    // status: partial
13    // parameters: module, file
14    // notes: file case needs work -- search through blog site archive path, etc...
15
16    // push to ctx->vars
17    $ext_args = array();
18    while(list ($key, $val) = each($args)) {
19        if (!preg_match('/(^file$|^module$|^widget$|^blog_id$|^identifier$|^type$)/', $key)) {
20            require_once("function.mtsetvar.php");
21            smarty_function_mtsetvar(array('name' => $key, 'value' => $val), $ctx);
22            $ext_args[] = $key;
23        }
24    }
25
26    $blog_id = $args['blog_id'];
27    $blog_id or $blog_id = $ctx->stash('blog_id');
28    $blog = $ctx->mt->db->fetch_blog($blog_id);
29
30    // When the module name starts by 'Widget', it converts to 'Widget' from 'Module'.
31    if (isset($args['module']) && ($args['module'])) {
32        $module = $args['module'];
33        if (preg_match('/^Widget:/', $module)) {
34            $args['widget'] = preg_replace('/^Widget: ?/', '', $module);
35            unset($args['module']);
36        }
37    }
38
39    // Fetch template meta data
40    $load_type = null;
41    $load_name = null;
42    if (isset($args['module'])) {
43        $load_type = 'custom';
44        $load_name = $args['module'];
45    } elseif (isset($args['widget'])) {
46        $load_type = 'widget';
47        $load_name = $args['widget'];
48    } elseif (isset($args['identifier'])) {
49        $load_type = 'identifier';
50        $load_name = $args['identifier'];
51    }
52
53    $tmpl_meta = array();
54    if (!empty($load_type)) {
55        $is_global = isset($args['global']) && $args['global'] ? 1 : 0;
56        $tmpl_meta = $ctx->mt->db->fetch_template_meta($load_type, $load_name, $blog_id, $is_global);
57    }
58
59    # Convert to phrase of PHP Include
60    $ssi_enable = false;
61    $include_file = '';
62    if (!empty($load_type) &&
63        isset($blog) && $blog['blog_include_system'] == 'php' &&
64        ((isset($args['ssi']) && $args['ssi']) || (isset($tmpl_meta['include_with_ssi']) && $tmpl_meta['include_with_ssi']))) {
65
66        $ssi_enable = true;
67
68        // Generates include path using Key
69        $base_path = '';
70        if (isset($args['key'])) {
71            $base_path = $args['key'];
72        } elseif(isset($args['cache_key'])) {
73            $base_path or $base_path = $args['cache_key'];
74        }
75        $include_path_array = _include_path($base_path);
76
77        require_once('MTUtil.php');
78        $filename = dirify($tmpl_meta['template_name']);
79        $filename or $filename = 'template_' . $tmpl_meta['template_id'];
80        $filename .= '.'.$blog['blog_file_extension'];
81
82        $include_path = $blog['blog_site_path'];
83        if (substr($include_path, strlen($include_path) - 1, 1) != DIRECTORY_SEPARATOR)
84            $include_path .= DIRECTORY_SEPARATOR;
85        foreach ($include_path_array as $p) {
86            $include_path .= $p . DIRECTORY_SEPARATOR;
87        }
88        $include_file = $include_path . $filename;
89    }
90
91    # Try to read from cache
92    $cache_enable = false;
93    $cache_id = '';
94    $cacje_key = '';
95    $cache_ttl = 0;
96    if (!empty($load_type) &&
97        isset($blog) && $blog['blog_include_cache'] == 1 &&
98        ((isset($tmpl_meta['cache_expire_type']) && ($tmpl_meta['cache_expire_type'] == '1' || $tmpl_meta['cache_expire_type'] == '2')) ||
99         ((isset($args['cache']) && $args['cache'] == '1') || isset($args['key']) || isset($args['cache_key']) || isset($args['ttl']))))
100    {
101        global $mt;
102        $cache_enable = true;
103        $cache_key = isset($args['key'])
104            ? $args['key']
105            : isset($args['cache_key'])
106                ? $args['cache_key']
107                : 'blog::' . $blog_id . '::template_' . $load_type  . '::' . $load_name;
108
109        if (isset($args['ttl']))
110            $cache_ttl = $args['ttl'];
111        elseif (isset($tmpl_meta['cache_expire_type']) && $tmpl_meta['cache_expire_type'] == '1')
112            $cache_ttl = $tmpl_meta['cache_expire_interval'];
113        else
114            $cache_ttl = 60 * 60; # default 60 min.
115
116        if (isset($tmpl_meta['cache_expire_type']) && $tmpl_meta['cache_expire_type'] == '2') {
117            $expire_types = preg_split('/,/', $tmpl_meta['cache_expire_event'], -1, PREG_SPLIT_NO_EMPTY);
118            if (!empty($expire_types)) {
119                $latest = $ctx->mt->db->get_latest_touch($blog_id, $expire_types);
120                if ($latest) {
121                    if ($ssi_enable) {
122                        $file_stat = stat($include_file);
123                        if ($file_stat) {
124                            $file_stamp = gmdate("Y-m-d H:i:s", $file_stat[9]);
125                            if (strtotime($latest) > strtotime($file_stamp))
126                                $cache_ttl = 1;
127                        }
128                    } else {
129                      $cache_ttl = time() - strtotime($latest);
130                    }
131                }
132            }
133        }
134
135        if ($cache_ttl == 0 || (time() - strtotime($tmpl_meta['template_modified_on']) < $cache_ttl)) {
136            $cache_ttl = time() - strtotime($tmpl_meta['template_modified_on']);
137        }
138
139        $cache_driver = $mt->cache_driver($cache_ttl);
140        $cached_val = $cache_driver->get($cache_key, $cache_ttl);
141        if (!empty($cached_val)) {
142            _clear_vars($ctx, $ext_args);
143            if ($ssi_enable) {
144                if (file_exists($include_file) && is_readable($include_file)) {
145                  $content = file_get_contents($include_file);
146                  if ($content)
147                      return $content;
148                }
149            } else {
150                return $cached_val;
151            }
152        }
153    }
154
155    if ($ssi_enable && !$cache_enable) {
156        if (file_exists($include_file) && is_readable($include_file)) {
157            $content = file_get_contents($include_file);
158            if ($content)
159                return $content;
160        }
161    }
162
163    # Compile template
164    static $_include_cache = array();
165    $_var_compiled = '';
166
167    if (!empty($load_type)) {
168        $cache_id = $load_type . '::' . $blog_id . '::' . $load_name;
169        if (isset($_include_cache[$cache_id])) {
170            $_var_compiled = $_include_cache[$cache_id];
171        } else {
172            $tmpl = $ctx->mt->db->get_template_text($ctx, $load_name, $blog_id, $load_type, $args['global']);
173            if (!$ctx->_compile_source('evaluated template', $tmpl, $_var_compiled)) {
174                _clear_vars($ctx, $ext_args);
175                return $ctx->error("Error compiling template module '$module'");
176            }
177            $_include_cache[$cache_id] = $_var_compiled;
178        }
179    } elseif (isset($args['file']) && ($args['file'])) {
180        $file = $args['file'];
181        $cache_id = 'file::' . $blog_id . '::' . $file;
182        if (isset($_include_cache[$cache_id])) {
183            $_var_compiled = $_include_cache[$cache_id];
184        } else {
185            $tmpl = _get_template_from_file($ctx, $file, $blog_id);
186            if (!$ctx->_compile_source('evaluated template', $tmpl, $_var_compiled)) {
187                _clear_vars($ctx, $ext_args);
188                return $ctx->error("Error compiling template file '$file'");
189            }
190            $_include_cache[$cache_id] = $_var_compiled;
191        }
192    } elseif (isset($args['type']) && ($args['type'])) {
193        $type = $args['type'];
194        $cache_id = 'type::' . $blog_id . '::' . $type;
195        if (isset($_include_cache[$cache_id])) {
196            $_var_compiled = $_include_cache[$cache_id];
197        } else {
198            $tmpl = $ctx->mt->db->load_special_template($ctx, null, $type, $blog_id);
199            if ($tmpl) {
200                if ($ctx->_compile_source('evaluated template', $tmpl['template_text'], $_var_compiled)) {
201                    $_include_cache[$cache_id] = $_var_compiled;
202                } else {
203                    if ($type != 'dynamic_error') {
204                        _clear_vars($ctx, $ext_args);
205                        return $ctx->error("Error compiling template module '$module'");
206                     } else {
207                        _clear_vars($ctx, $ext_args);
208                         return null;
209                     }
210                }
211            } else {
212                _clear_vars($ctx, $ext_args);
213                return null;
214            }
215        }
216    }
217
218    ob_start();
219    $ctx->_eval('?>' . $_var_compiled);
220    $_contents = ob_get_contents();
221    ob_end_clean();
222
223    _clear_vars($ctx, $ext_args);
224
225    if ($cache_enable) {
226        $cache_driver = $mt->cache_driver($cache_ttl);
227        $cache_driver->set($cache_key, $_contents, $cache_ttl);
228    }
229
230    if ($ssi_enable) {
231        $include_dir = dirname($include_file);
232        if (!file_exists($include_dir) && !is_dir($include_dir)) {
233            mkdir($include_dir, 0777, true);
234        }
235        if (is_writable($include_dir)) {
236            if ($h_file = fopen($include_file, 'w')) {
237                fwrite($h_file, $_contents);
238                fclose($h_file);
239            }
240        }
241    }
242
243    return $_contents;
244}
245
246function _get_template_from_file ($ctx, $file, $blog_id) {
247    $base_filename = basename($file);
248    global $restricted_include_filenames;
249    if (array_key_exists(strtolower($base_filename), $restricted_include_filenames)) {
250        return '';
251    }
252    if (is_file($file) && is_readable($file)) {
253        $contents = @file($file);
254        $tmpl = implode('', $contents);
255    } else {
256        $blog = $ctx->stash('blog');
257        if ($blog['blog_id'] != $blog_id) {
258            $blog = $ctx->mt->db->fetch_blog($blog_id);
259        }
260        $path = $blog['blog_site_path'];
261        if (!preg_match('!/$!', $path))
262            $path .= '/';
263        $path .= $file;
264        if (is_file($path) && is_readable($path)) {
265            $contents = @file($path);
266            $tmpl = implode('', $contents);
267        } else {
268            return false;
269        }
270    }
271
272    return $tmpl;
273}
274
275function _clear_vars(&$ctx, $ext_vars) {
276    # unset vars
277    $vars =& $ctx->__stash['vars'];
278    foreach ($ext_vars as $v) {
279        unset($vars[$v]);
280    }
281    $ctx->__stash['vars'] =& $vars;
282}
283
284function _include_path($path) {
285    $path_array = array();
286    if (preg_match('/^\//', $path)) {
287        $path_array = preg_split('/\//', $path, -1, PREG_SPLIT_NO_EMPTY);
288    } else {
289        $path_array = preg_split('/\//', $path, -1, PREG_SPLIT_NO_EMPTY);
290        global $mt;
291        array_unshift($path_array, $mt->config('IncludesDir'));
292    }
293    return $path_array;
294}
295?>
Note: See TracBrowser for help on using the browser.