root/branches/release-41/php/mt.php.pre @ 2688

Revision 2688, 31.9 kB (checked in by bchoate, 17 months ago)

Ignore invalid PluginPath locations.

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