From d043477bc317e9c092da60f3c17310f60b2e4850 Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 26 Jul 2011 11:58:23 -0400 Subject: [PATCH] Added Output class, fixed some formatting issues --- README.md | 2 + application/core/MY_Output.php | 222 +++++++++++++ application/libraries/Page.php | 562 ++++++++++++++++----------------- 3 files changed, 502 insertions(+), 284 deletions(-) create mode 100644 application/core/MY_Output.php diff --git a/README.md b/README.md index e69de29..2b4ad42 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,2 @@ +Codeigniter Page Builder is a simple system for putting together content into web pages, using Codeigniter's views, and making it simpler to set expiration headers for javascript and CSS. + diff --git a/application/core/MY_Output.php b/application/core/MY_Output.php new file mode 100644 index 0000000..c9c3e29 --- /dev/null +++ b/application/core/MY_Output.php @@ -0,0 +1,222 @@ +final_output + * + * This function sends the finalized output data to the browser along + * with any server headers and profile data. It also stops the + * benchmark timer so the page rendering speed and memory usage can be shown. + * + * @access public + * @return mixed + */ + function _display($output = '') + { + // Note: We use globals because we can't use $CI =& get_instance() + // since this function is sometimes called by the caching mechanism, + // which happens before the CI super object is available. + global $BM, $CFG; + //$this->min = 0; + + // -------------------------------------------------------------------- + + // Set the output data + if ($output == '') + { + $output =& $this->final_output; + } + + // -------------------------------------------------------------------- + + // Do we need to write a cache file? + if ($this->cache_expiration > 0) + { + $this->_write_cache($output); + } + + // -------------------------------------------------------------------- + + // Parse out the elapsed time and memory usage, + // then swap the pseudo-variables with the data + + $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end'); + $output = str_replace('{elapsed_time}', $elapsed, $output); + + $memory = (!function_exists('memory_get_usage')) ? '0' : round(memory_get_usage() / 1024 / 1024, 2) . 'MB'; + $output = str_replace('{memory_usage}', $memory, $output); + + // -------------------------------------------------------------------- + + // Is compression requested? + if ($CFG->item('compress_output') === TRUE) + { + if (extension_loaded('zlib')) + { + if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) + { + ob_start('ob_gzhandler'); + } + } + } + + // -------------------------------------------------------------------- + + // Are there any server headers to send? + if (count($this->headers) > 0) + { + foreach ($this->headers as $header) + { + header($header[0], $header[1]); + } + } + + // -------------------------------------------------------------------- + + // Does the get_instance() function exist? + // If not we know we are dealing with a cache file so we'll + // simply echo out the data and exit. + if (!function_exists('get_instance')) + { + echo $output; + log_message('debug', "Final output sent to browser"); + log_message('debug', "Total execution time: " . $elapsed); + return TRUE; + } + + // -------------------------------------------------------------------- + + // Grab the super object. We'll need it in a moment… + $CI =& get_instance(); + + // Do we need to generate profile data? + // If so, load the Profile class and run it. + if ($this->enable_profiler == TRUE) + { + $CI->load->library('profiler'); + + // If the output data contains closing and tags + // we will remove them and add them back after we insert the profile data + if (preg_match("|.*?|is", $output)) + { + $output = preg_replace("|.*?|is", '', $output); + $output .= $CI->profiler->run(); + $output .= ''; + } + else + { + $output .= $CI->profiler->run(); + } + } + + //Let's minify! + switch ((int) $this->min) + { + case 0: + //Don't minify + break; + + case 1: //Safe Minify + $output = preg_replace("`>\s+<`", "> <", $output); + break; + + case 2: //Extreme Minify + $output = preg_replace('//Uis', '', $output); + $output = preg_replace("`\s+`", " ", $output); + $output = preg_replace("`> <`", "><", $output); + $output = str_replace(" )`", " ", $output); + break; + + case 4: //Extreme minify, save comments + $output = preg_replace("`\s+`", " ", $output); + $output = preg_replace("`> <`", "><", $output); + $output = str_replace(" )`", " ", $output); + break; + + default: + //Don't minify + break; + } + + //Replace common entities with more compatible versions + $replace = array( + '"&"' => '"&"', + '{NL}' => " ", + ' ' => ' ', + '©' => '©', + 'â' => 'â', + '¢' => '¢', + '»' => '»', + '«' => '«' + ); + + $output = strtr($output, $replace); + + // -------------------------------------------------------------------- + + // Does the controller contain a function named _output()? + // If so send the output there. Otherwise, echo it. + if (method_exists($CI, '_output')) + { + $CI->_output($output); + } + else + { + echo $output; // Send it to the browser! + } + + log_message('debug', "Final output sent to browser"); + log_message('debug', "Total execution time: " . $elapsed); + } + + /** + * Enable/disable Minified HTML + * + * @access public + * @param int + * @return void + */ + function enable_min($val = 0) + { + $this->min = $val; + } + +} +// END Output Class + +/* End of file Output.php */ +/* Location: ./system/libraries/Output.php */ \ No newline at end of file diff --git a/application/libraries/Page.php b/application/libraries/Page.php index ff00b30..7c3818f 100644 --- a/application/libraries/Page.php +++ b/application/libraries/Page.php @@ -1,83 +1,83 @@ -meta = ""; - $this->head_js = ""; - $this->foot_js = ""; - $this->css = ""; - $this->title = ""; - $this->head_tags = ""; + $this->meta = ""; + $this->head_js = ""; + $this->foot_js = ""; + $this->css = ""; + $this->title = ""; + $this->head_tags = ""; $this->body_class = ""; - $this->body_id = ""; - $this->base = ""; + $this->body_id = ""; + $this->base = ""; $this->CI =& get_instance(); - + //Define some constants for formatting define('NL', "\n"); define('T1', "\t"); - define('T2', T1.T1); - define('T3', T2.T1); - define('T4', T2.T2); - define('T5', T3.T2); - define('T6', T3.T3); + define('T2', T1 . T1); + define('T3', T2 . T1); + define('T4', T2 . T2); + define('T5', T3 . T2); + define('T6', T3 . T3); } // -------------------------------------------------------------------------- - - /** - * Sets server headers and doctype + + /** + * Sets server headers and doctype * * Also sets page mime type, based on if sent as * html or xhtml, and what the target browser * supports * - * @param bool $xhtml - * @param bool $html5 + * @param bool $xhtml + * @param bool $html5 * @return Page - */ - private function _headers($xhtml, $html5) - { - $this->CI->output->set_header("Cache-Control: must-revalidate, public"); - + */ + private function _headers($xhtml, $html5) + { + $this->CI->output->set_header("Cache-Control: must-revalidate, public"); + $this->CI->output->set_header("Vary: Accept"); - $mime = ""; - + $mime = ""; + //Variable for accept keyword $accept = (!empty($_SERVER['HTTP_ACCEPT'])) ? $_SERVER['HTTP_ACCEPT'] : ""; //Predefine doctype $doctype_string = ($html5 == TRUE) ? doctype('html5') : doctype('xhtml11'); - + //Predefine charset $charset = "UTF-8"; - - //If xhtml flag is false, set html4 header - if($xhtml == TRUE) + + //If xhtml flag is false, set html4 header + if ($xhtml == TRUE) { //Check that the user agent accepts application/xhtml+xml, or if it's the W3C Validator - if(stristr($accept,"application/xhtml+xml") || stristr($_SERVER["HTTP_USER_AGENT"],"W3C_Validator")) + if (stristr($accept, "application/xhtml+xml") || stristr($_SERVER["HTTP_USER_AGENT"], "W3C_Validator")) { $mime = "application/xhtml+xml"; } //Or if it supports application/xml - else if(stristr($accept,"application/xml")) + else if (stristr($accept, "application/xml")) { $mime = "application/xml"; } //Or if it supports text/xml - else if(stristr($accept,"text/xml")) + else if (stristr($accept, "text/xml")) { $mime = "text/xml"; } @@ -85,7 +85,7 @@ class Page { { $mime = "text/html"; - if($html5 == FALSE) //If it's not HTML5, it's HTML4 + if ($html5 == FALSE) //If it's not HTML5, it's HTML4 { $doctype_string = doctype('html4-strict'); } @@ -94,41 +94,41 @@ class Page { else { $mime = "text/html"; - - if($html5 == FALSE) + + if ($html5 == FALSE) { $doctype_string = doctype('html4-strict'); } } - + // set the doctype according to the mime type which was determined - if($mime == "application/xhtml+xml" || $mime == "text/xml" || $mime == "application/xml") + if ($mime == "application/xhtml+xml" || $mime == "text/xml" || $mime == "application/xml") { - if($html5 == TRUE) + if ($html5 == TRUE) { $doctype_string = ''; } - - $doctype_string = "\n" . - $doctype_string . "\n"; + + $doctype_string = "\n" + . $doctype_string + . "\n"; } else { $doctype_string .= "\n"; } - - // finally, output the mime type and prolog type - $this->CI->output->set_header("Content-Type: $mime;charset=$charset"); - $this->CI->output->set_header("X-UA-Compatible: chrome=1, IE=edge"); - $this->CI->output->set_output($doctype_string); - - return $this; - } - - // -------------------------------------------------------------------------- - - /** + + // finally, output the mime type and prolog type + $this->CI->output->set_header("Content-Type: $mime;charset=$charset"); + $this->CI->output->set_header("X-UA-Compatible: chrome=1, IE=edge"); + $this->CI->output->set_output($doctype_string); + + return $this; + } + + // -------------------------------------------------------------------------- + + /** * Set Meta * * Sets meta tags, with codeigniter native meta tag helper @@ -136,200 +136,199 @@ class Page { * @param array $meta * @return Page */ - public function set_meta($meta) - { - $this->meta .= T1.meta($meta).NL; + public function set_meta($meta) + { + $this->meta .= T1 . meta($meta) . NL; return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets minified javascript group in header - * @param string $group - * @param bool $debug + } + + // -------------------------------------------------------------------------- + + /** + * Sets minified javascript group in header + * @param string $group + * @param bool $debug * @return Page - */ - public function set_head_js_group($group, $debug=FALSE) - { - if($group === FALSE) - { - return $this; - } - + */ + public function set_head_js_group($group, $debug = FALSE) + { + if ($group === FALSE) + { + return $this; + } + $file = $this->CI->config->item('group_js_path') . $group; $file .= ($debug == TRUE) ? "/debug/1" : ""; $this->head_js .= $this->script_tag($file, FALSE); return $this; - } - - // -------------------------------------------------------------------------- - - /** + } + + // -------------------------------------------------------------------------- + + /** * Set an individual js file in header * @param string $js * @param bool $domain * @return Page */ - public function set_head_js($js, $domain=TRUE) - { + public function set_head_js($js, $domain = TRUE) + { $this->head_js .= $this->script_tag($js, $domain); return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets a minified css group - * @param string $group - * @return Page - */ - public function set_css_group($group) - { - $link = array( - 'href' => $this->CI->config->item('group_style_path') . $group, - 'rel' => 'stylesheet', - 'type' => 'text/css', - ); - $this->css .= T1.link_tag($link).NL; - - return $this; - } - + } + // -------------------------------------------------------------------------- - - /** - * Sets a minified javascript group for the page footer - * @param string $group + + /** + * Sets a minified css group + * @param string $group * @return Page - */ - public function set_foot_js_group($group, $debug=FALSE) - { + */ + public function set_css_group($group) + { + $link = array( + 'href' => $this->CI->config->item('group_style_path') . $group, + 'rel' => 'stylesheet', + 'type' => 'text/css' + ); + $this->css .= T1 . link_tag($link) . NL; + + return $this; + } + + // -------------------------------------------------------------------------- + + /** + * Sets a minified javascript group for the page footer + * @param string $group + * @return Page + */ + public function set_foot_js_group($group, $debug = FALSE) + { $file = $this->CI->config->item('group_js_path') . $group; $file .= ($debug == TRUE) ? "?debug=1" : ""; $this->foot_js .= $this->script_tag($file, FALSE); return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets js in footer; multiple files are combined and minified. - * @param array $args + } + + // -------------------------------------------------------------------------- + + /** + * Sets js in footer; multiple files are combined and minified. + * @param array $args * @return Page - */ - public function set_foot_js($js, $domain) - { - $this->foot_js .= $this->script_tag($js, $domain); - return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets html title string - * @param string $title - * @return Page - */ - public function set_title($title="") - { - $title = ($title == "") ? - $this->CI->config->item('default_title') : $title; - - $this->title = $title; - - return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets custom body class - * @param string $class - * @return Page - */ - public function set_body_class($class="") - { - $this->body_class = $class; - return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets custom body id - * @param string $id - * @return Page - */ - public function set_body_id($id="") - { - $this->body_id = $id; - return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets custom base href - * @param string href - * @return Page - */ - public function set_base($href) - { - $this->base = $href; - return $this; - } - - // -------------------------------------------------------------------------- - - /** - * Sets custom css tags - * @param string $name - * @param string $media - * @return Page - */ - public function set_css_tag($name, $domain=TRUE, $media="all") - { - $path = $this->CI->config->item('content_domain'); - $css_file = $path . "/css/" . $name . ".css"; - - if ($domain == FALSE) - $css_file = $name; - - $this->css_tags .= T1.link_tag($name, "stylesheet", "text/css", "", $media).NL; - + */ + public function set_foot_js($js, $domain) + { + $this->foot_js .= $this->script_tag($js, $domain); return $this; } - - // -------------------------------------------------------------------------- - + + // -------------------------------------------------------------------------- + + /** + * Sets html title string + * @param string $title + * @return Page + */ + public function set_title($title = "") + { + $title = ($title == "") ? $this->CI->config->item('default_title') : $title; + + $this->title = $title; + + return $this; + } + + // -------------------------------------------------------------------------- + + /** + * Sets custom body class + * @param string $class + * @return Page + */ + public function set_body_class($class = "") + { + $this->body_class = $class; + return $this; + } + + // -------------------------------------------------------------------------- + + /** + * Sets custom body id + * @param string $id + * @return Page + */ + public function set_body_id($id = "") + { + $this->body_id = $id; + return $this; + } + + // -------------------------------------------------------------------------- + + /** + * Sets custom base href + * @param string href + * @return Page + */ + public function set_base($href) + { + $this->base = $href; + return $this; + } + + // -------------------------------------------------------------------------- + + /** + * Sets custom css tags + * @param string $name + * @param string $media + * @return Page + */ + public function set_css_tag($name, $domain = TRUE, $media = "all") + { + $path = $this->CI->config->item('content_domain'); + $css_file = $path . "/css/" . $name . ".css"; + + if ($domain == FALSE) + $css_file = $name; + + $this->css_tags .= T1 . link_tag($name, "stylesheet", "text/css", "", $media) . NL; + + return $this; + } + + // -------------------------------------------------------------------------- + /** * Sets uncompressed js file in footer * @param string $name * @param bool $domain * @return Page */ - public function set_foot_js_tag($name, $domain=TRUE) + public function set_foot_js_tag($name, $domain = TRUE) { - $this->foot_js .= $this->script_tag($name, $domain); + $this->foot_js .= $this->script_tag($name, $domain); return $this; } // -------------------------------------------------------------------------- - + /** * Sets a custom tag in the header * @param string $tag * @return Page */ - public function set_head_tag($tag) - { - $this->head_tags .= $tag . "\n"; + public function set_head_tag($tag) + { + $this->head_tags .= $tag . "\n"; return $this; - } - - // -------------------------------------------------------------------------- - + } + + // -------------------------------------------------------------------------- + /** * Sets custom page header * @param mixed $xhtml @@ -337,16 +336,14 @@ class Page { * @param bool $fbml * @return $this */ - public function build_header($xhtml = FALSE, $html5 = TRUE) - { - $data = array(); - - //Set Meta Tags - $this->meta = ($html5 == TRUE) ? - T1.''.NL. $this->meta : - T1.meta('content-type', 'text/html; charset=utf-8', 'equiv').NL.$this->meta; + public function build_header($xhtml = FALSE, $html5 = TRUE) + { + $data = array(); + + //Set Meta Tags + $this->meta = ($html5 == TRUE) ? T1 . '' . NL . $this->meta : T1 . meta('content-type', 'text/html; charset=utf-8', 'equiv') . NL . $this->meta; $data['meta'] = $this->meta; - + //Set CSS if ($this->css != "") { @@ -358,59 +355,58 @@ class Page { $this->set_css_group($this->CI->config->item('default_css_group')); $data['css'] = $this->css; } - + //Set head javascript - if($this->head_js != "") + if ($this->head_js != "") { - $data['head_js'] = $this->head_js; - } + $data['head_js'] = $this->head_js; + } else { $this->set_head_js_group($this->CI->config->item('default_head_js_group')); $data['head_js'] = $this->head_js; - } - - //Set Page Title + } + + //Set Page Title $data['title'] = ($this->title != '') ? $this->title : $this->CI->config->item('default_title'); - + //Set Body Class - $data['body_class'] = $this->body_class; - - //Set Body Id + $data['body_class'] = $this->body_class; + + //Set Body Id $data['body_id'] = $this->body_id; - - //Set Base HREF + + //Set Base HREF $data['base'] = $this->base; - - //Set individual head tags + + //Set individual head tags $data['head_tags'] = $this->head_tags; - - //Set Server Headers and Doctype + + //Set Server Headers and Doctype $this->_headers($xhtml, $html5); - + //Output Header - $this->CI->load->view('header', $data); - - flush(); - - return $this; - } - - // -------------------------------------------------------------------------- - - - /** - * Builds common footer with any additional js - */ - public function build_footer() - { - $data = array(); - - $data['foot_js'] = ($this->foot_js != "") ? - $this->foot_js : ''; - - $this->CI->load->view('footer', $data); - } + $this->CI->load->view('header', $data); + + flush(); + + return $this; + } + + // -------------------------------------------------------------------------- + + + /** + * Builds common footer with any additional js + */ + public function build_footer() + { + $data = array(); + + $data['foot_js'] = ($this->foot_js != "") ? $this->foot_js : ''; + + $this->CI->load->view('footer', $data); + } // -------------------------------------------------------------------------- @@ -423,23 +419,21 @@ class Page { * @param bool $domain * @return string */ - private function script_tag($js, $domain=TRUE) + private function script_tag($js, $domain = TRUE) { - $path = $this->CI->config->item('content_domain'); - $js_file = $path . "/js/" . $js . ".js"; - + $path = $this->CI->config->item('content_domain'); + $js_file = $path . "/js/" . $js . ".js"; + if ($domain == FALSE) $js_file = $js; - - $tag = T1.''.NL; - + + $tag = T1 . '' . NL; + return $tag; } - + // -------------------------------------------------------------------------- - + /** * Quick Build * @@ -449,7 +443,7 @@ class Page { * @param bool $xhtml * @param bool $html5 */ - public function quick_build($view, $data, $xhtml=TRUE, $html5=TRUE) + public function quick_build($view, $data, $xhtml = TRUE, $html5 = TRUE) { //Set up header if ($title != '') @@ -460,9 +454,9 @@ class Page { { $this->set_title($this->CI->config->item('default_title')); } - + $this->build_header($xhtml, $html5); - + //Load view(s) if (is_array($view)) { @@ -475,12 +469,12 @@ class Page { { $this->CI->load->view($view, $data); } - + //Create footer $this->build_footer(); } - - + + // -------------------------------------------------------------------------- /** @@ -492,7 +486,7 @@ class Page { */ public function num_queries() { - return (isset($this->CI->db)) ? count($this->CI->db->queries) : 0; + return (isset($this->CI->db)) ? count($this->CI->db->queries) : 0; } // -------------------------------------------------------------------------- @@ -508,7 +502,7 @@ class Page { public function set_message($type, $message) { $data['stat_class'] = $type; - $data['message'] = $message; + $data['message'] = $message; $this->CI->load->view('message', $data); }