miniMVC/sys/core/Page.php

715 lines
13 KiB
PHP

<?php
/**
* MiniMVC
*
* Convention-based micro-framework for PHP
*
* @package miniMVC
* @author Timothy J. Warren
* @copyright Copyright (c) 2011 - 2012
* @link https://github.com/aviat4ion/miniMVC
* @license http://philsturgeon.co.uk/code/dbad-license
*/
// --------------------------------------------------------------------------
namespace miniMVC;
/**
* Class for building pages
*
* All methods are chainable, with the exception of the constructor,
* build_header(), build_footer(), and _headers() methods.
*
* @package miniMVC
* @subpackage System
*/
class Page {
/**
* Meta tags
*
* @var string
*/
private $meta;
/**
* JS tags for the header
*
* @var string
*/
private $head_js;
/**
* JS tags for the footer
*
* @var string
*/
private $foot_js;
/**
* CSS tags for the page
*
* @var string
*/
private $css;
/**
* Page title
*
* @var string
*/
private $title;
/**
* Additional header tags
*
* @var string
*/
private $head_tags;
/**
* Class(es) to apply to the main body tag
*
* @var string
*/
private $body_class;
/**
* Id to apply to the body tag
*
* @var string
*/
private $body_id;
/**
* Base tag
*
* @var string
*/
private $base;
/**
* Content for outputting
*
* @var string
*/
private $buffer;
/**
* HTTP headers to send
*
* @var array
*/
private $headers;
/**
* Set up the page class
*
* @return void
*/
public function __construct()
{
$this->meta = "";
$this->head_js = "";
$this->foot_js = "";
$this->css = "";
$this->title = "";
$this->head_tags = "";
$this->body_class = "";
$this->body_id = "";
$this->base = "";
$this->buffer = "";
$this->headers = array();
}
// --------------------------------------------------------------------------
/**
* PHP magic method called when ending the script
* Used for outputing HTML
*
* @return void
*/
public function __destruct()
{
if ( ! empty($this->headers))
{
// Set headers
foreach($this->headers as $key => $val)
{
if ( ! isset($val))
{
@header($key);
}
else
{
@header("$key: $val");
}
}
}
if ( ! empty($this->buffer))
{
// @todo Figure out how to adjust content compression for 5.4.4
ob_start();
echo $this->buffer;
// Check if a buffer exists
// so that it doesn't throw a notice
if (ob_get_level() > 0)
{
ob_end_flush();
}
}
else
{
echo 'No content';
}
}
// --------------------------------------------------------------------------
/**
* 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 $html5
* @return Page
*/
private function _headers($html5)
{
$this->set_header("Cache-Control", "must-revalidate, public");
$mime = "";
//Variable for accept keyword
$accept = ( ! empty($_SERVER['HTTP_ACCEPT'])) ? $_SERVER['HTTP_ACCEPT'] : "";
//Predefine doctype
$doctype_string = ($html5 == TRUE) ? '<!DOCTYPE html>' : '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">';
//Predefine charset
$charset = "UTF-8";
$mime = "text/html";
if ($html5 == FALSE)
{
$doctype_string = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">';
}
$doctype_string .= "<html lang='en'>";
// finally, output the mime type and prolog type
$this->set_header("Content-Type", "{$mime};charset={$charset}");
$this->set_header("X-UA-Compatible", "chrome=1, IE=edge");
$this->set_output($doctype_string);
return $this;
}
// --------------------------------------------------------------------------
/**
* Set Meta
*
* Sets meta tags, with codeigniter native meta tag helper
*
* @param array $meta
* @return Page
*/
public function set_meta($meta)
{
$this->meta .= $this->_meta($meta);
return $this;
}
// --------------------------------------------------------------------------
/**
* 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;
}
$file = SCRIPT_PATH . $group;
$file .= ($debug == TRUE) ? "/debug/1" : "";
$this->head_js .= $this->script_tag($file, FALSE);
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets a minified css group
* @param string $group
* @return Page
*/
public function set_css_group($group)
{
$link = array(
'href' => STYLE_PATH . $group,
'rel' => 'stylesheet',
'type' => 'text/css'
);
$this->css .= $this->_link_tag($link);
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets a minified javascript group for the page footer
*
* @param string $group
* @param bool $debug
* @return Page
*/
public function set_foot_js_group($group, $debug = FALSE)
{
$file = SCRIPT_PATH . $group;
$file .= ($debug == TRUE) ? "/debug/1" : "";
$this->foot_js .= $this->script_tag($file, FALSE);
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets html title string
*
* @param string $title
* @return Page
*/
public function set_title($title = "")
{
$title = ($title == "") ? 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 bool $domain
* @param string $media
* @return Page
*/
public function set_css_tag($name, $domain = TRUE, $media = "all")
{
$path = CONTENT_DOMAIN;
$css_file = "{$path}/css/{$name}.css";
if ($domain == FALSE)
{
$css_file = $name;
}
$this->css_tags .= $this->_link_tag(array(
'rel' => 'stylesheet',
'type' => 'text/css',
'media' => $media,
'href' => $css_file,
));
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets a custom tag in the header
*
* @param string $tag
* @return Page
*/
public function set_head_tag($tag)
{
$this->head_tags .= $tag;
return $this;
}
// --------------------------------------------------------------------------
/**
* Sets custom page header
*
* @param bool $html5
* @return Page
*/
public function build_header($html5 = TRUE)
{
$data = array();
//Set Meta Tags
$this->meta = ($html5 == TRUE)
? '<meta charset="utf-8" />'. $this->meta
: $this->_meta(array(
'http-equiv' => 'Content-Type',
'content' => 'text/html; charset=utf-8',
)) . $this->meta;
$data['meta'] = $this->meta;
//Set CSS
if ($this->css !== "")
{
$data['css'] = $this->css;
}
else
{
//Set default CSS group
$this->set_css_group(DEFAULT_CSS_GROUP);
$data['css'] = $this->css;
}
//Set head javascript
$data['head_js'] = ( ! empty($this->head_js)) ? $this->head_js : "";
//Set Page Title
$data['title'] = ($this->title !== '') ? $this->title : DEFAULT_TITLE;
//Set Body Class
$data['body_class'] = $this->body_class;
//Set Body Id
$data['body_id'] = $this->body_id;
//Set Base HREF
$data['base'] = $this->base;
//Set individual head tags
$data['head_tags'] = $this->head_tags;
//Set Server Headers and Doctype
$this->_headers($html5);
//Output Header
$this->load_view('header', $data);
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->load_view('footer', $data);
}
// --------------------------------------------------------------------------
/**
* Script Tag
*
* Helper function for making script tags
*
* @param string $js
* @param bool $domain
* @return string
*/
private function script_tag($js, $domain = TRUE)
{
$path = CONTENT_DOMAIN;
$js_file = "{$path}/js/{$js}.js";
if ($domain == FALSE)
{
$js_file = $js;
}
$tag = '<script src="' . $js_file . '"></script>';
return $tag;
}
// --------------------------------------------------------------------------
/**
* Set Message
*
* Adds a message to the page
* @param string $type
* @param string $message
* @param bool $return
* @return void
*/
public function set_message($type, $message, $return=FALSE)
{
$data['stat_class'] = $type;
$data['message'] = $message;
return $this->load_view('message', $data, $return);
}
// --------------------------------------------------------------------------
/**
* Redirect 303
*
* Shortcut function for 303 redirect
* @param string $url
*/
public function redirect_303($url)
{
$this->set_header("HTTP/1.1 303 See Other");
$this->set_header("Location:" . $url);
}
// --------------------------------------------------------------------------
/**
* Render
*
* Shortcut function for building a page
* @param string $view
* @param array $data
*/
public function render($view, $data=array())
{
$this->build_header();
$this->load_view($view, $data);
$this->build_footer();
}
// --------------------------------------------------------------------------
/**
* Output String
*
* Similar to render(), this is a shortcut
* to output a string in the body of the
* page.
* @param string $string
*/
public function output_string($string)
{
$this->build_header();
$this->append_output($string);
$this->build_footer();
}
// --------------------------------------------------------------------------
/**
* Private helper function to generate meta tags
*
* @param array $params
* @return string
*/
private function _meta($params)
{
$string = "<meta ";
foreach ($params as $k => &$v)
{
$string .= $k.'="'.$v.'" ';
}
$string .= " />";
return $string;
}
// --------------------------------------------------------------------------
/**
* Private helper function to generate link tags
*
* @param array $params
* @return string
*/
private function _link_tag($params)
{
$string = "<link ";
foreach ($params as $k => &$v)
{
$string .= $k . '="'.$v.'" ';
}
$string .= "/>";
return $string;
}
// --------------------------------------------------------------------------
/**
* Function for loading a view
*
* @param string $file
* @param array $data
* @param bool $return
* @return mixed
*/
public function load_view($file, array $data=array(), $return=FALSE)
{
$path = "";
// The module is set via the router
$module = strtolower(MM_MOD);
$path = MM_MOD_PATH . "{$module}/views/{$file}.php";
// If it's not a module, or doesn't exist in the module view folder
// look in the app view folder
if ( ! is_file($path))
{
$path = MM_APP_PATH . "views/{$file}.php";
}
// Contain the content for buffering
ob_start();
// Extract the data array
extract($data);
// Include the file
include($path);
$buffer = ob_get_contents();
ob_end_clean();
if ($return == TRUE)
{
return $buffer;
}
else
{
$this->append_output($buffer);
}
}
// --------------------------------------------------------------------------
/**
* Sets a header for later output
*
* @param string $key
* @param string $val
*/
public function set_header($key, $val)
{
$this->headers[$key] = $val;
}
// --------------------------------------------------------------------------
/**
* Adds text to the output buffer
*
* @param string $string
*/
public function append_output($string)
{
$this->buffer .= $string;
}
// --------------------------------------------------------------------------
/**
* Sets the output buffer
*
* @param string $string
*/
public function set_output($string)
{
$this->buffer = $string;
}
// --------------------------------------------------------------------------
/**
* Sends headers and then removes them
*/
public function flush_headers()
{
// Set headers
foreach ($this->headers as $key => &$val)
{
if ( ! isset($val))
{
@header($key);
}
else
{
@header("{$key}: {$val}");
}
}
// Empty headers
$this->headers = array();
}
}
// End of page.php