root/branches/release-40/php/lib/MTViewer.php @ 2636

Revision 2636, 19.0 kB (checked in by takayama, 17 months ago)

Fixed BugId:80249
* Added file existence check before include

  • 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
8include_once("Smarty.class.php");
9class MTViewer extends Smarty {
10    var $varstack = array();
11    var $__stash;
12    var $mt;
13    var $last_ts = 0;
14    var $id;
15
16    var $path_sep;
17
18    var $conditionals = array(
19        'mtparentcategory' => 1,
20        'mttoplevelparent' => 1,
21        'mtunless' => 1,
22        'mtfolderheader' => 1,
23        'mtfolderfooter' => 1,
24        'mtpagesheader' => 1,
25        'mtpagesfooter' => 1,
26        'mthassubfolders' => 1,
27        'mthasparentfolders' => 1,
28        'mthasparentfolder' => 1,
29        'mtauthorhasentry' => 1,
30        'mtauthorhaspage' => 1,
31    );
32    var $sanitized = array(
33        'mtcommentauthor' => 1,
34        'mtcommentemail' => 1,
35        'mtcommenturl' => 1,
36        'mtcommentbody' => 1,
37        'mtpingtitle' => 1,
38        'mtpingurl' => 1,
39        'mtpingexcerpt' => 1,
40        'mtpingblogname' => 1,
41    );
42    var $nofollowed = array(
43        'mtcommentauthorlink' => 1,
44        'mtcommenturl' => 1,
45        'mtcommentbody' => 1,
46        'mtpings' => 1,
47    );
48    var $global_attr = array(
49        'filters' => 1,
50        'trim_to' => 1,
51        'trim' => 1,
52        'ltrim' => 1,
53        'rtrim' => 1,
54        'decode_html' => 1,
55        'decode_xml' => 1,
56        'remove_html' => 1,
57        'dirify' => 1,
58        'sanitize' => 1,
59        'encode_html' => 1,
60        'encode_xml' => 1,
61        'encode_js' => 1,
62        'encode_php' => 1,
63        'encode_url' => 1,
64        'upper_case' => 1,
65        'lower_case' => 1,
66        'strip_linefeeds' => 1,
67        'space_pad' => 1,
68        'zero_pad' => 1,
69        'sprintf' => 1,
70        'wrap_text' => 1,
71        'setvar' => 1,
72        'numify' => 1,
73         # native smarty modifiers
74        'regex_replace' => 1,
75        'capitalize' => 1,
76        'count_characters' => 1,
77        'cat' => 1,
78        'count_paragraphs' => 1,
79        'count_sentences' => 1,
80        'count_words' => 1,
81        'date_format' => 1,
82        '_default' => 'default',
83        'escape' => 1,
84        'indent' => 1,
85        'nl2br' => 1,
86        'replace' => 1,
87        'spacify' => 1,
88        'string_format' => 1,
89        'strip' => 1,
90        'strip_tags' => 1,
91        'truncate' => 1,
92        'wordwrap' => 1,
93    );
94    var $needs_tokens = array(
95        'mtsubcategories' => 1,
96        'mttoplevelcategories' => 1,
97        'mtsubfolers' => 1,
98        'mttoplevelfolders' => 1,
99        'mtcommentreplies' => 1,
100        'mtsetvartemplate' => 1,
101    );
102
103    function MTViewer(&$mt) {
104        // prevents an unknown index error within Smarty.class.php
105        $this->id = md5(uniqid('MTViewer',true));
106        $_COOKIE['SMARTY_DEBUG'] = 0;
107        $GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG'] = 0;
108        $this->path_sep = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') ? ';' : ':';
109        $this->Smarty();
110        $this->mt =& $mt;
111        $this->__stash =& $this->_tpl_vars;
112        $this->left_delimiter = "{{";
113        $this->right_delimiter = "}}";
114        $this->load_filter('pre', 'mt_to_smarty');
115        $this->register_block('mtdynamic', array(&$this, 'smarty_block_dynamic'),
116                              false);
117        $this->register_block('mtelse', array(&$this, 'smarty_block_else'));
118        $this->register_block('mtelseif', array(&$this, 'smarty_block_elseif'));
119
120        # Unregister the 'core' regex_replace so we can replace it
121        $this->register_modifier('regex_replace', array(&$this, 'regex_replace'));
122    }
123
124    function add_plugin_dir($plugin_dir) {
125        ini_set('include_path', $plugin_dir . $this->path_sep . ini_get('include_path'));
126        $this->plugins_dir[] = $plugin_dir;
127    }
128
129    function regex_replace($string, $search, $replace) {
130        if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (preg_match('/[eg]/', $match[1]))) {
131            if (strpos($match[1], "g") !== false)
132                $global = 1;
133            /* remove eval-modifier from $search */
134            $search = substr($search, 0, -strlen($match[1])) . preg_replace('![eg\s]+!', '', $match[1]);
135        }
136        return preg_replace($search, $replace, $string, $global ? -1 : 1);
137    }
138
139    function add_token_tag($name) {
140        $this->needs_tokens[$name] = 1;
141    }
142
143    function add_conditional_tag($name, $code = null, $cacheable = null, $cache_attrs = null) {
144        $this->conditionals[$name] = 1;
145        if (isset($code)) {
146            $this->register_block($name, $code, $cacheable, $cache_attrs);
147        }
148    }
149
150    function add_global_filter($name, $code = null) {
151        $this->global_attr[$name] = 1;
152        if (isset($code)) {
153            $this->register_modifier($name, $code);
154        }
155    }
156
157    function error($err, $error_type = E_USER_ERROR) {
158        trigger_error($err, $error_type);
159        return '';
160    }
161
162    function this_tag() {
163        $ts = $this->_tag_stack[count($this->_tag_stack)-1];
164        if ($ts) {
165            return $ts[0];
166        } else {
167            return null;
168        }
169    }
170
171    function stash($name,$value=null) {
172        if(isset($this->__stash[$name]))
173            $old_val = $this->__stash[$name];
174        else
175            $old_val = null;
176        if(func_num_args() > 1)
177            $this->__stash[$name] = $value;
178        return $old_val;
179    }
180
181    function localize($vars) {
182        foreach ($vars as $v) {
183            if (!isset($this->varstack[$v])) $this->varstack[$v] = array();
184            $this->varstack[$v][] = isset($this->__stash[$v]) ? $this->__stash[$v] : null;
185        }
186    }
187
188    function restore($vars) {
189        foreach ($vars as $v) {
190            $this->__stash[$v] = (isset($this->varstack[$v]) && count($this->varstack[$v]) > 0) ? array_pop($this->varstack[$v]) : null;
191        }
192    }
193
194    function last_ts($ts = 0) {
195        if ($ts > 0) {
196            $ts = preg_replace('/[ :-]/', '', $ts);
197            if ($ts > $this->last_ts) {
198                $this->last_ts = $ts;
199            }
200        }
201        return $this->last_ts;
202    }
203
204    function smarty_block_dynamic($param, $content, &$smarty) {
205        return $content;
206    }
207
208    function _hdlr_if($args, $content, &$ctx, &$repeat, $cond_tag = 1) {
209        if (!isset($content)) {
210            if (!isset($args['elseif'])) {
211                $ctx->localize(array('conditional', 'else_content', 'elseif_content', 'elseif_conditional'));
212                unset($ctx->_tpl_vars['conditional']);
213                unset($ctx->_tpl_vars['else_content']);
214                unset($ctx->_tpl_vars['elseif_content']);
215                unset($ctx->_tpl_vars['elseif_conditional']);
216            }
217            if ($cond_tag == '1' or $cond_tag == '0')
218                $ctx->_tpl_vars['conditional'] = $cond_tag;
219            else
220                $ctx->_tpl_vars['conditional'] = $ctx->_tpl_vars[$cond_tag];
221        } else {
222            if (!$ctx->_tpl_vars['conditional']) {
223                if (isset($ctx->_tpl_vars['else_content'])) {
224                    $content = $ctx->_tpl_vars['else_content'];
225                } else {
226                    $content = '';
227                }
228            }
229            else {
230                if (isset($ctx->_tpl_vars['elseif_content'])) {
231                    $content = $ctx->_tpl_vars['elseif_content'];
232                }
233            }
234            if (!isset($args['elseif'])) {
235                $ctx->restore(array('conditional', 'else_content', 'elseif_content', 'elseif_conditional'));
236            }
237        }
238        return $content;
239    }
240
241    function smarty_block_elseif($args, $content, &$ctx, &$repeat) {
242        return $this->smarty_block_else($args, $content, $ctx, $repeat);
243    }
244
245    function smarty_block_else($args, $content, &$ctx, &$repeat) {
246        if (isset($ctx->_tpl_vars['elseif_content'])
247            or ($ctx->_tpl_vars['conditional'])) {
248            $repeat = false;
249            return '';
250        }
251        if ((count($args) > 0) && (!isset($args['name']) && !isset($args['var']) && !isset($args['tag']))) {
252            $vars =& $ctx->__stash['vars'];
253            if ( array_key_exists('__cond_tag__', $vars) ) {
254                $tag = $vars['__cond_tag__'];
255                unset($vars['__cond_tag__']);
256                if ( isset($tag) && $tag )
257                    $args['tag'] = $tag;
258            }
259            else if ( array_key_exists('__cond_name__', $vars) ) {
260                $name = $vars['__cond_name__'];
261                unset($vars['__cond_name__']);
262                if ( isset($name) && $name )
263                    $args['name'] = $name;
264            }
265            if ( array_key_exists('__cond_value__', $vars) ) {
266                $value = $vars['__cond_value__'];
267                unset($vars['__cond_value__']);
268                if ( isset($value) && $value )
269                    $args['value'] = $value;
270            }
271            $ctx->__stash['vars'] =& $vars;
272        }
273        if (count($args) >= 1) { # else-if case
274            require_once("block.mtif.php");
275            $args['elseif'] = 1;
276            if (!isset($content)) {
277                $out = smarty_block_mtif($args, $content, $ctx, $repeat);
278                if ($ctx->_tpl_vars['conditional']) {
279                    $ctx->_tpl_vars['elseif_conditional'] = 1;
280                    unset($ctx->_tpl_vars['conditional']);
281                }
282            } else {
283                // $out = smarty_block_mtif($args, $content, $ctx, $repeat);
284                if ($ctx->_tpl_vars['elseif_conditional']) {
285                    $ctx->_tpl_vars['elseif_content'] = $content;
286                    $ctx->_tpl_vars['conditional'] = 1;
287                }
288            }
289            return '';
290        }
291        if (!isset($content)) {
292            if ($ctx->_tpl_vars['conditional'])
293                $repeat = false;
294        } else {
295            $else_content = $ctx->_tpl_vars['else_content'];
296            $else_content .= $content;
297            $ctx->_tpl_vars['else_content'] = $else_content;
298        }
299        return '';
300    }
301
302    function _hdlr_date($args, &$ctx) {
303        $ts = null;
304        if (isset($args['ts'])) {
305            $ts = $args['ts'];
306        }
307        $ts or $ts = $ctx->stash('current_timestamp');
308        $ts = preg_replace('![^0-9]!', '', $ts);
309        $blog = $ctx->stash('blog');
310        if ($ts == '') {
311            $t = time();
312            if ($args['utc']) {
313                $ts = gmtime($t);
314            } else {
315                $ts = offset_time_list($t, $blog);
316            }
317            $ts = sprintf("%04d%02d%02d%02d%02d%02d",
318                $ts[5]+1900, $ts[4]+1, $ts[3], $ts[2], $ts[1], $ts[0]);
319        }
320        if (isset($args['utc'])) {
321            if (!is_array($blog)) {
322                $blog = $ctx->mt->db->fetch_blog($blog);
323            }
324            preg_match('/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/', $ts, $matches);
325            list($all, $y, $mo, $d, $h, $m, $s) = $matches;
326            $so = $blog['blog_server_offset'];
327            $timelocal = mktime($h, $m, $s, $mo, $d, $y);
328            $localtime = localtime($timelocal);
329            if ($localtime[8])
330                $so += 1;
331            $partial_hour_offset = 60 * abs($so - intval($so));
332            $four_digit_offset = sprintf('%s%02d%02d', $so < 0 ? '-' : '+',
333                                         abs($so), $partial_hour_offset);
334            $ts = gmdate('YmdHis', strtotime("$y-$mo-$d $h:$m:$s $four_digit_offset"));
335        }
336        if (isset($args['format_name'])) {
337            if ($format = $args['format_name']) {
338                $tz = 'Z';
339                if (!$args['utc']) {
340                    $blog = $ctx->stash('blog');
341                    if (!is_array($blog)) {
342                        $blog = $ctx->mt->db->fetch_blog($blog);
343                    }
344                    $so = $blog['blog_server_offset'];
345                    $partial_hour_offset = 60 * abs($so - intval($so));
346                    if ($format == 'rfc822') {
347                        $tz = sprintf("%s%02d%02d", $so < 0 ? '-' : '+',
348                                  abs($so), $partial_hour_offset);
349                    }
350                    elseif ($format == 'iso8601') {
351                        $tz = sprintf("%s%02d:%02d", $so < 0 ? '-' : '+',
352                                  abs($so), $partial_hour_offset);
353                    }
354                }
355                if ($format == 'rfc822') {
356                    $args['format'] = '%a, %d %b %Y %H:%M:%S ' . $tz;
357                    $args['language'] = 'en';
358                }
359                elseif ($format == 'iso8601') {
360                    $args['format'] = '%Y-%m-%dT%H:%M:%S'. $tz;
361                }
362            }
363        }
364        if (!isset($args['format'])) $args['format'] = null;
365        require_once("MTUtil.php");
366        $fds = format_ts($args['format'], $ts, $blog, isset($args['language']) ? $args['language'] : null);
367        if (isset($args['relative'])) {
368            if ($args['relative'] == 'js') {
369                preg_match('/(\d\d\d\d)[^\d]?(\d\d)[^\d]?(\d\d)[^\d]?(\d\d)[^\d]?(\d\d)[^\d]?(\d\d)/', $ts, $match);
370                list($xx, $y, $mo, $d, $h, $m, $s) = $match;
371                $mo--;
372                $js = <<<EOT
373<script type="text/javascript">
374/* <![CDATA[ */
375document.write(mtRelativeDate(new Date($y,$mo,$d,$h,$m,$s), '$fds'));
376/* ]]> */
377</script><noscript>$fds</noscript>
378EOT;
379                return $js;
380            }
381        }
382        return $fds;
383    }
384
385    function tag($tag, $args = array()) {
386        $tag = preg_replace('/^mt:?/i', '', strtolower($tag));
387        if ((array_key_exists('mt' . $tag, $this->conditionals)) || (preg_match('/^if/i', $tag) || preg_match('/^has/', $tag) || preg_match('/[a-z](header|footer|previous|next)$/i', $tag))) {
388            list($hdlr) = $this->handler_for($tag);
389            if (!$hdlr) {
390                $fntag = 'smarty_block_mt' . $tag;
391                if (!function_exists($fntag))
392                    @include_once("block.mt$tag.php");
393                if (function_exists($fntag))
394                    $hdlr = $fntag;
395            }
396            if ($hdlr) {
397                $this->_tag_stack[] = array("mt$tag", $args);
398                $repeat = true;
399                $hdlr($args, NULL, $this, $repeat);
400                if ($repeat) {
401                    $content = 'true';
402                    $content = $hdlr($args, $content, $this, $repeat = false);
403                    $result = isset($content) && ($content === 'true');
404                } else {
405                    $result = false;
406                }
407                array_pop($this->_tag_stack);
408                return $result;
409            }
410        } else {
411            list($hdlr, $type) = $this->handler_for("mt" . $tag);
412            if ($hdlr) $block_tag = $type == 'block';
413            if (!$hdlr) {
414                $fntag = 'smarty_function_mt'.$tag;
415                if (!function_exists($fntag))
416                  if (file_exists($this->mt->config['phplibdir']."/function.mt$tag.php"))
417                        @include_once("function.mt$tag.php");
418                if (function_exists($fntag))
419                    $hdlr = $fntag;
420            }
421            if (!$hdlr) { // try block tags
422                $fntag = 'smarty_block_mt'.$tag;
423                if (!function_exists($fntag))
424                    if (file_exists($this->mt->config['phplibdir']."/block.mt$tag.php"))
425                        @include_once("block.mt$tag.php");
426                if (function_exists($fntag)) {
427                    $hdlr = $fntag;
428                    $block_tag = true;
429                }
430            }
431            if ($hdlr) {
432                if ($block_tag) {
433                    $this->_tag_stack[] = array("mt$tag", $args);
434                    $repeat = true;
435                    $hdlr($args, NULL, $this, $repeat);
436                    if ($repeat) {
437                        $content = 'true';
438                        $content = $hdlr($args, $content, $this, $repeat = false);
439                        $result = isset($content) && ($content === 'true');
440                    } else {
441                        $result = false;
442                    }
443                    array_pop($this->_tag_stack);
444                    return $result;
445                }
446                $this->_tag_stack[] = array("mt$tag", $args);
447                $content = $hdlr($args, $this);
448                foreach ($args as $k => $v) {
449                    if (array_key_exists($k, $this->global_attr)) {
450                        $fnmod = 'smarty_modifier_' . $k;
451                        if (!function_exists($fnmod))
452                            $this->load_modifier($k);
453                        if (function_exists($fnmod))
454                            $content = $fnmod($content, $v);
455                    }
456                }
457                array_pop($this->_tag_stack);
458                return $content;
459            }
460        }
461        return $this->error("Tag &lt;mt$tag&gt; does not exist.");
462    }
463
464    function load_modifier($name) {
465        $params = array('plugins' => array(array('modifier', $name, null, null, false)));
466        smarty_core_load_plugins($params, $this);
467        return true;
468    }
469
470    function register_tag_handler($tag, $fn, $type) {
471        if (substr($tag, 0, 2) != 'mt') {
472            $tag = 'mt' . $tag;
473        }
474        if ($type == 'block')
475            $this->register_block($tag, $fn);
476        elseif ($type == 'function')
477            $this->register_function($tag, $fn);
478        $old_handler = $this->_handlers[$tag];
479        $this->_handlers[$tag] = array( $fn, $type );
480        if ($old_handler) {
481            $fn = $old_handler[0];
482        } else {
483            if ($type == 'block')
484                $fn = create_function('$args, $content, &$ctx, &$repeat', 'if (!isset($content)) @include_once "block.' . $tag . '.php"; if (function_exists("smarty_block_' . $tag . '")) { return smarty_block_' . $tag . '($args, $content, $ctx, $repeat); } $repeat = false; return "";');
485            elseif ($type == 'function') {
486                $fn = create_function('$args, &$ctx', '@include_once "function.' . $tag . '.php"; if (function_exists("smarty_function_' . $tag . '")) { return smarty_function_' . $tag . '($args, $ctx); } return "";');
487            }
488        }
489        return $fn;
490    }
491    function add_container_tag($tag, $fn = null) {
492        return $this->register_tag_handler($tag, $fn, 'block');
493    }
494    function add_tag($tag, $fn) {
495        return $this->register_tag_handler($tag, $fn, 'function');
496    }
497    function handler_for($tag) {
498        if (isset($this->_handlers[$tag]))
499            return $this->_handlers[$tag];
500        else
501            return null;
502    }
503
504    function count_format($count, $args) {
505        $phrase = '';
506        if ($count == 0) {
507            $phrase = array_key_exists('none', $args) ? $args['none'] :
508                (array_key_exists('plural', $args) ? $args['plural'] : '');
509        } elseif ($count == 1) {
510            $phrase = array_key_exists('singular', $args) ? $args['singular'] : '';
511        } elseif ($count > 1) {
512            $phrase = array_key_exists('plural', $args) ? $args['plural'] : '';
513        }
514        if ($phrase == '')
515            return $count;
516
517        // \# of entries: #  --> # of entries: 10
518        $phrase = preg_replace('/(?<!\\\\)#/', $count, $phrase);
519        $phrase = preg_replace('/\\\\#/', '#', $phrase);
520
521        return $phrase;
522    }
523}
Note: See TracBrowser for help on using the browser.