<?php
/**
* Site class for the KvFramework.
* @package KvFramework
* @subpackage SiteHandler
* @author Greg McWhirter <hide@address.com>
* @copyright Copyright © 2006, Greg McWhirter
* @license BSD License
* @version 1.0
*/
load_file(KVF_FRAMEWORK_DIR."/sitehandler/kvframework_markup.class.php");
load_file(KVF_FRAMEWORK_DIR."/sitehandler/kvframework_irenderengine.interface.php");
load_file(KVF_FRAMEWORK_DIR."/sitehandler/kvframework_renderengine.class.php");
/**
* Basis for application site_class s
* @package KvFramework
* @subpackage SiteHandler
*/
abstract class kvframework_site extends kvframework_base {
/**
* Call the render engine with appropriate parameters and stuff
* @param string $content Either a view name or text to output
* @param string $type Either "full" or "inline" - determines whether or not to use a template
* @param array $render_params Parameters passed to the render engine
* @param boolean $text Wheter or not $content was text or a view name
* @param integer $status HTTP Status Code to return
* @return boolean
*/
final protected function render($content, $type = "full", array $render_params = array(), $text = false, $status = 200){
kvframework_log::write_log("Rendering ".get_class($this)."::".$content.", Type ".$type, KVF_LOG_LDEBUG);
header("HTTP/1.1 $status");
header("Status: $status");
if(!self::$RENDERED && $type == "full"){
self::$RENDERED = true;
if($text){
self::$RENDERENGINE->render_text($content, $render_params, self::layout_file(self::$LAYOUT));
} else {
self::$RENDERENGINE->render_file(self::view_file(get_class($this), $content), $render_params, self::layout_file(self::$LAYOUT));
}
return true;
} elseif($type == "inline") {
if($text){
self::$RENDERENGINE->render_text($content, $render_params);
} else {
self::$RENDERENGINE->render_file(self::view_file(get_class($this), $content), $render_params);
}
return true;
} else {
return false;
}
}
/**
* Shortcut to render for $type = "inline", $text = false
* @param string $view View to render
* @param array $render_params Parameters to pass to the render engine
* @return boolean
*/
final protected function render_inline($view, array $render_params = array()){
return $this->render($view, "inline", $render_params);
}
/**
* Shortcut to render for $text = true
* @param string $text Text to render
* @param string $type Either "full" or "inline"
* @param array $render_params Parameters to pass to the render engine
* @return boolean
*/
final protected function render_text($text, $type = "full", array $render_params = array()){
return $this->render($text, $type, $render_params, true);
}
final public function do_before_filters(){
foreach(self::$FILTERS["before"] as $filt){
kvframework_log::write_log("Doing before filter ".$filt, KVF_LOG_LDEBUG);
if(!$this->$filt()){return false;}
}
return true;
}
final public function do_after_filters(){
foreach(self::$FILTERS["after"] as $filt){
kvframework_log::write_log("Doing after filter ".$filt, KVF_LOG_LDEBUG);
if(!$this->$filt()){return false;}
}
return true;
}
protected static $POST;
protected static $GET;
protected static $FILES;
protected static $COOKIES;
protected static $QUERYSTRING;
protected static $LAYOUT = null;
protected static $RENDERED = false;
protected static $REQUEST;
protected static $FILTERS = array("before" => array(), "after" => array());
protected static $PARAMS = array();
protected static $CALLS = array();
protected static $SCALLS = array();
protected static $SERVER;
protected static $RENDERENGINE;
final public static function startup(kvframework_irenderengine &$engine){
self::$RENDERENGINE = $engine;
self::setvars();
return true;
}
final private static function setvars(){
self::$POST = self::$NAKOR_CORE->clean_input("POST");
self::$GET = self::$NAKOR_CORE->clean_input("GET");
self::$SERVER = $_SERVER;
self::$FILES = $_FILES;
self::$COOKIES = $_COOKIE;
self::$QUERYSTRING = getenv("QUERY_STRING");
self::$REQUEST = self::$GET["url"];
return true;
}
final protected static function set_layout($layout){
self::$LAYOUT = $layout;
}
final public static function truequery(array $remove = array()){
$parts = array();
$parts = preg_split("/&/", self::$QUERYSTRING);
$ret = "";
foreach($parts as $p){
if($p != "" && substr($p, 0, 4) != "url=" && !in_array($p, $remove)){
$ret .= $p."&";
}
}
return $ret;
}
final public static function do_route(){
foreach(explode("/", self::$REQUEST) as $up){
if(substr($up, 0, 1) == ":"){
$pts = explode(":", substr($up, 1), 2);
if(is_null($pts[1])){self::$SCALLS[] = $pts[0];}
else{self::$PARAMS[$pts[0]] = $pts[1];}
} elseif($up != "") {
self::$CALLS[] = $up;
}
}
kvframework_log::write_log("Routing request ".self::$REQUEST);
self::finish_params();
self::perform_route_action((array_key_exists(0, self::$CALLS)) ? self::$CALLS[0]."_site_class" : CONFIG::DEFAULT_SITE_CLASS."_site_class");
}
final protected static function finish_params(){
self::$PARAMS = array_merge(self::$PARAMS, self::$GET, self::$POST); #, self::$POST);
unset(self::$PARAMS['url']);
unset(self::$PARAMS['request_method']);
self::clean_array_recursive(self::$PARAMS);
kvframework_log::write_log("PARAMS dump: ".self::array_to_string(self::$PARAMS), KVF_LOG_LDEBUG);
return true;
}
final public static function clean_array_recursive(&$array){
array_walk_recursive($array, array("kvframework_site", "clean_callback"));
}
final public static function clean_callback(&$r, $i){
if($r == "") { $r = null; }
}
final protected static function render_component($site_class, $method, $newlayout = null){
kvframework_log::write_log("Rendering component ".$site_class."::".$method, KVF_LOG_LDEBUG);
$sc = $site_class."_site_class";
self::flush_filters();
self::perform_route_action($sc, $method, $newlayout);
}
final protected static function redirect_to($site_class, $method){
session_write_close();
header("Location: ".self::url_for($site_class, $method));
kvframework_log::close_logs();
ob_end_flush();
exit;
}
final protected static function redirect_to_url($url){
session_write_close();
header("Location: ".$url);
kvframework_log::close_logs();
ob_end_flush();
exit;
}
final protected static function perform_route_action($site_class, $method = null, $newlayout = null){
global $SITE_CLASS;
$SITE_CLASS = new $site_class();
if(!is_null($newlayout)){self::set_layout($newlayout);}
kvframework_log::write_log("Performing action ".$site_class."::".$method);
if(is_null($method)){$method = self::route_method_for_call($site_class, implode("/", array_slice(self::$CALLS, 1)));}
if(!is_callable(array($SITE_CLASS, $method), false)){
header("HTTP/1.1 404 Not Found");
header("Status: 404 Not Found");
readfile(CONFIG::rooturl."/404.shtml");
kvframework_log::close_logs();
ob_end_flush();
exit;
}
if($SITE_CLASS->do_before_filters()){
$SITE_CLASS->$method();
$SITE_CLASS->do_after_filters();
}
kvframework_log::close_logs();
ob_end_flush();
exit;
}
final protected static function url_for($sc, $method = null, array $params = array(), array $scalls = array()){
if(!is_null($method)){$call = self::route_call_for_method($sc."_site_class", $method);}
else{$call = implode("/", array_slice(self::$CALLS, 1));}
$ret = CONFIG::rooturl."/".strtolower((substr($sc, -10) == "site_class") ? substr($sc, 0, -11) : $sc)."/".$call;
$ret = implode("/:", array_merge(array($ret), $scalls));
foreach($params as $k => $v){
if(!is_numeric($k)){
$ret .= "/:".$k.":".$v;
}
}
return($ret);
}
final protected static function before_filter($filt){
self::$FILTERS["before"][] = $filt;
}
final protected static function after_filter($filt){
self::$FILTERS["after"][] = $filt;
}
final protected static function flush_filters(){
self::$FILTERS = array("before" => array(), "after" => array());
}
final protected static function view_file($class, $view){
$view = strtolower($view);
$class = strtolower($class);
if(substr($class,-10) == "site_class"){
return(KVF_MODULES."/".substr($class, 0, -11).".module/views/".$view.".phtml");
} else {
return(KVF_MODULES."/".$class.".module/views/".$view.".phtml");
}
}
final protected static function layout_file($name){
return(KVF_LAYOUTS_DIR."/".$name.".phtml");
}
final protected static function route_method_for_call($class, $call){
$temp = self::parse_routes_file($class);
return($temp[$call]);
}
final protected static function route_call_for_method($class, $method){
$temp = self::parse_routes_file($class);
$rev = array_flip((is_array($temp)) ? $temp : array());
return($rev[$method]);
}
final protected static function parse_routes_file($class){
$map = array();
$class = strtolower($class);
if(substr($class,-10) == "site_class"){
$lines = file(KVF_MODULES."/".substr($class, 0, -11).".module/routes");
} else {
$lines = file(KVF_MODULES."/".$class.".module/routes");
}
foreach($lines as $l){
list($call, $method) = preg_split("#=>#", $l);
list($call, $method) = array(trim($call, "/ \t\n\r\0\x0B"), trim($method, "/ \t\n\r\0\x0B"));
$map[$call] = $method;
}
return $map;
}
final protected static function session($key){
return (array_key_exists($key, $_SESSION)) ? $_SESSION[$key] : null;
}
final protected static function session_set($key, $val){
return $_SESSION[$key] = $val;
}
final public static function do_eval($string){
global $SITE_CLASS;
if($SITE_CLASS instanceOf kvframework_site){
$SITE_CLASS->do_evali($string);
} else {
throw new Exception("Could not call do_evali on global \$SITE_CLASS");
}
}
final public function do_evali($string){
eval($string);
return true;
}
}
?>