root/branches/athena/php/mt.php.pre @ 1092

Revision 1092, 27.9 kB (checked in by hachi, 2 years ago)

Merging release-15 to athena branch. svn merge -r59987:60375 http://svn.sixapart.com/repos/eng/movabletype/branches/release-15 .

  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2# Copyright 2001-2007 Six Apart. This code cannot be redistributed without
3# permission from www.sixapart.com.  For more information, consult your
4# Movable Type license.
5#
6# $Id$
7
8define('VERSION', '__API_VERSION__');
9define('VERSION_ID', '__PRODUCT_VERSION_ID__');
10define('PRODUCT_VERSION', '__PRODUCT_VERSION__');
11define('PRODUCT_NAME', '__PRODUCT_NAME__');
12
13global $Lexicon;
14$Lexicon = array();
15
16class MT {
17    var $mime_types = array(
18        '__default__' => 'text/html',
19        'css' => 'text/css',
20        'txt' => 'text/plain',
21        'rdf' => 'text/xml',
22        'rss' => 'text/xml',
23        'xml' => 'text/xml',
24    );
25    var $blog_id;
26    var $db;
27    var $config;
28    var $debugging = false;
29    var $caching = false;
30    var $conditional = false;
31    var $log = array();
32    var $id;
33    var $request;
34    var $http_error;
35    var $cfg_file;
36
37    /***
38     * Constructor for MT class. Also declares a global variable
39     * '$mt' and assigns itself to that. There can only be one
40     * instance of this class.
41     */
42    function MT($blog_id = null, $cfg_file = null) {
43        error_reporting(E_ALL ^ E_NOTICE);
44        global $mt;
45        if (isset($mt)) {
46            die("Only one instance of the MT class can be created.");
47        }
48        $this->id = md5(uniqid('MT',true));
49        $this->init($blog_id, $cfg_file);
50    }
51
52    function init($blog_id = null, $cfg_file = null) {
53        if (isset($blog_id)) {
54            $this->blog_id = $blog_id;
55        }
56
57        if (!file_exists($cfg_file)) {
58            $mtdir = dirname(dirname(__FILE__));
59            $cfg_file = $mtdir . DIRECTORY_SEPARATOR . "mt-config.cgi";
60        }
61
62        $this->configure($cfg_file);
63        $this->init_addons();
64        $this->configure_from_db();
65
66        $lang = substr(strtolower($this->config('DefaultLanguage')), 0, 2);
67        if (!@include_once("l10n_$lang.php"))
68            include_once("l10n_en.php");
69
70        if (extension_loaded('mbstring')) {
71            $charset = $this->config('PublishCharset');
72            mb_internal_encoding($charset);
73            mb_http_output($charset);
74        }
75    }
76
77    function init_addons() {
78        $mtdir = dirname(dirname(__FILE__));
79        $path = $mtdir . DIRECTORY_SEPARATOR . "addons";
80        if (is_dir($path)) {
81            $ctx =& $this->context();
82            if ($dh = opendir($path)) {
83                while (($file = readdir($dh)) !== false) {
84                    if ($file == "." || $file == "..") {
85                        continue;
86                    }
87                    $plugin_dir = $path . DIRECTORY_SEPARATOR . $file
88                        . DIRECTORY_SEPARATOR . 'php';
89                    if (is_dir($plugin_dir)) {
90                        $ctx->plugins_dir[] = $plugin_dir;
91                        $this->load_plugin($plugin_dir);
92                    }
93                }
94                closedir($dh);
95            }
96        }
97    }
98
99    function init_plugins() {
100        $plugin_paths = $this->config('PluginPath');
101        $ctx =& $this->context();
102        foreach ($plugin_paths as $path) {
103            if ($dh = opendir($path)) {
104                 while (($file = readdir($dh)) !== false) {
105                     if ($file == "." || $file == "..") {
106                         continue;
107                     }
108                     $plugin_dir = $path . DIRECTORY_SEPARATOR . $file
109                         . DIRECTORY_SEPARATOR . 'php';
110                     if (is_dir($plugin_dir)) {
111                         $ctx->plugins_dir[] = $plugin_dir;
112                         $this->load_plugin($plugin_dir);
113                     }
114                 }
115                 closedir($dh);
116            }
117        }
118
119        $plugin_dir = $this->config('PHPDir') . DIRECTORY_SEPARATOR
120            . 'plugins';
121        if (is_dir($plugin_dir)) {
122            $this->load_plugin($plugin_dir);
123        }
124    }
125
126    function load_plugin($plugin_dir) {
127        $path_sep = (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) ? ';' : ':';
128        ini_set('include_path', $plugin_dir . $path_sep . ini_get('include_path'));
129
130        $ctx =& $this->context();
131        // global filters have to be handled differently from
132        // tag attributes, so this causes them to be recognized
133        // as they should...
134        if ($dh = opendir($plugin_dir)) {
135            while (($file = readdir($dh)) !== false) {
136                if (preg_match('/^modifier\.(.+?)\.php$/', $file, $matches)) {
137                    $ctx->add_global_filter($matches[1]);
138                } elseif (preg_match('/^init\.(.+?)\.php$/', $file, $matches)) {
139                    // load 'init' plugin file
140                    require_once($file);
141                }
142            }
143            closedir($dh);
144        }
145    }
146
147    /***
148     * Retreives a handle to the database and assigns it to
149     * the member variable 'db'.
150     */
151    function &db() {
152        if (isset($this->db)) return $this->db;
153
154        require_once("mtdb_".$this->config('DBDriver').".php");
155        $mtdbclass = 'MTDatabase_'.$this->config('DBDriver');
156        $this->db = new $mtdbclass($this->config('DBUser'),
157            $this->config('DBPassword'), $this->config('Database'),
158            $this->config('DBHost'), $this->config('DBPort'));
159        return $this->db;
160    }
161
162    function config($id, $value = null) {
163        $id = strtolower($id);
164        if (isset($value))
165            $this->config[$id] = $value;
166        return $this->config[$id];
167    }
168
169    /***
170     * Loads configuration data from mt.cfg and mt-db-pass.cgi files.
171     * Stores content in the 'config' member variable.
172     */
173    function configure($file = null) {
174        if (isset($this->config)) return $config;
175
176        $this->cfg_file = $file;
177
178        $cfg = array();
179        $type_array = array('pluginpath', 'alttemplate', 'outboundtrackbackdomains', 'memcachedservers');
180        if ($fp = file($file)) {
181            foreach ($fp as $line) {
182                // search through the file
183                if (!ereg('^\s*\#',$line)) {
184                    // ignore lines starting with the hash symbol
185                    if (preg_match('/^\s*(\S+)\s+(.*)$/', $line, $regs)) {
186                        $key = strtolower(trim($regs[1]));
187                        $value = trim($regs[2]);
188                        if (in_array($key, $type_array)) {
189                            $cfg[$key][] = $value;
190                        } else {
191                            $cfg[$key] = $value;
192                        }
193                    }
194                }
195            }
196        } else {
197            die("Unable to open configuration file $file");
198        }
199
200        // setup directory locations
201        // location of mt.php
202        $cfg['phpdir'] = realpath(dirname(__FILE__));
203        // path to MT directory
204        $cfg['mtdir'] = realpath(dirname($file));
205        // path to handlers
206        $cfg['phplibdir'] = $cfg['phpdir'] . DIRECTORY_SEPARATOR . 'lib';
207
208        $cfg['dbhost'] or $cfg['dbhost'] = 'localhost'; // default to localhost
209        $driver = $cfg['objectdriver'];
210        $driver = preg_replace('/^DB[ID]::/', '', $driver);
211        $driver or $driver = 'mysql';
212        $cfg['dbdriver'] = strtolower($driver);
213   
214        if ((strlen($cfg['database'])<1 || strlen($cfg['dbuser'])<1)) {
215            if (($cfg['dbdriver'] != 'sqlite') && ($cfg['dbdriver'] != 'mssqlserver')) {
216                die("Unable to read database or username");
217            }
218        }
219
220        $this->config =& $cfg;
221        $this->config_defaults();
222
223        // read in the database password
224        if (!isset($cfg['dbpassword'])) {
225            $db_pass_file = $cfg['mtdir'] . DIRECTORY_SEPARATOR . 'mt-db-pass.cgi';
226            if (file_exists($db_pass_file)) {
227                $password = implode('', file($db_pass_file));
228                $password = trim($password, "\n\r\0");
229                $cfg['dbpassword'] = $password;
230            }
231        }
232
233        // set up include path
234        // add MT-PHP 'plugins' and 'lib' directories to the front
235        // of the existing PHP include path:
236        if (strtoupper(substr(PHP_OS, 0,3) == 'WIN')) {
237            $path_sep = ';';
238        } else {
239            $path_sep = ':';
240        }
241        ini_set('include_path',
242            $cfg['phpdir'] . DIRECTORY_SEPARATOR . "lib" . $path_sep .
243            $cfg['phpdir'] . DIRECTORY_SEPARATOR . "extlib" . $path_sep .
244            $cfg['phpdir'] . DIRECTORY_SEPARATOR . "extlib" . DIRECTORY_SEPARATOR . "smarty" . DIRECTORY_SEPARATOR . "libs" . $path_sep .
245            ini_get('include_path')
246        );
247    }
248
249    function configure_from_db() {
250        $cfg =& $this->config;
251        $mtdb =& $this->db();
252        $db_config = $mtdb->fetch_config();
253        if ($db_config) {
254            $data = $db_config['config_data'];
255            $data = preg_split('/[\r?\n]/', $data);
256            foreach ($data as $line) {
257                // search through the file
258                if (!ereg('^\s*\#',$line)) {
259                    // ignore lines starting with the hash symbol
260                    if (preg_match('/^\s*(\S+)\s+(.*)$/', $line, $regs)) {
261                        $key = strtolower(trim($regs[1]));
262                        $value = trim($regs[2]);
263                        if (($key == 'PluginSwitch') || ($key == 'PluginSchemaVersion')) { # special case for hash
264                            if (preg_match('/^(.+)=(.+)$/', $value, $match))
265                                $cfg[$key][trim($match[1])] = trim($match[2]);
266                        } else {
267                            $cfg[$key] or $cfg[$key] = $value;
268                        }
269                    }
270                }
271            }
272            if ($cfg['dbdriver'] == 'mysql' or $cfg['dbdriver'] == 'postgres') {
273                if ($cfg['sqlsetnames']) {
274                    $Charset = array(
275                        'postgres' => array('utf-8' => 'UNICODE', 'shift_jis' => 'SJIS', 'euc-jp' => 'EUC_JP'),
276                        'mysql' => array('utf-8' => 'utf8', 'shift_jis' => 'sjis', 'euc-jp' => 'ujis'));
277                    $lang = $Charset[$cfg['dbdriver']][strtolower($cfg['publishcharset'])];
278                    if ($lang) {
279                        $mtdb->query("SET NAMES '$lang'");
280                    }
281                }
282            }           
283        }
284    }
285
286    function config_defaults() {
287        $cfg =& $this->config;
288        // assign defaults:
289        if (substr($cfg['cgipath'], strlen($cfg['cgipath']) - 1, 1) != '/')
290            $cfg['cgipath'] .= '/';
291        isset($cfg['staticwebpath']) or
292            $cfg['staticwebpath'] = $cfg['cgipath'] . 'mt-static/';
293        isset($cfg['publishcharset']) or
294            $cfg['publishcharset'] = '__PUBLISH_CHARSET__';
295        isset($cfg['trackbackscript']) or
296            $cfg['trackbackscript'] = 'mt-tb.cgi';
297        isset($cfg['adminscript']) or
298            $cfg['adminscript'] = 'mt.cgi';
299        isset($cfg['commentscript']) or
300            $cfg['commentscript'] = 'mt-comments.cgi';
301        isset($cfg['atomscript']) or
302            $cfg['atomscript'] = 'mt-atom.cgi';
303        isset($cfg['xmlrpcscript']) or
304            $cfg['xmlrpcscript'] = 'mt-xmlrpc.cgi';
305        isset($cfg['searchscript']) or
306            $cfg['searchscript'] = 'mt-search.cgi';
307        isset($cfg['defaultlanguage']) or
308            $cfg['defaultlanguage'] = '__BUILD_LANGUAGE__';
309        isset($cfg['globalsanitizespec']) or
310            $cfg['globalsanitizespec'] = 'a href,b,i,br/,p,strong,em,ul,ol,li,blockquote,pre';
311        isset($cfg['signonurl']) or
312            $cfg['signonurl'] = 'https://www.typekey.com/t/typekey/login?';
313        isset($cfg['signoffurl']) or
314            $cfg['signoffurl'] = 'https://www.typekey.com/t/typekey/logout?';
315        isset($cfg['identityurl']) or
316            $cfg['identityurl'] = 'http://profile.typekey.com/';
317        isset($cfg['publishcommentericon']) or
318            $cfg['publishcommentericon'] = '1';
319        isset($cfg['allowcomments']) or
320            $cfg['allowcomments'] = '1';
321        isset($cfg['allowpings']) or
322            $cfg['allowpings'] = '1';
323        isset($cfg['indexbasename']) or
324            $cfg['indexbasename'] = 'index';
325        isset($cfg['typekeyversion']) or
326            $cfg['typekeyversion'] = '1.1';
327        isset($cfg['assetcachedir']) or
328            $cfg['assetcachedir'] = 'assets_c';
329        isset($cfg['pluginpath']) or
330            $cfg['pluginpath'] = array($this->config('MTDir') . DIRECTORY_SEPARATOR . 'plugins');
331    }
332
333    function configure_paths($blog_site_path) {
334        if (preg_match('/^\./', $blog_site_path)) {
335            // relative address, so tack on the MT dir in front
336            $blog_site_path = $this->config('MTDir') .
337                DIRECTORY_SEPARATOR . $blog_site_path;
338        }
339        $this->config('PHPTemplateDir') or
340            $this->config('PHPTemplateDir', $blog_site_path .
341            DIRECTORY_SEPARATOR . 'templates');
342        $this->config('PHPCacheDir') or
343            $this->config('PHPCacheDir', $blog_site_path .
344            DIRECTORY_SEPARATOR . 'cache');
345
346        $ctx =& $this->context();
347        $ctx->template_dir = $this->config('PHPTemplateDir');
348        $ctx->compile_dir = $ctx->template_dir . '_c';
349        $ctx->cache_dir = $this->config('PHPCacheDir');
350    }
351
352    /***
353     * Mainline handler function.
354     */
355    function view($blog_id = null) {
356        if ($this->debugging) {
357            require_once("MTUtil.php");
358        }
359        $blog_id or $blog_id = $this->blog_id;
360
361        $ctx =& $this->context();
362        $this->init_plugins();
363        $ctx->caching = $this->caching;
364
365        // Some defaults...
366        $mtdb =& $this->db();
367        $ctx->mt->db =& $mtdb;
368
369        // Set up our customer error handler
370        set_error_handler(array(&$this, 'error_handler'));
371
372        // User-specified request through request variable
373        $path = $this->request;
374
375        // Apache request
376        if (!$path && $_SERVER['REQUEST_URI']) {
377            $path = $_SERVER['REQUEST_URI'];
378            // strip off any query string...
379            $path = preg_replace('/\?.*/', '', $path);
380            // strip any duplicated slashes...
381            $path = preg_replace('!/+!', '/', $path);
382        }
383
384        // IIS request by error document...
385        if (preg_match('/IIS/', $_SERVER['SERVER_SOFTWARE'])) {
386            // assume 404 handler
387            if (preg_match('/^\d+;(.*)$/', $_SERVER['QUERY_STRING'], $matches)) {
388                $path = $matches[1];
389                $path = preg_replace('!^http://[^/]+!', '', $path);
390                if (preg_match('/\?(.+)?/', $path, $matches)) {
391                    $_SERVER['QUERY_STRING'] = $matches[1];
392                    $path = preg_replace('/\?.*$/', '', $path);
393                }
394            }
395        }
396
397        // now set the path so it may be queried
398        $this->request = $path;
399
400        // When we are invoked as an ErrorDocument, the parameters are
401        // in the environment variables REDIRECT_*
402        if (isset($_SERVER['REDIRECT_QUERY_STRING'])) {
403            // todo: populate $_GET and QUERY_STRING with REDIRECT_QUERY_STRING
404            $_SERVER['QUERY_STRING'] = getenv('REDIRECT_QUERY_STRING');
405        }
406
407        if (preg_match('/\.(\w+)$/', $path, $matches)) {
408            $req_ext = strtolower($matches[1]);
409        }
410
411        $this->blog_id = $blog_id;
412
413        $data =& $this->resolve_url($path);
414        if (!$data) {
415            // 404!
416            $this->http_error = 404;
417            header("HTTP/1.1 404 Not found");
418            return $ctx->error("Page not found - $path", E_USER_ERROR);
419        }
420
421        $info =& $data['fileinfo'];
422        $fi_path = $info['fileinfo_url'];
423        $fid = $info['fileinfo_id'];
424        $at = $info['fileinfo_archive_type'];
425        $ts = $info['fileinfo_startdate'];
426        $tpl_id = $info['fileinfo_template_id'];
427        $cat = $info['fileinfo_category_id'];
428        $auth = $info['fileinfo_author_id'];
429        $entry_id = $info['fileinfo_entry_id'];
430        $blog_id = $info['fileinfo_blog_id'];
431        $blog =& $data['blog'];
432        if ($at == 'index') {
433            $at = null;
434            $ctx->stash('index_archive', true);
435        } else {
436            $ctx->stash('index_archive', false);
437        }
438        $tts = $data['template']['template_modified_on'];
439        if ($tts) {
440            $tts = offset_time(datetime_to_timestamp($tts), $blog);
441        }
442        $ctx->stash('template_timestamp', $tts);
443        $ctx->stash('template_created_on', $data['template']['template_created_on']);
444
445        $this->configure_paths($blog['blog_site_path']);
446
447        // start populating our stash
448        $ctx->stash('blog_id', $blog_id);
449        $ctx->stash('blog', $blog);
450        $ctx->stash('build_template_id', $tpl_id);
451
452        // conditional get support...
453        if ($this->caching) {
454            $this->cache_modified_check = true;
455        }
456        if ($this->conditional) {
457            $last_ts = $blog['blog_children_modified_on'];
458            $last_modified = $ctx->_hdlr_date(array('ts' => $last_ts, 'format' => '%a, %d %b %Y %H:%M:%S GMT', 'language' => 'en', 'utc' => 1), $ctx);
459            $this->doConditionalGet($last_modified);
460        }
461
462        $cache_id = $blog_id.';'.$fi_path;
463        if (!$ctx->is_cached('mt:'.$tpl_id, $cache_id)) {
464            if (isset($at) && ($at != 'Category')) {
465                global $_archivers;
466                require_once("archive_lib.php");
467                global $_archivers;
468                if (!isset($_archivers[$at])) {
469                    // 404
470                    $this->http_errr = 404;
471                    header("HTTP/1.1 404 Not Found");
472                    return $ctx->error("Page not found - $at", E_USER_ERROR);
473                }
474                $archiver = $_archivers[$at];
475                $archiver->template_params($ctx);
476            }
477
478            if ($cat) {
479                $archive_category = $mtdb->fetch_category($cat);
480                $ctx->stash('category', $archive_category);
481                $ctx->stash('archive_category', $archive_category);
482            }
483            if ($auth) {
484                $archive_author = $mtdb->fetch_author($auth);
485                $ctx->stash('author', $archive_author);
486                $ctx->stash('archive_author', $archive_author);
487            }
488            if (isset($at)) {
489                if (($at != 'Category') && isset($ts)) {
490                    list($ts_start, $ts_end) = $archiver->get_range($ctx, $ts);
491                    $ctx->stash('current_timestamp', $ts_start);
492                    $ctx->stash('current_timestamp_end', $ts_end);
493                }
494                $ctx->stash('current_archive_type', $at);
495            }
496   
497            if (isset($entry_id) && ($entry_id) && ($at == 'Individual' || $at == 'Page')) {
498                if ($at == 'Individual') {
499                    $entry =& $mtdb->fetch_entry($entry_id);
500                } elseif($at == 'Page') {
501                    $entry =& $mtdb->fetch_page($entry_id);
502                }
503                $ctx->stash('entry', $entry);
504                $ctx->stash('current_timestamp', $entry['entry_authored_on']);
505            }
506
507            if ($at == 'Category') {
508                $vars =& $ctx->__stash['vars'];
509                $vars['archive_class'] = "category-archive";
510                $vars['category_archive'] = 1;
511                $vars['main_template'] = 1;
512                $vars['archive_template'] = 1;
513                $vars['module_category_archives'] = 1;
514                $vars['module_category-monthly_archives'] = 1;
515            }
516        }
517
518        $output = $ctx->fetch('mt:'.$tpl_id, $cache_id);
519
520        $this->http_error = 200;
521        header("HTTP/1.1 200 OK");
522        // content-type header-- need to supplement with charset
523        $content_type = $ctx->stash('content_type');
524
525        if (!isset($content_type)) {
526            $content_type = $this->mime_types['__default__'];
527            if ($req_ext && (isset($this->mime_types[$req_ext]))) {
528                $content_type = $this->mime_types[$req_ext];
529            }
530        }
531        $charset = $this->config('PublishCharset');
532        if (isset($charset)) {
533            if (!preg_match('/charset=/', $content_type))
534                $content_type .= '; charset=' . $charset;
535        }
536        header("Content-Type: $content_type");
537
538        // finally, issue output
539        echo $output;
540
541        if ($this->debugging) {
542            $this->log("Queries: ".$mtdb->num_queries);
543            $this->log("Queries executed:");
544            $queries = $mtdb->savedqueries;
545            foreach ($queries as $q) {
546                $this->log($q);
547            }
548            $this->log_dump();
549        }
550        restore_error_handler();
551    }
552
553    function &resolve_url($path) {
554        $data =& $this->db->resolve_url($path, $this->blog_id);
555        return $data;
556    }
557
558    function doConditionalGet($last_modified) {
559        // Thanks to Simon Willison...
560        //   http://simon.incutio.com/archive/2003/04/23/conditionalGet
561        // A PHP implementation of conditional get, see
562        //   http://fishbowl.pastiche.org/archives/001132.html
563        $etag = '"'.md5($last_modified).'"';
564        // Send the headers
565        header("Last-Modified: $last_modified");
566        header("ETag: $etag");
567        // See if the client has provided the required headers
568        $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
569            stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) :
570            false;
571        $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
572            stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) :
573            false;
574        if (!$if_modified_since && !$if_none_match) {
575            return;
576        }
577        // At least one of the headers is there - check them
578        if ($if_none_match && $if_none_match != $etag) {
579            return; // etag is there but doesn't match
580        }
581        if ($if_modified_since && $if_modified_since != $last_modified) {
582            return; // if-modified-since is there but doesn't match
583        }
584        // Nothing has changed since their last request - serve a 304 and exit
585        header('HTTP/1.1 304 Not Modified');
586        exit;
587    }
588
589    function display($tpl, $cid = null) {
590        $ctx =& $this->context();
591        $this->init_plugins();
592        $blog =& $ctx->stash('blog');
593        if (!$blog) {
594            $db =& $this->db();
595            $ctx->mt->db =& $db;
596            $blog =& $db->fetch_blog($this->blog_id);
597            $ctx->stash('blog', $blog);
598            $ctx->stash('blog_id', $this->blog_id);
599            $this->configure_paths($blog['blog_site_path']);
600        }
601        return $ctx->display($tpl, $cid);
602    }
603
604    function fetch($tpl, $cid = null) {
605        $ctx =& $this->context();
606        $this->init_plugins();
607        $blog =& $ctx->stash('blog');
608        if (!$blog) {
609            $db =& $this->db();
610            $ctx->mt->db =& $db;
611            $blog =& $db->fetch_blog($this->blog_id);
612            $ctx->stash('blog', $blog);
613            $ctx->stash('blog_id', $this->blog_id);
614            $this->configure_paths($blog['blog_site_path']);
615        }
616        return $ctx->fetch($tpl, $cid);
617    }
618
619    function log_dump() {
620        if ($_SERVER['REMOTE_ADDR']) {
621            // web view...
622            echo "<div class=\"debug\" style=\"border:1px solid red; margin:0.5em; padding: 0 1em; text-align:left; background-color:#ddd; color:#000\"><pre>";
623            echo implode("\n", $this->log);
624            echo "</pre></div>\n\n";
625        } else {
626            // console view...
627            $stderr = fopen('php://stderr', 'w');
628            fwrite($stderr,implode("\n", $this->log));
629            echo (implode("\n", $this->log));
630            fclose($stderr);
631        }
632    }
633
634    function error_handler($errno, $errstr, $errfile, $errline) {
635        if ($errno & (E_ALL ^ E_NOTICE)) {
636            $mtphpdir = $this->config('PHPDir');
637            $ctx =& $this->context();
638            $ctx->stash('blog_id', $this->blog_id);
639            $ctx->stash('blog', $this->db->fetch_blog($this->blog_id));
640            $ctx->stash('error_message', $errstr."<!-- file: $errfile; line: $errline; code: $errno -->");
641            $ctx->stash('error_code', $errno);
642            $http_error = $this->http_error;
643            if (!$http_error) {
644                $http_error = 500;
645            }
646            $ctx->stash('http_error', $http_error);
647            $ctx->stash('error_file', $errfile);
648            $ctx->stash('error_line', $errline);
649            $ctx->template_dir = $mtphpdir . DIRECTORY_SEPARATOR . 'tmpl';
650            $ctx->caching = 0;
651            $ctx->stash('StaticWebPath', $this->config('StaticWebPath'));
652            $ctx->stash('PublishCharset', $this->config('PublishCharset'));
653            $charset = $this->config('PublishCharset');
654            $out = $ctx->tag('Include', array('type' => 'dynamic_error'));
655            if (isset($out)) {
656                header("Content-type: text/html; charset=".$charset);
657                echo $out;
658            } else {
659                header("HTTP/1.1 500 Server Error");
660                header("Content-type: text/plain");
661                echo "Error executing error template.";
662            }
663            exit;
664        }
665    }
666
667    /***
668     * Retreives a context and rendering object.
669     */
670    function &context() {
671        static $ctx;
672        if (isset($ctx)) return $ctx;
673
674        require_once('MTViewer.php');
675        $ctx = new MTViewer($this);
676        $ctx->mt =& $this;
677        $mtphpdir = $this->config('PHPDir');
678        $mtlibdir = $this->config('PHPLibDir');
679        $ctx->compile_check = 1;
680        $ctx->caching = false;
681        $ctx->plugins_dir[] = $mtlibdir;
682        $ctx->plugins_dir[] = $mtphpdir . DIRECTORY_SEPARATOR . "plugins";
683        if ($this->debugging) {
684            $ctx->debugging_ctrl = 'URL';
685            $ctx->debug_tpl = $mtphpdir . DIRECTORY_SEPARATOR .
686                'extlib' . DIRECTORY_SEPARATOR .
687                'smarty' . DIRECTORY_SEPARATOR . "libs" . DIRECTORY_SEPARATOR .
688                'debug.tpl';
689        }
690        #if (isset($this->config('SafeMode')) && ($this->config('SafeMode'))) {
691        #    // disable PHP support
692        #    $ctx->php_handling = SMARTY_PHP_REMOVE;
693        #}
694        return $ctx;
695    }
696
697    function log($msg = null) {
698        $this->log[] = $msg;
699    }
700
701    function translate($str, $params = null) {
702        return translate_phrase($str, $params);
703    }
704
705    function translate_templatized_item($str) {
706        return translate_phrase($str[1]);
707    }
708
709    function translate_templatized($tmpl) {
710        $cb = array($this, 'translate_templatized_item');
711        $out = preg_replace_callback('/<(?:_|mt)_trans phrase="(.+?)".*?>/i', $cb, $tmpl);
712        return $out;
713    }
714}
715
716function is_valid_email($addr) {
717    if (preg_match('/[ |\t|\r|\n]*\"?([^\"]+\"?@[^ <>\t]+\.[^ <>\t][^ <>\t]+)[ |\t|\r|\n]*/', $addr, $matches)) {
718        return $matches[1];
719    } else {
720        return 0;
721    }
722}
723
724$spam_protect_map = array(':' => '&#58;', '@' => '&#64;', '.' => '&#46;');
725function spam_protect($str) {
726    global $spam_protect_map;
727    return strtr($str, $spam_protect_map);
728}
729
730function datetime_to_timestamp($dt) {
731    $dt = preg_replace('/[^0-9]/', '', $dt);
732    $ts = mktime(substr($dt, 8, 2), substr($dt, 10, 2), substr($dt, 12, 2), substr($dt, 4, 2), substr($dt, 6, 2), substr($dt, 0, 4));
733    return $ts;
734}
735
736function offset_time($ts, $blog = null, $dir = null) {
737    if (isset($blog)) {
738        if (!is_array($blog)) {
739            global $mt;
740            $blog = $mt->db->fetch_blog($blog);
741        }
742        $offset = $blog['blog_server_offset'];
743    } else {
744        global $mt;
745        $offset = $mt->config('TimeOffset');
746    }
747    intval($offset) or $offset = 0;
748    $tsa = localtime($ts);
749
750    if ($tsa[8]) {  // daylight savings offset
751        $offset++;
752    }
753    if ($dir == '-') {
754        $offset *= -1;
755    }
756    $ts += $offset * 3600;
757    return $ts;
758}
759function _strip_index($url, $blog) {
760    global $mt;
761    $index = $mt->config('IndexBasename');
762    $ext = $blog['blog_file_extension'];
763    if ($ext != '') $ext = '.' . $ext;
764    $index = preg_quote($index . $ext);
765    $url = preg_replace("/\/$index(#.*)?$/", '/$1', $url);
766    return $url;
767}
768
769function translate_phrase_param($str, $params = null) {
770    if (is_array($params) && strpos($str, '[_')) {
771        for ($i = 1; $i <= count($params); $i++) {
772            $str = preg_replace("/\\[_$i\\]/", $params[$i-1], $str);
773        }
774    }
775    return $str;
776}
777?>
Note: See TracBrowser for help on using the browser.