<?php
/**
* _Core_ControllerAbstract class is the parent abstract class of every controller in a PWF application.
* @copyright Copyright (c) 2012, PWF
* @license http://phpwebframework.com/License
* @version PWF_0.3.0
*/
abstract class _Core_ControllerAbstract implements _Core_ControllerInterface
{
/**
* Instance of _Core_Path with properties and methods relative to the url path
* @var _Core_Path
*/
public $path;
/**
* Instance of _Core_Server with properties and methods relative to the variables passed by the server
* @var _Core_Server
*/
public $server;
/**
* Instance of _Properties generated by the PROPERTIES_FILE constant difined in the index.php
* @var _Properties
*/
public $properties;
/**
* Instance of _Core_Post with properties and methods relative to data received by post
* @var _Core_Post
*/
public $post;
/**
* The instance of the current _Core_FrontController
* @var _Core_FrontController
*/
private $frontController;
/**
* Array with Javascript lines added when pwfFooter method is called
* @var array
*/
private $jsLines = array();
/**
* The _Data_Db objects that have been instantiated by data from the main properties file
* @var array of _Data_Db
*/
private $dbObjects = array();
/**
* It uses the instance of the current FrontController to give value to objects needed by
* Controllers mainly for shorter usage reasons.It also keeps this instance as private
* in order to have feedback methods like submit and link.
* @param _Core_FrontController $fc
*/
public function __construct(_Core_FrontController $fc)
{
$this->frontController = $fc;
$this->path = $this->frontController->path;
$this->server = $this->frontController->server;
$this->properties = $this->frontController->properties;
$this->post = $this->frontController->post;
}
/**
* It returns the current application id as PWF has generated it.
* (crc32 hash of the src directory + "_" + after the last / of the src directory)
*/
public function getApplicationId()
{
return $this->internalRequest->applicationId;
}
/**
* It returns the root url of the application (where the index.php is)
* Shortcut for $this->path->getRootUrl();
*/
public function root()
{
return $this->path->getRootUrl();
}
/**
* It stops the flow order and redirect to the given url or path of the Controller relative to root()
* @param $controllerPath The url for the redirection or the path of the Controller to redirect to
*/
public function link($controllerPath)
{
$this->frontController->link($controllerPath);
}
/**
* It stops the flow order and redirect to the given Controller Path imitating the PWF.js submit function.
* It keeps post data to session variables , redirects and then FrontController will recognize them as post.
* @param string $submitData The submit data as defined also for a submit from a page
* (e.g. ControlerPath?action:actionData or action or action:actionData or ControlerPath?action if ControllerPath
* is not provided the current controller path will be used)
* @param boolean $clearPostData If true the current data from post will not be used.
*/
public function submit($submitData,$clearPostData = true)
{
$this->frontController->submit($submitData, $clearPostData);
}
/**
* Bypasses the defined template that was going to be used (from the application properties) with the one given
* @param $template The name of the template (without the .php)
*/
public function setTemplate($template)
{
$this->frontController->setSpecialTemplate($template);
}
/**
* It uses a template file and returns the result as string.
* The instance of the current Controller can be also used
* from inside the template with the $c variable.
* @param $template The name of the template (without the .php)
* @param $var If given it will contains a variable (e.g. an array map of variables) that can be used by the template file
* @throws _Exception_FileSystem
* @return string
*/
public function useTemplate($template,$var = null)
{
$filename = $this->properties->get("VIEWS_FOLDER")."/".$template.".php";
if (!_File::exists($filename))
{
throw new _Exception_FileSystem(_Exception_Messages::$fileNotFound." ".$filename, 45687);
}
else
{
$c = $this;
ob_start();
include $filename;
$contents = ob_get_contents();
ob_end_clean();
return $contents;
}
}
/**
* It returns true if there is a PWF post Action with the one given (e.g. action("doSomething") will return if there is
* action doSomething from post ) . If provided a Controller Path it checks that this is also acurate
* (e.g. action("Welcome?doSomething") will return true if the Controller is the Controller_Welcome and the action is doSomething).
* @param string $check
* @return boolean
*/
public function action($check)
{
if($this->post->get("pwf_Action") == null)
{
return false;
}
else
{
return (_String::contains($check, "?") ? $this->path->getControllerPath()."?":"") . $this->post->get("pwf_Action") == $check ;
}
}
/**
* Returns the data value that fallows the action in submit data.
* (e.g. if submit data is "doSomething:id=34&title=this is a title" actionData("id") will return 34)
* @param unknown_type $key
* @return string or null
*/
public function actionData($key)
{
return $this->post->get("pwf_ActionData_".$key);
}
/**
* Initialize (if not yet initialized) and returns a _Data_Db object (PDO inhereted).
* The parameters for the initialization comes from the application's main property file
* (e.g. for db() will use the parameters from DB , for db("USERS") will use the parameters
* from DB_USERS)
* @param string $dbName
* @return _Data_Db
*/
public function db($dbName = null)
{
if(!isset($this->dbObjects[$dbName]))
{
$this->initDb($dbName);
}
return $this->dbObjects[$dbName];
}
/**
* Initialize the _Data_Db object according to the dbName provided
* @param string $dbName
* @throws _Exception_Data
*/
private function initDb($dbName)
{
$dbIndex = $dbName == null ? "DB" : "DB_".$dbName;
if(!$this->properties->containsKey($dbIndex))
{
throw new _Exception_Data(_Exception_Messages::$dbWithoutProperties.$dbIndex, 456554);
}
else
{
$dbConstructors = $this->properties->get($dbIndex);
if(!isset($dbConstructors["username"]))
{
throw new _Exception_Data(_Exception_Messages::$dbWithoutUsername.$dbIndex, 456554);
}
else if(!isset($dbConstructors["password"]))
{
throw new _Exception_Data(_Exception_Messages::$dbWithoutPassword.$dbIndex, 456554);
}
else if(isset($dbConstructors["dsn"]))
{
try
{
$this->dbObjects[$dbName] = new Pwf_Data_Db($dbConstructors["dsn"],$dbConstructors["username"],$dbConstructors["password"]);
}
catch (PDOException $e)
{
throw new _Exception_Data($e->getMessage(),$e->getCode());
}
}
else if(!isset($dbConstructors["database"]))
{
throw new _Exception_Data(_Exception_Messages::$dbWithoutDatabase.$dbIndex, 456554);
}
else
{
if(!isset($dbConstructors["host"]))
{
$dbConstructors["host"] = "localhost";
}
if(!isset($dbConstructors["engine"]))
{
$dbConstructors["engine"] = "mysql";
}
try
{
$this->dbObjects[$dbName] = new _Data_Db($dbConstructors["engine"].':dbname='.$dbConstructors["database"].";host=".$dbConstructors["host"],$dbConstructors["username"],$dbConstructors["password"]);
}
catch(PDOException $e)
{
throw new _Exception_Data($e->getMessage(),$e->getCode());
}
if(isset($dbConstructors["charset"]))
{
$this->dbObjects[$dbName]->exec("SET NAMES '".$dbConstructors["charset"]."'");
}
}
}
}
/**
* Adds a JavaScript line that will be output with pwfFooter.(; is auto added at the end of each line)
* @param string $line
*/
public function addJsLine($line)
{
$this->jsLines[] = $line;
}
/**
* pwfHeader must be called from templates after the <body> tag for every page that generates HTML
* @return string
*/
public function pwfHeader()
{
$header = "<script type=\"text/javascript\" src=\"".$this->path->getRootUrl()."/".$this->properties->get("JAVASCRIPTS_FOLDER")."/PWF.js\"></script>\n".
"<form id=\"pwfForm\" action=\"".$this->root()."/".$this->path->getAfterRootUrl()."\" method=\"post\" enctype=\"multipart/form-data\" onsubmit=\"return false\">\n";
if(_File::exists($this->path->getPublicPath()."/".$this->properties->get("JAVASCRIPTS_FOLDER")."/".$this->path->getControllerPath().".js"))
{
$header .= "<script type=\"text/javascript\" src=\"".$this->root()."/".$this->properties->get("JAVASCRIPTS_FOLDER")."/".$this->path->getControllerPath().".js"."\"></script>\n";
}
return $header;
}
/**
* pwfHeader must be called from templates before the </body> tag for every page that generates HTML
* @return string
*/
public function pwfFooter()
{
$footer = "<script type=\"text/javascript\">\n";
$footer .= "pwf.setup('".$this->path->getRootUrl()."','".$this->path->getControllerPath()."','".$this->path->getControllerUrl()."');\n";
if(count($this->jsLines) > 0)
{
foreach($this->jsLines as $line)
{
$footer .= $line.";\n";
}
}
$footer .= "</script>\n</form>\n";
return $footer;
}
/**
* Binds a Controller's static parameter starting with _ with a PWF cache file depending on the id given.
* If there is no PWF cache file for that spesific bind then the papameter will be null. And if you make null
* a parameter that there is a PWF cache file for it then the file will be deleted.
* @param string $staticPropertyName
* @param string $id
*/
public static function cachingBind($staticPropertyName,$id)
{
_Core_ClassLoader::cachingBind(get_called_class(),$staticPropertyName,$id);
}
}
?>