root/branches/release-36/php/lib/function.mtinclude.php @ 2104

Revision 2104, 10.3 kB (checked in by takayama, 19 months ago)

Implemented BugId:71811, BugId:79438
* Added SSI support into the Dynamic Publishing
* Added cache option support

  • 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    # Compile template
156    static $_include_cache = array();
157    $_var_compiled = '';
158
159    if (!empty($load_type)) {
160        $cache_id = $load_type . '::' . $blog_id . '::' . $load_name;
161        if (isset($_include_cache[$cache_id])) {
162            $_var_compiled = $_include_cache[$cache_id];
163        } else {
164            $tmpl = $ctx->mt->db->get_template_text($ctx, $load_name, $blog_id, $load_type, $args['global']);
165            if (!$ctx->_compile_source('evaluated template', $tmpl, $_var_compiled)) {
166                _clear_vars($ctx, $ext_args);
167                return $ctx->error("Error compiling template module '$module'");
168            }
169            $_include_cache[$cache_id] = $_var_compiled;
170        }
171    } elseif (isset($args['file']) && ($args['file'])) {
172        $file = $args['file'];
173        $cache_id = 'file::' . $blog_id . '::' . $file;
174        if (isset($_include_cache[$cache_id])) {
175            $_var_compiled = $_include_cache[$cache_id];
176        } else {
177            $tmpl = _get_template_from_file($ctx, $file, $blog_id);
178            if (!$ctx->_compile_source('evaluated template', $tmpl, $_var_compiled)) {
179                _clear_vars($ctx, $ext_args);
180                return $ctx->error("Error compiling template file '$file'");
181            }
182            $_include_cache[$cache_id] = $_var_compiled;
183        }
184    } elseif (isset($args['type']) && ($args['type'])) {
185        $type = $args['type'];
186        $cache_id = 'type::' . $blog_id . '::' . $type;
187        if (isset($_include_cache[$cache_id])) {
188            $_var_compiled = $_include_cache[$cache_id];
189        } else {
190            $tmpl = $ctx->mt->db->load_special_template($ctx, null, $type, $blog_id);
191            if ($tmpl) {
192                if ($ctx->_compile_source('evaluated template', $tmpl['template_text'], $_var_compiled)) {
193                    $_include_cache[$cache_id] = $_var_compiled;
194                } else {
195                    if ($type != 'dynamic_error') {
196                        _clear_vars($ctx, $ext_args);
197                        return $ctx->error("Error compiling template module '$module'");
198                     } else {
199                        _clear_vars($ctx, $ext_args);
200                         return null;
201                     }
202                }
203            } else {
204                _clear_vars($ctx, $ext_args);
205                return null;
206            }
207        }
208    }
209
210    ob_start();
211    $ctx->_eval('?>' . $_var_compiled);
212    $_contents = ob_get_contents();
213    ob_end_clean();
214
215    _clear_vars($ctx, $ext_args);
216
217    if ($cache_enable) {
218        $cache_driver = $mt->cache_driver($cache_ttl);
219        $cache_driver->set($cache_key, $_contents, $cache_ttl);
220    }
221
222    if ($ssi_enable) {
223        $include_dir = dirname($include_file);
224        if (!file_exists($include_dir) && !is_dir($include_dir)) {
225            mkdir($include_dir, 0777, true);
226        }
227        if (is_writable($include_dir)) {
228            if ($h_file = fopen($include_file, 'w')) {
229                fwrite($h_file, $_contents);
230                fclose($h_file);
231            }
232        }
233    }
234
235    return $_contents;
236}
237
238function _get_template_from_file ($ctx, $file, $blog_id) {
239    $base_filename = basename($file);
240    global $restricted_include_filenames;
241    if (array_key_exists(strtolower($base_filename), $restricted_include_filenames)) {
242        return '';
243    }
244    if (is_file($file) && is_readable($file)) {
245        $contents = @file($file);
246        $tmpl = implode('', $contents);
247    } else {
248        $blog = $ctx->stash('blog');
249        if ($blog['blog_id'] != $blog_id) {
250            $blog = $ctx->mt->db->fetch_blog($blog_id);
251        }
252        $path = $blog['blog_site_path'];
253        if (!preg_match('!/$!', $path))
254            $path .= '/';
255        $path .= $file;
256        if (is_file($path) && is_readable($path)) {
257            $contents = @file($path);
258            $tmpl = implode('', $contents);
259        } else {
260            return false;
261        }
262    }
263
264    return $tmpl;
265}
266
267function _clear_vars(&$ctx, $ext_vars) {
268    # unset vars
269    $vars =& $ctx->__stash['vars'];
270    foreach ($ext_vars as $v) {
271        unset($vars[$v]);
272    }
273    $ctx->__stash['vars'] =& $vars;
274}
275
276function _include_path($path) {
277    $path_array = array();
278    if (preg_match('/^\//', $path)) {
279        $path_array = preg_split('/\//', $path, -1, PREG_SPLIT_NO_EMPTY);
280    } else {
281        $path_array = preg_split('/\//', $path, -1, PREG_SPLIT_NO_EMPTY);
282        global $mt;
283        array_unshift($path_array, $mt->config('IncludesDir'));
284    }
285    return $path_array;
286}
287?>
Note: See TracBrowser for help on using the browser.