PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/addons/DynamicMTML.pack/php/mt.php

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