PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/manage/expressionengine/core/EE_Output.php

https://bitbucket.org/myockey/clearcreek-chapel-website
PHP | 500 lines | 259 code | 94 blank | 147 comment | 58 complexity | d5b9223a32c64ce5d45ba78534a3d908 MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author EllisLab Dev Team
  7. * @copyright Copyright (c) 2003 - 2012, EllisLab, Inc.
  8. * @license http://ellislab.com/expressionengine/user-guide/license.html
  9. * @link http://ellislab.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine Output Display Class
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Core
  19. * @category Core
  20. * @author EllisLab Dev Team
  21. * @link http://ellislab.com
  22. */
  23. class EE_Output extends CI_Output {
  24. var $out_type = 'webpage';
  25. var $refresh_msg = TRUE; // TRUE/FALSE - whether to show the "You will be redirected in 5 seconds" message.
  26. var $refresh_time = 1; // Number of seconds for redirects
  27. var $remove_unparsed_variables = FALSE; // whether to remove left-over variables that had bad syntax
  28. // --------------------------------------------------------------------
  29. /**
  30. * Set Header
  31. *
  32. * Lets you set a server header which will be outputted with the final display.
  33. *
  34. * @access public
  35. * @param string
  36. * @return void
  37. */
  38. function set_header($header, $replace = TRUE)
  39. {
  40. $EE =& get_instance();
  41. // We always need to send a content type
  42. if ($EE->config->item('send_headers') != 'y' && strncasecmp($header, 'content-type', 12) != 0)
  43. {
  44. return;
  45. }
  46. parent::set_header($header, $replace);
  47. }
  48. // --------------------------------------------------------------------
  49. /**
  50. * Display the final output
  51. *
  52. * @access public
  53. * @return void
  54. */
  55. function _display($output = '')
  56. {
  57. $EE =& get_instance();
  58. if ($output == '')
  59. {
  60. $output = $this->final_output;
  61. }
  62. // Generate No-Cache Headers
  63. if ($EE->config->item('send_headers') == 'y' && $this->out_type != 'feed' && $this->out_type != '404' && $this->out_type != 'cp_asset')
  64. {
  65. $this->set_status_header(200);
  66. $this->set_header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  67. $this->set_header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
  68. $this->set_header("Pragma: no-cache");
  69. }
  70. // Content Type Headers
  71. // Also need to do some extra work for feeds
  72. switch ($this->out_type)
  73. {
  74. case 'webpage': $this->set_header("Content-Type: text/html; charset=".$EE->config->item('charset'));
  75. break;
  76. case 'css': $this->set_header("Content-type: text/css");
  77. break;
  78. case 'js': $this->set_header("Content-type: text/javascript");
  79. $this->enable_profiler = FALSE;
  80. break;
  81. case '404': $this->set_status_header(404);
  82. $this->set_header("Date: ".gmdate("D, d M Y H:i:s")." GMT");
  83. break;
  84. case 'xml': $this->set_header("Content-Type: text/xml");
  85. $output = trim($output);
  86. break;
  87. case 'feed': $this->_send_feed($output);
  88. break;
  89. default: // Likely a custom template type
  90. // -------------------------------------------
  91. // 'template_types' hook.
  92. // - Provide information for custom template types.
  93. //
  94. $template_types = $EE->extensions->call('template_types', array());
  95. //
  96. // -------------------------------------------
  97. if (isset($template_types[$this->out_type]))
  98. {
  99. // Set custom headers as defined by the template_headers key,
  100. // and replace any headers as necessary
  101. if (isset($template_types[$this->out_type]['template_headers']))
  102. {
  103. foreach ($template_types[$this->out_type]['template_headers'] as $header)
  104. {
  105. $this->set_header($header, TRUE);
  106. }
  107. }
  108. }
  109. break;
  110. }
  111. // Compress the output
  112. // We simply set the ci config value to true
  113. if ($EE->config->item('gzip_output') == 'y' AND REQ == 'PAGE')
  114. {
  115. $EE->config->set_item('compress_output', TRUE);
  116. }
  117. // Parse query count
  118. if (REQ != 'CP')
  119. {
  120. $output = str_replace(LD.'total_queries'.RD, $EE->db->query_count, $output);
  121. }
  122. // Send it to the CI method for final processing
  123. parent::_display($output);
  124. }
  125. // --------------------------------------------------------------------
  126. /**
  127. * Do extra processing for feeds
  128. *
  129. * @access private
  130. * @param string
  131. * @return void
  132. */
  133. function _send_feed(&$output)
  134. {
  135. $EE =& get_instance();
  136. $request = ( ! function_exists('getallheaders')) ? array() : @getallheaders();
  137. if (preg_match("|<ee\:last_update>(.*?)<\/ee\:last_update>|", $output, $matches))
  138. {
  139. $last_update = $matches['1'];
  140. $output = str_replace($matches['0'], '', $output);
  141. }
  142. else
  143. {
  144. $last_update = $EE->localize->now;
  145. }
  146. $output = trim($output);
  147. // Check for the 'If-Modified-Since' Header
  148. if ($EE->config->item('send_headers') == 'y' && isset($request['If-Modified-Since']) && trim($request['If-Modified-Since']) != '')
  149. {
  150. $x = explode(';', $request['If-Modified-Since']);
  151. $modify_tstamp = strtotime($x['0']);
  152. // If no new content, send no data
  153. if ($last_update <= $modify_tstamp)
  154. {
  155. $this->set_status_header(304);
  156. exit;
  157. }
  158. }
  159. $this->set_status_header(200);
  160. $this->set_header("Content-Type: text/xml; charset=".$EE->config->item('output_charset'));
  161. $this->set_header('Expires: '.gmdate('D, d M Y H:i:s', $last_update+(60*60)).' GMT'); // One hour
  162. $this->set_header('Last-Modified: '.gmdate('D, d M Y H:i:s', $last_update).' GMT');
  163. $this->set_header("Cache-Control: no-store, no-cache, must-revalidate");
  164. $this->set_header("Cache-Control: post-check=0, pre-check=0", false);
  165. $this->set_header("Pragma: no-cache");
  166. // Swap XML declaration for RSS files
  167. $output = preg_replace("/{\?xml(.+?)\?}/", "<?xml\\1?".">", $output);
  168. }
  169. // --------------------------------------------------------------------
  170. /**
  171. * Display fatal error message
  172. *
  173. * @access public
  174. * @return void
  175. */
  176. function fatal_error($error_msg = '', $use_lang = TRUE)
  177. {
  178. $EE =& get_instance();
  179. $heading = ($use_lang == TRUE && is_object($EE->lang)) ? $EE->lang->line('error') : 'Error Message';
  180. $data = array( 'title' => $heading,
  181. 'heading' => $heading,
  182. 'content' => '<p>'.$error_msg.'</p>'
  183. );
  184. $this->show_message($data);
  185. }
  186. // --------------------------------------------------------------------
  187. /**
  188. * System is off message
  189. *
  190. * @access public
  191. * @return void
  192. */
  193. function system_off_msg()
  194. {
  195. $EE =& get_instance();
  196. $query = $EE->db->query("SELECT template_data FROM exp_specialty_templates WHERE site_id = '".$EE->db->escape_str($EE->config->item('site_id'))."' AND template_name = 'offline_template'");
  197. $this->set_status_header(503, 'Service Temporarily Unavailable');
  198. @header('Retry-After: 3600');
  199. echo $query->row('template_data') ;
  200. exit;
  201. }
  202. // --------------------------------------------------------------------
  203. /**
  204. * Show message
  205. *
  206. * This function and the next enable us to show error messages to
  207. * users when needed. For example, when a form is submitted without
  208. * the required info.
  209. *
  210. * This is not used in the control panel, only with publicly
  211. * accessible pages.
  212. *
  213. * @access public
  214. * @param mixed
  215. * @param bool
  216. * @return void
  217. */
  218. function show_message($data, $xhtml = TRUE)
  219. {
  220. $EE =& get_instance();
  221. @header("Cache-Control: no-cache, must-revalidate");
  222. @header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
  223. @header("Pragma: no-cache");
  224. foreach (array('title', 'heading', 'content', 'redirect', 'rate', 'link') as $val)
  225. {
  226. if ( ! isset($data[$val]))
  227. {
  228. $data[$val] = '';
  229. }
  230. }
  231. if ( ! is_numeric($data['rate']) OR $data['rate'] == '')
  232. {
  233. $data['rate'] = $this->refresh_time;
  234. }
  235. $data['meta_refresh'] = ($data['redirect'] != '') ? "<meta http-equiv='refresh' content='".$data['rate']."; url=".$EE->security->xss_clean($data['redirect'])."'>" : '';
  236. $data['charset'] = $EE->config->item('output_charset');
  237. if (is_array($data['link']) AND count($data['link']) > 0)
  238. {
  239. $refresh_msg = ($data['redirect'] != '' AND $this->refresh_msg == TRUE) ? $EE->lang->line('click_if_no_redirect') : '';
  240. $ltitle = ($refresh_msg == '') ? $data['link']['1'] : $refresh_msg;
  241. $url = (strtolower($data['link']['0']) == 'javascript:history.go(-1)') ? $data['link']['0'] : $EE->security->xss_clean($data['link']['0']);
  242. $data['link'] = "<a href='".$url."'>".$ltitle."</a>";
  243. }
  244. if ($xhtml == TRUE && isset($EE->session))
  245. {
  246. $EE->load->library('typography');
  247. $data['content'] = $EE->typography->parse_type(stripslashes($data['content']), array('text_format' => 'xhtml'));
  248. }
  249. $EE->db->select('template_data');
  250. $EE->db->where('site_id', $EE->config->item('site_id'));
  251. $EE->db->where('template_name', 'message_template');
  252. $query = $EE->db->get('specialty_templates');
  253. $row = $query->row_array();
  254. foreach ($data as $key => $val)
  255. {
  256. $row['template_data'] = str_replace('{'.$key.'}', $val, $row['template_data'] );
  257. }
  258. echo stripslashes($row['template_data'] );
  259. exit;
  260. }
  261. // --------------------------------------------------------------------
  262. /**
  263. * Show user error
  264. *
  265. * @access public
  266. * @param string
  267. * @param mixed
  268. * @param string
  269. * @return void
  270. */
  271. function show_user_error($type = 'submission', $errors, $heading = '')
  272. {
  273. $EE =& get_instance();
  274. $this->set_header("Content-Type: text/html; charset=".$EE->config->item('charset'));
  275. if ($type != 'off')
  276. {
  277. switch($type)
  278. {
  279. case 'submission' : $heading = $EE->lang->line('submission_error');
  280. break;
  281. case 'general' : $heading = $EE->lang->line('general_error');
  282. break;
  283. default : $heading = $EE->lang->line('submission_error');
  284. break;
  285. }
  286. }
  287. $content = '<ul>';
  288. if ( ! is_array($errors))
  289. {
  290. $content.= "<li>".$errors."</li>\n";
  291. }
  292. else
  293. {
  294. foreach ($errors as $val)
  295. {
  296. $content.= "<li>".$val."</li>\n";
  297. }
  298. }
  299. $content .= "</ul>";
  300. $data = array( 'title' => $EE->lang->line('error'),
  301. 'heading' => $heading,
  302. 'content' => $content,
  303. 'redirect' => '',
  304. 'link' => array('JavaScript:history.go(-1)', $EE->lang->line('return_to_previous'))
  305. );
  306. $this->show_message($data, 0);
  307. }
  308. // --------------------------------------------------------------------
  309. /**
  310. * Send AJAX response
  311. *
  312. * Outputs and exits content, makes sure profiler is disabled
  313. * and sends 500 status header on error
  314. *
  315. * @access public
  316. * @param string
  317. * @param bool whether or not the response is an error
  318. * @return void
  319. */
  320. function send_ajax_response($msg, $error = FALSE)
  321. {
  322. $this->enable_profiler(FALSE);
  323. if ($error === TRUE)
  324. {
  325. $this->set_status_header(500);
  326. }
  327. $EE =& get_instance();
  328. if ($EE->config->item('send_headers') == 'y')
  329. {
  330. if (is_array($msg))
  331. {
  332. @header('Content-Type: application/json');
  333. }
  334. else
  335. {
  336. @header('Content-Type: text/html; charset=UTF-8');
  337. }
  338. }
  339. $EE->load->library('javascript');
  340. exit($EE->javascript->generate_json($msg, TRUE));
  341. }
  342. // --------------------------------------------------------------------
  343. /**
  344. * Send Cache Headers
  345. *
  346. * Used to control client caching for JS, CSS
  347. *
  348. * @access public
  349. * @param int Unix Timestamp, date of "file" modification
  350. * @param int max-age value
  351. * @param string path identifier for ETag, helpful in load balanced environs
  352. * @return void
  353. */
  354. function send_cache_headers($modified, $max_age = 172800, $etag_path = NULL)
  355. {
  356. $EE =& get_instance();
  357. if ($EE->config->item('send_headers') == 'y')
  358. {
  359. $max_age = (int) $max_age;
  360. $modified = (int) $modified;
  361. $modified_since = $EE->input->server('HTTP_IF_MODIFIED_SINCE');
  362. // Remove anything after the semicolon
  363. if ($pos = strrpos($modified_since, ';') !== FALSE)
  364. {
  365. $modified_since = substr($modified_since, 0, $pos);
  366. }
  367. // If the file is in the client cache, we'll
  368. // send a 304 and be done with it.
  369. if ($modified_since && (strtotime($modified_since) == $modified))
  370. {
  371. $this->set_status_header(304);
  372. exit;
  373. }
  374. // All times GMT
  375. $modified = gmdate('D, d M Y H:i:s', $modified).' GMT';
  376. $expires = gmdate('D, d M Y H:i:s', time() + $max_age).' GMT';
  377. $this->set_status_header(200);
  378. $this->set_header("Cache-Control: max-age={$max_age}, must-revalidate");
  379. $this->set_header('Vary: Accept-Encoding');
  380. $this->set_header('Last-Modified: '.$modified);
  381. $this->set_header('Expires: '.$expires);
  382. // Send a custom ETag to maintain a useful cache in
  383. // load-balanced environments
  384. if ( ! is_null($etag_path))
  385. {
  386. $this->set_header("ETag: ".md5($modified.$etag_path));
  387. }
  388. }
  389. }
  390. // --------------------------------------------------------------------
  391. /**
  392. * Setter for the remove_unparsed_variables class var
  393. *
  394. * used in the ee.php controller.
  395. *
  396. * @param boolean
  397. */
  398. public function remove_unparsed_variables($remove_unparsed_vars)
  399. {
  400. $this->remove_unparsed_variables = $remove_unparsed_vars;
  401. }
  402. // --------------------------------------------------------------------
  403. }
  404. // END CLASS
  405. /* End of file EE_Output.php */
  406. /* Location: ./system/expressionengine/libraries/EE_Output.php */