root/branches/release-34/php/lib/MTViewer.php @ 1876

Revision 1876, 16.5 kB (checked in by fumiakiy, 20 months ago)

Fixed the issue in which MTElse and MTElseIf did not work correctly when "name" or "tag" argument was omitted both in static and in dynamic. BugId:69678

Also fixed the bug case filed as BugId:79027 in PHP tag handlers.

  • 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         # native smarty modifiers
73        'regex_replace' => 1,
74        'capitalize' => 1,
75        'count_characters' => 1,
76        'cat' => 1,
77        'count_paragraphs' => 1,
78        'count_sentences' => 1,
79        'count_words' => 1,
80        'date_format' => 1,
81        '_default' => 'default',
82        'escape' => 1,
83        'indent' => 1,
84        'nl2br' => 1,
85        'replace' => 1,
86        'spacify' => 1,
87        'string_format' => 1,
88        'strip' => 1,
89        'strip_tags' => 1,
90        'truncate' => 1,
91        'wordwrap' => 1,
92    );
93    var $needs_tokens = array(
94        'mtsubcategories' => 1,
95        'mttoplevelcategories' => 1,
96        'mtsubfolers' => 1,
97        'mttoplevelfolders' => 1,
98        'mtcommentreplies' => 1,
99        'mtsetvartemplate' => 1,
100    );
101
102    function MTViewer(&$mt) {
103        // prevents an unknown index error within Smarty.class.php
104        $this->id = md5(uniqid('MTViewer',true));
105        $_COOKIE['SMARTY_DEBUG'] = 0;
106        $GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG'] = 0;
107        $this->path_sep = (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') ? ';' : ':';
108        $this->Smarty();
109        $this->mt =& $mt;
110        $this->__stash =& $this->_tpl_vars;
111        $this->left_delimiter = "{{";
112        $this->right_delimiter = "}}";
113        $this->load_filter('pre', 'mt_to_smarty');
114        $this->register_block('mtdynamic', array(&$this, 'smarty_block_dynamic'),
115                              false);
116        $this->register_block('mtelse', array(&$this, 'smarty_block_else'));
117        $this->register_block('mtelseif', array(&$this, 'smarty_block_elseif'));
118
119        # Unregister the 'core' regex_replace so we can replace it
120        $this->register_modifier('regex_replace', array(&$this, 'regex_replace'));
121    }
122
123    function add_plugin_dir($plugin_dir) {
124        ini_set('include_path', $plugin_dir . $this->path_sep . ini_get('include_path'));
125        $this->plugins_dir[] = $plugin_dir;
126    }
127
128    function regex_replace($string, $search, $replace) {
129        if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (preg_match('/[eg]/', $match[1]))) {
130            if (strpos($match[1], "g") !== false)
131                $global = 1;
132            /* remove eval-modifier from $search */
133            $search = substr($search, 0, -strlen($match[1])) . preg_replace('![eg\s]+!', '', $match[1]);
134        }
135        return preg_replace($search, $replace, $string, $global ? -1 : 1);
136    }
137
138    function add_token_tag($name) {
139        $this->needs_tokens[$name] = 1;
140    }
141
142    function add_conditional_tag($name, $code = null, $cacheable = null, $cache_attrs = null) {
143        $this->conditionals[$name] = 1;
144        if (isset($code)) {
145            $this->register_block($name, $code, $cacheable, $cache_attrs);
146        }
147    }
148
149    function add_global_filter($name, $code = null) {
150        $this->global_attr[$name] = 1;
151        if (isset($code)) {
152            $this->register_modifier($name, $code);
153        }
154    }
155
156    function error($err, $error_type = E_USER_ERROR) {
157        trigger_error($err, $error_type);
158        return '';
159    }
160
161    function this_tag() {
162        $ts = $this->_tag_stack[count($this->_tag_stack)-1];
163        if ($ts) {
164            return $ts[0];
165        } else {
166            return null;
167        }
168    }
169
170    function stash($name,$value=null) {
171        if(isset($this->__stash[$name]))
172            $old_val = $this->__stash[$name];
173        else
174            $old_val = null;
175        if(func_num_args() > 1)
176            $this->__stash[$name] = $value;
177        return $old_val;
178    }
179
180    function localize($vars) {
181        foreach ($vars as $v) {
182            if (!isset($this->varstack[$v])) $this->varstack[$v] = array();
183            $this->varstack[$v][] = isset($this->__stash[$v]) ? $this->__stash[$v] : null;
184        }
185    }
186
187    function restore($vars) {
188        foreach ($vars as $v) {
189            $this->__stash[$v] = (isset($this->varstack[$v]) && count($this->varstack[$v]) > 0) ? array_pop($this->varstack[$v]) : null;
190        }
191    }
192
193    function last_ts($ts = 0) {
194        if ($ts > 0) {
195            $ts = preg_replace('/[ :-]/', '', $ts);
196            if ($ts > $this->last_ts) {
197                $this->last_ts = $ts;
198            }
199        }
200        return $this->last_ts;
201    }
202
203    function smarty_block_dynamic($param, $content, &$smarty) {
204        return $content;
205    }
206
207    function _hdlr_if($args, $content, &$ctx, &$repeat, $cond_tag = 1) {
208        if (!isset($content)) {
209            if (!isset($args['elseif'])) {
210                $ctx->localize(array('conditional', 'else_content', 'elseif_content', 'elseif_conditional'));
211                unset($ctx->_tpl_vars['conditional']);
212                unset($ctx->_tpl_vars['else_content']);
213                unset($ctx->_tpl_vars['elseif_content']);
214                unset($ctx->_tpl_vars['elseif_conditional']);
215            }
216            if ($cond_tag == '1' or $cond_tag == '0')
217                $ctx->_tpl_vars['conditional'] = $cond_tag;
218            else
219                $ctx->_tpl_vars['conditional'] = $ctx->_tpl_vars[$cond_tag];
220        } else {
221            if (!$ctx->_tpl_vars['conditional']) {
222                if (isset($ctx->_tpl_vars['else_content'])) {
223                    $content = $ctx->_tpl_vars['else_content'];
224                } else {
225                    $content = '';
226                }
227            }
228            else {
229                if (isset($ctx->_tpl_vars['elseif_content'])) {
230                    $content = $ctx->_tpl_vars['elseif_content'];
231                }
232            }
233            if (!isset($args['elseif'])) {
234                $ctx->restore(array('conditional', 'else_content', 'elseif_content', 'elseif_conditional'));
235            }
236        }
237        return $content;
238    }
239
240    function smarty_block_elseif($args, $content, &$ctx, &$repeat) {
241        return $this->smarty_block_else($args, $content, $ctx, $repeat);
242    }
243
244    function smarty_block_else($args, $content, &$ctx, &$repeat) {
245        if (isset($ctx->_tpl_vars['elseif_content'])
246            or ($ctx->_tpl_vars['conditional'])) {
247            $repeat = false;
248            return '';
249        }
250        if ((count($args) > 0) && (!isset($args['name']) && !isset($args['var']) && !isset($args['tag']))) {
251            $vars =& $ctx->__stash['vars'];
252            if ( array_key_exists('__cond_tag__', $vars) ) {
253                $tag = $vars['__cond_tag__'];
254                unset($vars['__cond_tag__']);
255                if ( isset($tag) && $tag )
256                    $args['tag'] = $tag;
257            }
258            else if ( array_key_exists('__cond_name__', $vars) ) {
259                $name = $vars['__cond_name__'];
260                unset($vars['__cond_name__']);
261                if ( isset($name) && $name )
262                    $args['name'] = $name;
263            }
264            if ( array_key_exists('__cond_value__', $vars) ) {
265                $value = $vars['__cond_value__'];
266                unset($vars['__cond_value__']);
267                if ( isset($value) && $value )
268                    $args['value'] = $value;
269            }
270            $ctx->__stash['vars'] =& $vars;
271        }
272        if (count($args) >= 1) { # else-if case
273            require_once("block.mtif.php");
274            $args['elseif'] = 1;
275            if (!isset($content)) {
276                $out = smarty_block_mtif($args, $content, $ctx, $repeat);
277                if ($ctx->_tpl_vars['conditional']) {
278                    $ctx->_tpl_vars['elseif_conditional'] = 1;
279                    unset($ctx->_tpl_vars['conditional']);
280                }
281            } else {
282                // $out = smarty_block_mtif($args, $content, $ctx, $repeat);
283                if ($ctx->_tpl_vars['elseif_conditional']) {
284                    $ctx->_tpl_vars['elseif_content'] = $content;
285                    $ctx->_tpl_vars['conditional'] = 1;
286                }
287            }
288            return '';
289        }
290        if (!isset($content)) {
291            if ($ctx->_tpl_vars['conditional'])
292                $repeat = false;
293        } else {
294            $else_content = $ctx->_tpl_vars['else_content'];
295            $else_content .= $content;
296            $ctx->_tpl_vars['else_content'] = $else_content;
297        }
298        return '';
299    }
300
301    function _hdlr_date($args, &$ctx) {
302        $ts = null;
303        if (isset($args['ts'])) {
304            $ts = $args['ts'];
305        }
306        $ts or $ts = $ctx->stash('current_timestamp');
307        $ts = preg_replace('![^0-9]!', '', $ts);
308        $blog = $ctx->stash('blog');
309        if ($ts == '') {
310            $t = time();
311            if ($args['utc']) {
312                $ts = gmtime($t);
313            } else {
314                $ts = offset_time_list($t, $blog);
315            }
316            $ts = sprintf("%04d%02d%02d%02d%02d%02d",
317                $ts[5]+1900, $ts[4]+1, $ts[3], $ts[2], $ts[1], $ts[0]);
318        }
319        if (isset($args['utc'])) {
320            if (!is_array($blog)) {
321                $blog = $ctx->mt->db->fetch_blog($blog);
322            }
323            preg_match('/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/', $ts, $matches);
324            list($all, $y, $mo, $d, $h, $m, $s) = $matches;
325            $so = $blog['blog_server_offset'];
326            $timelocal = mktime($h, $m, $s, $mo, $d, $y);
327            $localtime = localtime($timelocal);
328            if ($localtime[8])
329                $so += 1;
330            $partial_hour_offset = 60 * abs($so - intval($so));
331            $four_digit_offset = sprintf('%s%02d%02d', $so < 0 ? '-' : '+',
332                                         abs($so), $partial_hour_offset);
333            $ts = gmdate('YmdHis', strtotime("$y-$mo-$d $h:$m:$s $four_digit_offset"));
334        }
335        if (isset($args['format_name'])) {
336            if ($format = $args['format_name']) {
337                $tz = 'Z';
338                if (!$args['utc']) {
339                    $blog = $ctx->stash('blog');
340                    if (!is_array($blog)) {
341                        $blog = $ctx->mt->db->fetch_blog($blog);
342                    }
343                    $so = $blog['blog_server_offset'];
344                    $partial_hour_offset = 60 * abs($so - intval($so));
345                    if ($format == 'rfc822') {
346                        $tz = sprintf("%s%02d%02d", $so < 0 ? '-' : '+',
347                                  abs($so), $partial_hour_offset);
348                    }
349                    elseif ($format == 'iso8601') {
350                        $tz = sprintf("%s%02d:%02d", $so < 0 ? '-' : '+',
351                                  abs($so), $partial_hour_offset);
352                    }
353                }
354                if ($format == 'rfc822') {
355                    $args['format'] = '%a, %d %b %Y %H:%M:%S ' . $tz;
356                    $args['language'] = 'en';
357                }
358                elseif ($format == 'iso8601') {
359                    $args['format'] = '%Y-%m-%dT%H:%M:%S'. $tz;
360                }
361            }
362        }
363        if (!isset($args['format'])) $args['format'] = null;
364        require_once("MTUtil.php");
365        return format_ts($args['format'], $ts, $blog, isset($args['language']) ? $args['language'] : null);
366    }
367
368    function tag($tag, $args = array()) {
369        $tag = preg_replace('/^mt:?/i', '', strtolower($tag));
370        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))) {
371            list($hdlr) = $this->handler_for($tag);
372            if (!$hdlr) {
373                $fntag = 'smarty_block_mt' . $tag;
374                if (!function_exists($fntag))
375                    @include_once("block.mt$tag.php");
376                if (function_exists($fntag))
377                    $hdlr = $fntag;
378            }
379            if ($hdlr) {
380                $hdlr($args, NULL, $this, $repeat = true);
381                if ($repeat) {
382                    $content = 'true';
383                    $this->_tag_stack[] = array("mt$tag", $args);
384                    $content = $hdlr($args, $content, $this, $repeat = false);
385                    array_pop($this->_tag_stack);
386                    return isset($content) && ($content === 'true');
387                } else {
388                    return false;
389                }
390            }
391        } else {
392            list($hdlr) = $this->handler_for("mt" . $tag);
393            if (!$hdlr) {
394                $fntag = 'smarty_function_mt'.$tag;
395                if (!function_exists($fntag))
396                    @include_once("function.mt$tag.php");
397                if (function_exists($fntag))
398                    $hdlr = $fntag;
399            }
400            if ($hdlr) {
401                $this->_tag_stack[] = array("mt$tag", $args);
402                $content = $hdlr($args, $this);
403                foreach ($args as $k => $v) {
404                    if (array_key_exists($k, $this->global_attr)) {
405                        $fnmod = 'smarty_modifier_' . $k;
406                        if (!function_exists($fnmod))
407                            $this->load_modifier($k);
408                        if (function_exists($fnmod))
409                            $content = $fnmod($content, $v);
410                    }
411                }
412                array_pop($this->_tag_stack);
413                return $content;
414            }
415        }
416        return $this->error("Tag &lt;mt$tag&gt; does not exist.");
417    }
418
419    function load_modifier($name) {
420        $params = array('plugins' => array(array('modifier', $name, null, null, false)));
421        smarty_core_load_plugins($params, $this);
422        return true;
423    }
424
425    function register_tag_handler($tag, $fn, $type) {
426        if (substr($tag, 0, 2) != 'mt') {
427            $tag = 'mt' . $tag;
428        }
429        if ($type == 'block')
430            $this->register_block($tag, $fn);
431        elseif ($type == 'function')
432            $this->register_function($tag, $fn);
433        $old_handler = $this->_handlers[$tag];
434        $this->_handlers[$tag] = array( $fn, $type );
435        if ($old_handler) {
436            $fn = $old_handler[0];
437        } else {
438            if ($type == 'block')
439                $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 "";');
440            elseif ($type == 'function') {
441                $fn = create_function('$args, &$ctx', '@include_once "function.' . $tag . '.php"; if (function_exists("smarty_function_' . $tag . '")) { return smarty_function_' . $tag . '($args, $ctx); } return "";');
442            }
443        }
444        return $fn;
445    }
446    function add_container_tag($tag, $fn = null) {
447        return $this->register_tag_handler($tag, $fn, 'block');
448    }
449    function add_tag($tag, $fn) {
450        return $this->register_tag_handler($tag, $fn, 'function');
451    }
452    function handler_for($tag) {
453        if (isset($this->_handlers[$tag]))
454            return $this->_handlers[$tag];
455        else
456            return null;
457    }
458}
459?>
Note: See TracBrowser for help on using the browser.