'templates/layout/page.php', ///This should contain the layout of the site. 'template_folder' => 'templates', 'model_folder' => 'models', 'insert_layout' => true ); public $includes = array(); public $css_includes= array(); public $js_includes = array(); public $css_folder = 'css/'; public $js_folder = 'js/'; public $content = array( 'head' => '' ); /** * Constructor * Finds the location of the current file - eg. 'advertise/myaccount.php' */ function __construct() { global $config; $this->setPage($config["PHP_SELF"]); $this->setController(); $this->setModel(); } /////////////////////////////// Setting functions //////////////////////////////// /** * Takes a file name as the argument and find its template based on the file name. * Argument : $file_name - The file name of the controller document. */ function setPage($file_name) { global $config; //Remove the absolute site path while conserving the directory structure in the URL $file_name = str_replace($_SERVER['DOCUMENT_ROOT'], '', $file_name); $escaped_path = preg_replace('/([\/\\\.\?\~\\=\_\-\,])/','\\\$1', $config['site_absolute_path']); $file_name = preg_replace('/' . $escaped_path . '/', '', $file_name, 1); //Replace just 1 time $file_name = preg_replace('/controllers\//', '', $file_name);//If we are following mvc architecture if(strpos($file_name,'/') === 0) $file_name = substr($file_name, 1); //Remove the query parts $parts = explode('?', $file_name); $file_name = $parts[0]; //Make sure that it is a file call and not a directory if(!strpos(basename($file_name), '.php')) { ///:TODO: This could be .php5 or something - could cause problems. $file_name .= 'index.php'; } $this->page = $file_name; } /** * Find the controller for the current page - usually the folder's name is the controller. */ function setController($controller = '') { $controller = dirname($this->page); if($controller == '.') $controller = ''; $this->controller = $controller; } /** * This will set the template for the page - you can specify the file to be used as the template. * In most cases, this is an internal function. But it can be called by the user as well. * Argument : $template_file - This is the template file to be used - it must be kept in the template folder. * $use_exact_path - If this is false, MVC will try to find the template file using some rules(search in the templates folder etc. If true, it will just include the exact page. */ function setTemplate($template_file, $use_exact_path = false) { global $config; $this->_findResources($template_file); if(!$use_exact_path) $template_file = joinPath($config['site_folder'], $this->options['template_folder'], $template_file); //Plugins are a special case. if(strpos($config['PHP_SELF'],'plugins') !== false) { $template_file = 'template.php'; } if(!file_exists($template_file)) { //Search the template folder for that file if (file_exists( joinPath($this->options['template_folder'],$template_file) )) $this->template = joinPath($this->options['template_folder'],$template_file); else $this->template = ''; } else $this->template = $template_file; } /** * See if a Model page exist for this page - if it is there, include it */ function setModel($model_file = false) { $this->model = ''; if($model_file === '') { //The coder has specifically called setModel('') - so don't use a model return; } $model_file = $this->controller . '.php'; $model_folder = joinPath($GLOBALS['rel'], $this->options['model_folder'], '/'); $model_name = ''; if(!file_exists($model_file)) { //Search the template folder for that file if (file_exists( joinPath($model_folder, $model_file))) { $this->model = $model_file; } else { //Try to find the model with newer methods. //First, try to make the first letter uppercase if (file_exists( joinPath($model_folder, ucfirst($model_file)) )) { $this->model = ucfirst($model_file); //If thats not there, look for all lowercase model name. } elseif(file_exists( joinPath($model_folder, strtolower($this->controller) . '.php') )) { $this->model = strtolower($this->controller) . '.php'; break; } } } else $this->model = $model_file; $model_name = $this->model; if($this->model) { include_once(joinPath($model_folder, $this->model)); $this->model_name = str_replace('.php','',$model_name); } } /** * Finds all the CSS and JS files that must be included in this page. */ function _findResources($template_file) { global $config; $css_file = preg_replace('/\.php$/','.css',$template_file); $js_file = preg_replace('/\.php$/','.js', $template_file); if(file_exists(joinPath($config['site_relative_path'], $this->css_folder, $css_file))) $this->addResource($css_file, 'css'); if(file_exists(joinPath($config['site_relative_path'], $this->js_folder, $js_file))) $this->addResource($js_file, 'js'); } /** * This will set the title of the page. * Argument : $title - The string to be used inside the <title></title> tag. */ function setTitle($title) { if($title) $this->title = $title; } /** * Add a resource file to the HTML page - like a css file or a javascript file. * Arguments : $file - The file to be included in the output HTML file * $type - The type of file - this says whether the file is a javascript or a css file. Must have the value('css' or 'js') * $use_exact_path(Boolean) - Uses the exact value given as the $file argument in the 'href' part. If this is false, the system will gusess a better value. */ function addResource($file, $type="", $use_exact_path=false) { if(!$file) return; global $config; if(preg_match('#https?\://#', $file)) $use_exact_path = true; // If a full absolute url is given, use exact path. if(!$type) list($name,$type) = explode(".",$file); $folder = ($type == 'js') ? $this->js_folder : $this->css_folder ; $link = ''; if($use_exact_path) $link = $file; else $link = joinPath($config['site_url'], $folder, $file); if($type=='css' or $type=='stylesheet' or $type=='style' or $type=='stylesheets') { $current_include = ''; if(!in_array($current_include,$this->css_includes)) array_push($this->css_includes, $current_include); } elseif($type=='js' or $type=='javascript' or $type=='jscript' or $type=='script') { $current_include = ''; if(!in_array($current_include,$this->js_includes)) array_push($this->js_includes, $current_include); } else { error("Template Error: Type(2nd argument of addResource) '$type' not valid. Must be 'css' or 'js'."); } if(!in_array($current_include,$this->includes)) { array_push($this->includes,$current_include); } } /** * Adds meta tags. :TODO: improve this. */ function addMetadata($name,$contents) { $this->head_data .= ''."\n"; } //////////////////////////////// Layout Functions //////////////////////////////// /** * Prints the page portion. This is done by including 'page.php' inside the 'layout' folder. */ function printLayout() { extract($GLOBALS); $title = ($this->title) ? $this->title : $config['site_title']; $includes = implode($this->includes,"\n"); $css_includes = implode($this->css_includes,"\n"); $js_includes = implode($this->js_includes,"\n"); include(joinPath($config['site_folder'], $this->options['layout_file'])); } //////////////////////////////// Action functions //////////////////////////////// /** * Render the page by includeing the template file. It also calls the printHead() and printEnd() functions. * Arguments : $template_file - The template file for the current page - if nothing is given it uses the * template with the same name as the current page. OPTIONAL * $use_layout - If this is true, it will insert the template file into the layout file and display it. If false, it will just display the template file. * $use_exact_path - If this is false, MVC will try to find the template file using some rules(search in the templates folder etc. If true, it will just include the exact page. */ function render($__template_file = "", $use_layout = true, $use_exact_path = false) { // The __ to make sure a global variable don't overwrite it. extract($GLOBALS); //Make sure that all variables are accessable from the template. if($__template_file) { $this->setTemplate($__template_file, $use_exact_path); } elseif(!$this->template) { $this->setTemplate($this->page); } if(!$this->template) error('The template file for "' . $this->page . '" does not exist.'); if($use_layout and $this->options['insert_layout']) $this->printLayout(); else include($this->template); } }