<?
/**
 * $Id: Controller.mod.php 394 2008-05-28 19:28:03Z dakl $
 * Klasa kontrolera v 1.2.0
 *
 */
abstract class Controller {
	/**
 * Szablon dla metody
 *
 * @var unknown_type
 */
	public $partialTemplate;
	/**
     * Sciezka szablonu dla metody
     *
     * @var unknown_type
     */
	public $templatePath;
	/**
     * Wygenerowana przez metode tresc
     *
     * @var unknown_type
     */
	public $content;
	/**
     * Czas cache dla metody
     *
     * @var unknown_type
     */
	public $cacheTime;

	/**
     * Obiekt Smarty
     *
     * @var Smarty
     */
	protected $smarty;

	/**
     * Obiekt request
     *
     * @Request
     */
	protected $request;

	public $utf8;

	/**
     * Zawiera url na ktory ma byc przekierowany user
     *
     * @var string
     */
	private $redirect = array('url'=>'', 'time'=>'');
	/**
     * Wylacza obsluge smarty
     *
     * @var unknown_type
     */
	public $disableTemplates = false;

	public $actionRedirect = false;

	private $breadCrumbs = array();

	private $actionSet = array();

	/**
     * Konstruktor klasy
     *
     */
	public final function __construct() {

	}
	/**
     * Ustawia przekierowanie
     *
     * @param string $action (true/false/string: action)
     *
     */
	public final function SetActionRedirect($action) {
		$this->actionRedirect = $action;
	}
	/**
     * Zwraca przekierowanie
     *
     */
	public final function GetActionRedirect() {
		return $this->actionRedirect;
	}

	public final function SetBreadCrumbs($array) {
		$this->breadCrumbs = $array;
	}

	public function SetUtf8() {
		$this->utf8 = true;
	}

	public final function GetBreadCrumbs() {
		return $this->breadCrumbs;
	}

	public final function AddBreadCrumb($title, $url) {
		$this->breadCrumbs[] = array('title'=>$title, 'url'=>$url);
//		Utils::ArrayDisplay($this->breadCrumbs);
	}

	public final function AddHeader($name, $value) {
		//TODO : New Feature - testme

		$headers = Registry::Get('headers');
		$headers[$name][] = $value;
		Registry::Remove('headers');
		Registry::Set('headers', $headers);
	}

	/**
     * Dodawanie opisu
     *
     * @param unknown_type $desc
     */
	public final function AddDescription($desc) {
		//Registry::Remove('description');
		//Registry::Set('description', $desc);
		$this->AddHeader('description', $desc);
	}

	/**
     * Dodawanie opisu
     *
     * @param unknown_type $desc
     */
	public final function AddKeywords($desc) {
		//Registry::Remove('description');
		//Registry::Set('description', $desc);
		$this->AddHeader('meta', array('name'=>'keywords', 'content'=>$desc));
	}

	/**
     * Metoda przypisujaca obiekt smarty
     *
     * @param Smarty $smarty
     */
	public final function SetSmarty(Smarty $smarty) {
		$this->smarty = $smarty;
	}

	/**
     * Dodawanie elementu tytulu
     *
     * @param unknown_type $title
     */
	public final function AddTitle($title) {
		/*$t = Registry::Get('title');
		$t[] = $title;
		Registry::Remove('title');
		Registry::Set('title', $t);*/
		$this->AddHeader('title', $title);
	}

	/**
     * Weryfikacja cache metody
     *
     * @param unknown_type $method
     * @param unknown_type $param
     * @return unknown
     */
	public final function Init($method, $param) {

		$this->SetReturnPath(array());

		//logika werifikacji cache dla metod.
		$cacheTimeTmp = CacheParam::Get(get_class($this).$method);
		$cacheTimeTmp2 = CacheParam::Get(get_class($this));
		if(isset($cacheTimeTmp) && $cacheTimeTmp != '') {
			$cacheTime = $cacheTimeTmp;

		} else if(isset($cacheTimeTmp2) && $cacheTimeTmp2 != '') {
			$cacheTime = $cacheTimeTmp2;
		} else {
			$cacheTime = CacheParam::Get('global');

		}
		if($this->CheckLiveMethod($method, $param)) {
			$this->cacheTime = 0;
		} else {
			$this->cacheTime = $cacheTime;
		}

		if(Core::GetAppSafeMode()) {
			return true;
		}


		if(!$this->smarty->CacheControl($this->templatePath.$this->partialTemplate, array('cache_id'=> md5($method.$param), 'lifetime'=>$this->cacheTime))) {
			if(!Core::GetAppSafeMode()) {
				$this->smarty->CacheControl($this->templatePath.$this->partialTemplate, array('cache_id'=> md5($method.$param), 'write'=>true));

				return false;
			} else {
				return true;
			}

		} else {
			return true;
		}

		//echo ">>".$this->smarty->is_cached($this->templatePath.$this->partialTemplate, $method.substr($param,0, 100))."<<";
		//return $this->smarty->is_cached($this->templatePath.$this->partialTemplate, $method.substr($param,0, 100));

	}

	/**
     * Czysci bufor strony
     *
     * @param string $method
     * @param array $param
     */
	public final function ClearCache($method, $param) {
		$cacheParam = implode('-', $param);
		$this->smarty->clear_cache($this->partialTemplate, $method.substr($cacheParam,0, 100));
	}

	/**
     * Dodaje skrypt do naglowka strony
     *
     * @param string $script
     * @param string $type (file/code)
     * @param string $position (top/bottom)
     * @param int    $sort
     */
	public final function AddScript($script, $type='file', $position='top', $sort=100) {

		if($position == 'top') {
			$name = 'javascript';
		} else {
			$name = 'footerJavascript';
		}

		$t = Registry::Get($name);
		if($type=='file') {
			$t[$sort][$script] = array('file'=>$script, 'code'=>'');
		} else {
			$t[$sort][$script] = array('code'=>$script, 'file'=>'');
		}

		Registry::Remove($name);
		Registry::Set($name, $t);
	}

	/**
     * Dodaje CSS do naglowka strony
     *
     * @param string $script
     * @param string $type (file/code)
     * @param int    $sort
     */
	public final function AddCSS($script, $type='file', $sort=100) {

		$name = 'headerCSS';

		$t = Registry::Get($name);
		if($type=='file') {
			$t[$sort][$script] = array('file'=>$script, 'code'=>'');
		} else {
			$t[$sort][$script] = array('code'=>$script, 'file'=>'');
		}

		Registry::Remove($name);
		Registry::Set($name, $t);
	}

	public final function AddWpStatistics($key) {
		$this->AddScript("var pp_gemius_identifier ='$key';
						  var pp_gemius_hitcollector = 'wp.hit.gemius.pl';",'code','top',0);
		$this->AddScript("WP.stat.dot('max15','','');", 'code', 'top', 2);
	}

	/**
     * Dodaje skrypt przed </body>
     *
     * @param string $script
     * @param string $type
     */
	public final function AddFooterScript($script, $type='file') {
		throw new ApiException('Metoda nieobslugiwana od wersji 1.1 Controllera. Uzyj AddScript z opcja bottom.');
	}

	/**
     * Dodaje przekierowanie
     *
     * @param string $url
     * @param int $time
     */
	public final function AddRedirect($url, $time, $code=302) {
		if(is_array($url)) {
			Core::RequireOnce('plugins/Smarty/function.url.php');
			$urlData = smarty_function_url($url, $this->smarty);
		} else {
			$urlData = $url;
		}
		if($this->redirect['url']=='') {
			$this->redirect['url']=$urlData;
			$this->redirect['time']=$time;
			$this->redirect['code']=$code;
		}
	}

	/**
     * Usuwa przekierowanie
     *
     */
	public final function ClearRedirect() {
		$this->redirect = array('url'=>'', 'time'=>'');
	}

	/**
     * Sprawdza czy ustawione jest przekierowanie
     *
     * @return bool
     */
	public final function IsRedirect() {
		if($this->redirect['url']!='') {
			$return = true;
		} else {
			$return = false;
		}

		return $return;
	}

	/**
     * Zwraca url do przekierowania
     *
     * @return string
     */
	public final function GetRedirect() {
		return $this->redirect;
	}

	/**
     * Wylacza wyswietlenie szablonow
     *
     */
	public final function SetNoRender() {
		$this->disableTemplates = true;
		Profiler::$profiling = false;
	}

	/**
     * Uruchamianie obiektu klasy SharedController i wywolywanie pozadanej metody
     *
     * @param string $method
     */
	public final function RunShared($method,$param) {
		//print_R($param);
		//echo $method."<br>";
		$this->smarty->assign('param', $param);
		$shared = new SharedController();

		$shared->SetSmarty($this->smarty);
		$shared->templatePath = 'partial/Shared/';
		$shared->partialTemplate = $method.'.tpl';
		//$this->smarty->cache_lifetime = CacheParam::Get('shared'.$method);


		$cacheParam = Utils::MultiImplode('-', $param, '|').$shared->partialTemplate;
		if(FrontController::dispatchChecker($this->smarty, $shared->templatePath.$shared->partialTemplate, $cacheParam, CacheParam::Get('shared'.$method))) {
			//if(!$this->smarty->CacheControl($shared->templatePath.$shared->partialTemplate, array('cache_id'=> md5($cacheParam), 'lifetime'=>CacheParam::Get('shared'.$method)))) {
			//if(!Core::GetAppSafeMode()) {
			//$this->smarty->CacheControl($shared->templatePath.$shared->partialTemplate, array('cache_id'=> md5($cacheParam), 'write'=>true));
			//$this->smarty->assign($variable, $this->smarty->fetch($shared->templatePath.$shared->partialTemplate, md5($cacheParam), md5($cacheParam)));

			//if(!$this->smarty->is_cached($shared->templatePath.$shared->partialTemplate, md5($cacheParam), md5($cacheParam)) && !Core::GetAppSafeMode()) {
			//echo $method."<br />".$this->smarty->is_cached($shared->templatePath.$shared->partialTemplate, md5($cacheParam));
			$shared->$method($param);
			//}
			//echo "<br />".$method."<br />";
			//echo $this->smarty->get_template_vars($variable);



		}


		if(isset($param['runSharedVariable'])) {
			$variable = $param['runSharedVariable'];
		} else {
			$variable = strtolower(substr($method, 0, 1)) . substr($method, 1);
		}
		$this->smarty->assign($variable, $this->smarty->fetch($shared->templatePath.$shared->partialTemplate, md5($cacheParam), md5($cacheParam)));
	}

	/**
     *
     * Uruchamianie metody zewnetrzenego modulu
     *
     * @param string $module
     * @param string $method
     * @param string $param = null
     * @param string $template = false - czy ma byc zaladowany template
     *
     */

	public final function RunModule($module,$method,$param,$template = false) {

		if(isset($param) && is_array($param)) {
			$cparam = Utils::MultiImplode('-', $param, '|');
		} else {
			$cparam = null;
		}

		$cacheParam = $module.$method.$template.$cparam;

		$moduleControllerName = $module;
		$moduleControllerName .= "Controller";
		$moduleArray = explode('_', $moduleControllerName);
		if (count($moduleArray) > 1) {
			require_once "controller/".$moduleArray[0]."/".$moduleArray[1].".php";
		} else {
			require_once "controller/$moduleControllerName.php";
		}


		$moduleController = new $moduleControllerName();

		if($template == true) {
			$moduleController->SetSmarty($this->smarty);
			if (count($moduleArray) > 1) {
				$moduleController->templatePath = "partial/".$moduleArray[0]."/".str_replace('Controller', '',$moduleArray[1]);
				//	die($module.$moduleController->templatePath);
				$moduleController->partialTemplate = $method.'.tpl';
			} else {
				$moduleController->templatePath = "partial/$module/";
				//			die($module.$moduleController->templatePath);
				$moduleController->partialTemplate = str_replace('Action', '', $method).'.tpl';
				//$this->smarty->cache_lifetime = CacheParam::Get($module.$method);

				//			if(!$this->smarty->is_cached($moduleController->partialTemplate) && !Core::GetAppSafeMode()) {
				//				return $moduleController->$method($param);
				//			}
				//Utils::ArrayDisplay($moduleController->partialTemplate);
			}

			if(!$this->smarty->CacheControl($moduleController->templatePath.$moduleController->partialTemplate, array('cache_id'=> md5($cacheParam), 'lifetime'=>CacheParam::Get($module.$method)))) {

				if(!Core::GetAppSafeMode()) {
					//Utils::ArrayDisplay($moduleController->$method($param));
					$this->smarty->CacheControl($moduleController->templatePath.$moduleController->partialTemplate, array('cache_id'=> md5($cacheParam), 'write'=>true));

					return $moduleController->$method($param);
				}
			}



		}
		else {
			$moduleController->SetNoRender();
			return $moduleController->$method($param);
		}
	}

	/**
     *
     * Uruchamianie metody zewnetrzenego modulu
     *
     * @param string $module
     * @param string $method
     * @param string $param = null
     * @param string $template = false - czy ma byc zaladowany template
     *
     */

	public final function RunModuleController($module,$method,$param,$template = false) {

		$this->smarty->assign('param', $param);
		$moduleControllerName = $module;
		//$moduleControllerName .= "Controller";
		$moduleArray = explode('_', $moduleControllerName);
		if (count($moduleArray) > 1) {
			require_once "controller/".$moduleArray[0]."/".$moduleArray[1].".php";
		} else {
			require_once "controller/$moduleControllerName.php";
		}

		//Utils::ArrayDisplay('sd: '.$moduleControllerName);

		$moduleController = new $moduleControllerName();

		$moduleController->SetSmarty($this->smarty);

		if (count($moduleArray) > 1) {
			$moduleController->templatePath = "partial/".$moduleArray[0]."/".str_replace('Controller', '',$moduleArray[1]."/");
			//	die($module.$moduleController->templatePath);
			$moduleController->partialTemplate = $method.'.tpl';
			//Utils::ArrayDisplay($method);
		} else {
			$moduleController->templatePath = "partial/".str_replace('Controller', '',$module)."/";
			//			die($module.$moduleController->templatePath);
			$moduleController->partialTemplate = $method.'.tpl';
			
			//$this->smarty->cache_lifetime = CacheParam::Get($module.$method);

			//			if(!$this->smarty->is_cached($moduleController->partialTemplate) && !Core::GetAppSafeMode()) {
			//				return $moduleController->$method($param);
			//			}
			//Utils::ArrayDisplay($moduleController->partialTemplate);
		}
		//		$moduleController->templatePath = 'partial/Shared/';
		//		$moduleController->partialTemplate = $method.'.tpl';
		//$this->smarty->cache_lifetime = CacheParam::Get('shared'.$method);


		$cacheParam = Utils::MultiImplode('-', $param, '|').$moduleController->partialTemplate;
		if(FrontController::dispatchChecker($this->smarty, $moduleController->templatePath.$moduleController->partialTemplate, $cacheParam, CacheParam::Get($module.$method))) {
			$methodToRun = $method.'Action';
			//Utils::ArrayDisplay($methodToRun);
			$moduleController->$methodToRun($param);
		}


		if(isset($param['runSharedVariable'])) {
			$variable = $param['runSharedVariable'];
		} else {
			$variable = strtolower(substr($method, 0, 1)) . substr($method, 1);
		}
		//Utils::ArrayDisplay($param['runSharedVariable']);
		$this->smarty->assign($variable, $this->smarty->fetch($moduleController->templatePath.$moduleController->partialTemplate, md5($cacheParam), md5($cacheParam)));
	}



	public final function SetRequest(Request $request) {
		$this->request = $request;
	}

	/**
     * Zwraca obiekt Request
     *
     * @return Request
     */
	public final function Request() {
		return $this->request;
	}

	/**
     * Zmienia szablon glowny na pusty dla akcji ajaxowych
     *
     */
	public final function SetAjaxRender($ajaxCallPath = false) {
		Router::DeleteThisUrl();
		if ($ajaxCallPath) {
			$prev = SessionProxy::GetValue(Router::$PREV_URL);
			if($prev != null)
			SessionProxy::SetValue('ajaxCallPath', $prev);
		}
		$template = 'clean.tpl';
		Registry::Remove('smartyTemplate');
		Registry::Set('smartyTemplate', $template);
		Profiler::$profiling = false;
	}

	/**
     * Ustawia sciezke powrotna
     *
     * @param array $path
     */
	public final function SetReturnPath($path) {
		Registry::Set('smartyReturnPath', $path);
	}

	/**
     * Dodaje element sciezki powrotnej
     *
     * array(title=>title, url=>url)
     *
     * @param array $item
     */
	public final function AddReturnPathItem($item) {

		if(Registry::Exists('smartyReturnPath')) {
			$data = Registry::Get('smartyReturnPath');
			Registry::Remove('smartyReturnPath');
			$data[]=$item;
			Registry::Set('smartyReturnPath', $data);
		}
	}

	/**
     * Zwaraca sciezke powrotna
     *
     * @return array
     */
	public final function GetReturnPath() {
		return Registry::Get('smartyReturnPath');
	}

	/**
     * Zwraca sformatowany url
     *
     * @param string $controller
     * @param string $action
     * @return string
     */
	public final function GetMyUrl($controller,$action) {
		return ereg_replace('Action', '', $action).PATH_SEPARATOR.ereg_replace('Controller', '', $controller).APPLICATION_FILE_TYPE;
	}


	/**
     * Sprawdza czy dana metoda ma byc zawsze uruchamiana (cache independent)
     *
     * @param string $method
     * @return bool
     */
	public final function CheckLiveMethod($method, $param) {
		if(isset($this->$method) || preg_match('/^ajax/', $method) || (isset($param['liveMethod']) && $param['liveMethod']==true)) {
			return true;
		} else {
			return false;
		}
	}

	/**
     * Zwraca oryginalne parametry z urla
     *
     * @param array $param
     * @return array
     */
	public final function GetUrlParam($param) {
		if(is_array($param) && isset($param['urlParam'])) {
			return array_reverse(explode(",", $param['urlParam']));
		} else {
			return array();
		}
	}



	public function SetActionSet($set) {

		$this->actionSet = $set;
	}

	public function LoadAdditionalModule($module, $controller) {
		if(is_file('controller/'.$module.'/'.str_replace($module.'_', '', ucfirst($controller)).'.php')) {
			Core::RequireOnce('controller/'.$module.'/'.str_replace($module.'_', '', ucfirst($controller)).'.php');
			MFLog::Debug('Loading module: '.$module.': '.$controller);
		} else {

			MFLog::Debug('Unable to load module, Loading controller: '.$controller);
			throw new CoreException('Unable to load module, Loading controller: '.$controller);
		}
	}

	public function LoadAdditionalController($controller) {

		if(is_file('controller/'.ucfirst($controller).'.php')) {
			Core::RequireOnce('controller/'.ucfirst($controller).'.php');
			MFLog::Debug('Loading module: '.$controller);
		} else {

			MFLog::Debug('Unable to load module, Loading controller: '.$controller);
			throw new CoreException('Unable to load module, Loading controller: '.$controller);
		}
	}

	public function RunAdditionalModule($controller, $method) {

		$controllerObj = null;

		if(class_exists($controller) && class_parents($controller) == Array('MainController'=>'MainController', 'Controller'=>'Controller') && class_implements($controller) == Array('ControllerInterface'=>'ControllerInterface')) {
			$controllerObj = new $controller();

			if(!method_exists($controllerObj, $method) && !method_exists($controllerObj, $method.'Action')) {
				MFLog::Debug('Method thoes not exists: '.$method);
				throw new CoreException('Method thoes not exists: '.$method);
			}
		} else {
			throw new CoreException('Brak klasy lub brak dziedziczenia!');
		}

		return $controllerObj;
	}

	public function DispatchAdditionalModule($controllerObj, $controller, $method, $module, $param, $liveMethod) {
		$controllerObj->SetSmarty($this->smarty);
		$controllerObj->partialTemplate = $method.'.tpl';

		$controllerObj->templatePath = 'partial/'.str_replace('_', '/', str_replace('Controller', '', $controller)).'/';


		if((!$controllerObj->Init($method, md5(implode($param, '-'))) || $controllerObj->CheckLiveMethod($method, $param) || $liveMethod) && $controllerObj->GetActionRedirect()!=true) {

			$methodAction = $method;
			$controllerObj->$methodAction($param);

		}


		if(!isset($controllerObj->content) && !$liveMethod) {
			//$this->smarty->cache_lifetime = $controllerObj->cacheTime;

			if(!$this->smarty->CacheControl($controllerObj->templatePath.$controllerObj->partialTemplate, array('cache_id'=> $method.substr(md5(implode($param, '-')),0,100), 'lifetime'=>$controllerObj->cacheTime)) && !Core::GetAppSafeMode()) {

				$this->smarty->CacheControl($controllerObj->templatePath.$controllerObj->partialTemplate, array('cache_id'=> $method.substr(md5(implode($param, '-')),0,100), 'write'=>true));
			}


			$controllerObj->content	= $this->smarty->fetch($controllerObj->templatePath.$controllerObj->partialTemplate, $method.substr(md5(implode($param, '-')),0,100));
			//echo $this->controllerObj->templatePath.$this->controllerObj->partialTemplate;

		}

		//Utils::ArrayDisplay($controllerObj->content);

		$this->smarty->append('zoneContent', $controllerObj->content);
		$this->smarty->assign('zoneContent', $controllerObj->content);
	}

	public function GetActionSet() {
		return $this->actionSet;
	}

	public function ExecuteAdditionalActions($param) {
		$actionSetArray = $this->GetActionSet();
		$this->smarty->assign('zoneContent', '');

		//Utils::ArrayDisplay($actionSetArray);
		foreach($actionSetArray as $actionSet) {
			if(isset($actionSet['liveMethod'])) {
				$liveMethod = true;
			} else {
				$liveMethod = false;

			}
			try {
				$this->LoadAdditionalModule($actionSet['module'], $actionSet['controller']);
			} catch (CoreException $e) {

				$this->LoadAdditionalController($actionSet['controller']);
			}
			$controllerObj = $this->RunAdditionalModule($actionSet['controller'], $actionSet['method']);
			$this->DispatchAdditionalModule($controllerObj, $actionSet['controller'], $actionSet['method'], $actionSet['module'], $param, $liveMethod);
		}

	}

}

?>