<?PHP

/**
* extends engine
*/
class extender{

	var $error = false;

	/**
	* same as if($_POST['action'] == 'save')
	* 
	* @param String $name
	* 
	* @example $this->constrollerName->POST('save')->method(); //it will execute controller method "save" if $_POST['save'] variable is not null
	* @example $this->constrollerName->POST('action=save')->method(); //it will execute controller method "save" if $_POST['action'] variable is "save"
	*/
	function POST($name){

		$this->Request->query_method = 'POST';
		$this->Request->POST($name);
		return $this;
	}

	/**
	* same as if($_GET['action'] == 'save')
	* 
	* @param String $name
	* 
	* @example $this->constrollerName->GET('save')->method(); //it will execute controller method "save" if $_GET['save'] variable is not null
	* @example $this->constrollerName->GET('action=save')->method(); //it will execute controller method "save" if $_GET['action'] variable is "save"
	*/
	function GET($name){

		$this->Request->query_method = 'GET';
		$this->Request->GET($name);
		return $this;
	}
	/**
	* validate POST or GET data
	* @param array $set_to_validate = array - array('name' => 'is_numeric');
	* @param String $message or Array - 'fill required fields', array('user' => 'user field required', 'email => 'email field required')
	* 
	* @example  $set_to_validate = array('phone', 'first_name', 'last_name', 'password', 'password2' => 'equal_to=password', 'email' => 'email', 'county' => 'is_string', 'zip' => 'is_numeric')
	* @example $set_to_validate = array('phone', 'first_name' => 'equal_to="Mari"')
	* 
	* more details in class.Request.php file
	*/
	function validate($set_to_validate = array(), $message = ''){

		if($this->Request->activate == true){

			$val_data = array();
			if(gettype($set_to_validate) == 'string'){

				$validate_columns = $set_to_validate;
				$set_to_validate = array();
			}
			if($validate_columns){

				$exp = explode(',', $validate_columns);
				foreach($exp as $v){

					if($v)
						$val_data[$v] = $v;
				}
			}

			$validate_data = $set_to_validate ? array_merge($val_data, $set_to_validate) : $val_data;
			if($validate_data){
				$i=0;
				foreach($validate_data as $key => $val){

					$key = is_numeric($key) ? $val : $key;
					$msg = $message;
					if(is_Array($message)){

						if($message[$key]){

							$msg = $message[$key];
						}
						else{

							if($message[$i]){

								$msg = $message[$i];
							}
							else{

								foreach($message as $messageKey => $messageValue){

									if(is_numeric($messageKey)){

										$msg = $messageValue;
									}
								}
							}
						}
					}
					if($msg){

						if($this->Request->request[$key] == $this->Language($msg)){

							$this->Request->request[$key] = '';
							$_POST[$key] = '';
						}
					}
					$i++;
				}
			}

			$this->Request->validate($validate_data, $this->Request->request);
			if($this->Request->error){

				$i=0;
				foreach($this->Request->error as $key => $error){

					if($error == true){

						$msg = $message;
						if(is_Array($message)){

							if($message[$key]){

								$msg = $message[$key];
							}
							else{

								if($message[$i]){

									$msg = $message[$i];
								}
								else{

									foreach($message as $messageKey => $messageValue){

										if(is_numeric($messageKey)){

											$msg = $messageValue;
										}
									}
								}
							}
						}
						if($msg)
							$this->message[$key] = $this->Language($msg);
						$this->error[$key] = $this->message[$key];
					}
					else{

						unset($this->Request->error[$key]);
					}
					$i++;
				}
			}
			$this->error_json = json_encode(array('error' => $this->error, 'message' => $this->message));
		}
		return $this;
	}

	/**
	* it executes checkMethod, no error break
	* 
	* @param String $methods or Array
	* @param Array $variables = array() - sends array variable to method
	* 
	* @example $this->POST('save')->checkMethod('isLogged')->method() //method will not executed if error appears
	*/
	function checkMethod($methods, $variables = array()){

		if($this->Request->activate == true && $this->Request->error == false){

			if(is_array($methods)){

				foreach($methods as $method){

					if(method_exists($this, $method)){

						$this->$method($variables);
					}
				}
			}
			else{

				if(method_exists($this, $methods)){

					$this->$methods($variables);
				}
			}
		}
		return $this;
	}

	/**
	* executes controller method if no errors $this->error()
	* 
	* @param String $methods = '' or Array - needed if $_POST['save'] and method is not the same
	* @param Array $variables = array() - sends array variable to method
	* 
	* @example $this->POST('save')->method()
	* @example $this->POST('save')->method('saveUser')
	*/
	function method($methods = '', $variables = array()){

		$methods = $methods ? $methods : $this->Request->method;

		if(is_array($methods)){

			foreach($methods as $method){

				if(method_exists($this, $method) && $this->Request->activate == true && $this->Request->error == false && $this->error == false){

					$this->$method($variables);
				}
			}
		}
		else{

			if(method_exists($this, $methods) && $this->Request->activate == true && $this->Request->error == false && $this->error == false){

				$this->$methods($variables);
			}
		}
		unset($this->Request->method);
		return $this;
	}

	private function installKey($key_as_value){

		$key = ($key_as_value);
		$value = addslashes($key_as_value);

		if( !$this->model && !$this->page )
			die('No model and page AT extender.php LINE 234');

		$this->Sql->Query("INSERT INTO language (`name`, `value`, `language`, `model`, `page`, `show_page`, `is_visible`) VALUES ('".addslashes($key)."', '".$value."', '".$_SESSION['language']."', '".$this->model."', '".$this->page."', '".($_GET['show_page'] ? $_GET['show_page'] : $this->model.'_'.$this->page)."', 1)");
	}

	private function checkLanguageKey($key, $replacement){

		$row = $this->Sql->Query("SELECT SQL_CACHE * FROM language WHERE `name` = '".addslashes($key)."' AND language = '".$_SESSION['language']."' AND model = '".$this->model."' LIMIT 1 ", true);
		$id = $row[0]['id'];
		$value = $row[0]['value'];

		if(!$value){

			$this->installKey($key);
			$id = $this->Sql->Insertid;
			$value = $key;
		}
		$value = preg_replace_callback('/\{(.*?)\}/', function( $matches ) use ( $replacement ) {return $replacement[$matches[1]];}, $value);
		//return $value.'[HELP='.$id.']';
		return $value;
	}

	/**
	* it sets language key to database, if value is set then returns value
	* 
	* @param String $key
	* @param Boolean $add_help = false
	* @param Array $replacement = array() - if $key contains variable {variable} then it replace it array('variable' => 'value')
	*/
	function language($key, $replacement = array()){

		if(!trim($key)){

			return $key;
		}

		return $this->checkLanguageKey($key, $replacement);
	}

	/**
	* it makes error object and installs it to database
	* it will not start start method function
	* 
	* @param String $key_or_message - if u want use short key "user_not_logged" or "User not logged"
	* @param String $message = '' "User not logged"
	*/
	function error($key_or_message, $message = ''){

		$this->error[$key_or_message] = $this->Language(($message ? $message : $key_or_message));
		$this->error_json = json_encode(array('error' => $this->error, 'message' => $this->error));
	}

	/**
	* it makes message object and installs it to database
	* 
	* @param String $key_or_message - if u want use short key "user_not_logged" or "User not logged"
	* @param String $message = '' "User not logged"
	*/
	function message($key_or_message, $message = ''){

		$this->message[$key_or_message] = $this->Language(($message ? $message : $key_or_message));
		$this->message_json = json_encode(array('error' => array($key_or_message => false), 'message' => $this->message));
	}

	/**
	* gets message value
	* 
	* @param String $key - "user_not_exists" or "User not exists"
	*/
	function getMessage($key){

		if($key == 'json') return $this->message_json;
		return $this->message[$key];
	}

	/**
	* gets error value
	* 
	* @param String $key - "user_not_exists" or "User not exists"
	*/
	function getError($key){

		if($key == 'json') return $this->error_json;
		return $this->error[$key];
	}

	/**
	* append params to current link 
	* 
	* @param String $url = '' - "?action=save&id=1"
	* @param Array $hideId = array() - array('id') - it will hide id param from seo url
	*/
	function appendLink($url = '', $hideId = array()){

		$urlSplit = explode('&', str_replace('?', '', $url));
		$urlArray = array();
		foreach($urlSplit as $v){

			list($key, $value) = explode('=', $v);
			if($value){

				$urlArray[$key] = $value;
				$$key = $value;
			}
		}
		$firstGetUrl = '';
		$getUrl = '';
		$hideIdKeyList = preg_match('/([a-zA-Z0-9\__]+)/i', $_GET['hideIdKeyList']) ? explode('_', $_GET['hideIdKeyList']) : array();
		foreach($_GET as $k => $v){

			if(!$urlArray[$k] && preg_match('/([a-zA-Z0-9\__]+)/i', $v) && $k != 'hideIdKeyList' && $k != 'request'){

				if($k == 'show_page' || $k == 'model' || $k == 'page' || preg_match('/'.str_replace('/', '\/', $v).'/i', $_SERVER['REDIRECT_URL'])){

					$firstGetUrl .= $firstGetUrl ? '&'.$k.'='.$v : '?'.$k.'='.$v;
				}
				else{

					$getUrl .= '&'.$k.'='.$v;
				}

				if(in_array($k, $hideIdKeyList)){

					$hideId[] = $k;
				}
			}
		}
		if($_GET['hideIdKeyList']) $hideId[] = 'hideIdKeyList';
		$url = $firstGetUrl.str_replace('?', '&', $url).$getUrl;
		return $this->Link($url, $hideId);
	}

	/**
	* it will make SEO url if needed
	* 
	* @param String $url = '' - "?model=modelName&page=pageName&action=save&id=1&show_page=Product Name"
	* @param Array $hideId = array() - array('id') will hide parameters from url
	* 
	* if show_page param is added then SEO url will look like http://domain/Product-Name, if not then http://domain/pageName
	*/
	function Link($url = '', $hideId = array(), $ignoreAdmin = false){

		if(preg_match('/http/i', $url)){

			$url = str_replace('&amp;', '&', $url);
			$url = str_replace('&amp', '&', $url);
			$url = str_replace('&', '&#38;', $url);
			return $url;
		}
		if(preg_match('/mailto\:/i', $url)) return $url;
		if(preg_match('/callto\:/i', $url)) return $url;

		$url = str_replace('-', '+', $url);
		$url = str_replace(' ', '-', $url);
		$url = str_replace('?', '', $url);
		$url = str_replace('%', '', $url);
		$url = '?'.$url;
		$retUrl = '';
		$canonicalUrl = '';
		$regularUrl = '';

		$model = $this->model;
		$page = $this->page;
		if($model == $_GET['model'] && $page == $_GET['page'] && $_GET['show_page'])
			$show_page = $_GET['show_page'];

		$urlSplit = explode('&', str_replace('?', '', $url));
		$urlArray = array();
		foreach($urlSplit as $v){

			list($key, $value) = explode('=', $v);
			if(preg_match('/\=/i', $v))
				$urlArray[$key] = $value;
			else
				$urlArray[$last_key] .= '&'.$key;
			$last_key = $key;
		}

		$i = 1;
		$hideIdKeyList = '';
		foreach ($urlArray as $key => $value){

			$$key = $value;//lets declare new values for variables
			if($key != 'model' && $key != 'page' && $key != 'show_page' && $value && ($value != '&' || $value != '?')){

				if($hideId){

					if(!in_array($key, $hideId)){

						$retUrl .= '/'.$value;
					}
					if(in_array($key, $hideId)){

						$hideIdKeyList .= $hideIdKeyList ? '_'.$key : $key;
					}
					//$canonicalUrl .= '&'.$key.'='.$value;
				}
				else{

					$retUrl .= '/'.$value;
					//$canonicalUrl .= '&'.$key.'=$'.$i;
					$i++;
				}
				//see võib põhjustada probleeme
				if($key){

					$canonicalUrl .= '&'.$key.'='.$value;
					$regularUrl .= '&'.$key.'='.$value;
				}
			}
		}

		if(isset($show_page) && strlen($show_page) == 0){

			$retUrl = ($retUrl ? $retUrl.'/' : '');
			$canonicalUrl = '?show_page='.$show_page.'&model='.$model.'&page='.$page.$canonicalUrl.($hideIdKeyList ? '&hideIdKeyList='.$hideIdKeyList : '');
			$regularUrl = '?model='.$model.'&page='.$page.$regularUrl;
		}
		else{

			$retUrl = ($show_page ? $show_page : $page).$retUrl.'/';
			$canonicalUrl = '?'.($show_page ? 'show_page='.$show_page.'&' : '').'model='.$model.'&page='.$page.$canonicalUrl.($hideIdKeyList ? '&hideIdKeyList='.$hideIdKeyList : '');
			$regularUrl = '?model='.$model.'&page='.$page.$regularUrl;
		}
		if(substr($retUrl, 0, 1) == '/')
			$retUrl = substr($retUrl, 1);

		//die($retUrl);
		if((preg_match('/\/admin/i', urldecode($_SERVER['REQUEST_URI'])) || preg_match('/admin=admin/i', urldecode($_SERVER['REQUEST_URI'])) || constant('redirectLinks') == false) && $ignoreAdmin == false){

			return $regularUrl;
		}

		if($model && $page && $retUrl){

			$retUrl = stripslashes($retUrl);
			$retUrl = str_replace('õ', 'o', $retUrl);
			$retUrl = str_replace('ü', 'u', $retUrl);
			$retUrl = str_replace('ä', 'a', $retUrl);
			$retUrl = str_replace('ö', 'o', $retUrl);
			$retUrl = str_replace('Õ', 'O', $retUrl);
			$retUrl = str_replace('Ü', 'U', $retUrl);
			$retUrl = str_replace('Ä', 'A', $retUrl);
			$retUrl = str_replace('Ö', 'O', $retUrl);
			$canonicalUrl = stripslashes($canonicalUrl);

			$this->Sql->table = 'redirect_link';
			$this->Sql->Numrows = 0;
			$row = $this->Sql->Query("SELECT SQL_CACHE * FROM redirect_link WHERE redirect_url = '".addslashes($retUrl)."' LIMIT 1 ", true);

			if($this->Sql->Numrows > 0 && stripslashes($row[0]['canonical_url']) != $canonicalUrl && is_numeric($row[0]['id'])){

				$this->Sql->Query("DELETE FROM redirect_link WHERE id = ".$row[0]['id']." ");
				$this->Sql->Query("INSERT DELAYED INTO redirect_link (canonical_url, redirect_url, `from`, created_at) VALUES ('".addslashes($canonicalUrl)."','".addslashes($retUrl)."', 'link', NOW()) ");
			}
			if($this->Sql->Numrows == 0){

				$this->Sql->Query("INSERT DELAYED INTO redirect_link (canonical_url, redirect_url, `from`, created_at) VALUES ('".addslashes($canonicalUrl)."','".addslashes($retUrl)."', 'link', NOW()) ");
			}
		}

		$retUrl = str_replace('&', '&amp;', $retUrl);
		$retUrl = str_replace("'", '&apos;', $retUrl);
		$retUrl = str_replace('"', '&quot;', $retUrl);
		$retUrl = str_replace('<', '&lt;', $retUrl);
		$retUrl = str_replace('>', '&gt;', $retUrl);

		return _RootUrl.'/'.$retUrl;
	}

	/**
	* it will redirect to current url
	* 
	* @param String $url
	*/
	function redirect($url){

		echo '<meta http-equiv="refresh" content="0; url='.$url.'">';
	}

	/**
	* same as redirect, but uses header('Location:$url')
	* 
	* @param String $url
	*/
	function location($url){

		die(header('Location: '.$url));
	}
	/**
	* trims each value in array
	* 
	* @param Array $array
	*/
	function trim($array){

		foreach($array as $k => $v){

			if(is_array($v))
				$array[$k] = $this->trim($v);
			else
				$array[$k] = trim($v);
		}
		return $array;
	}

	/**
	* striptags in array
	* 
	* @param Array $array
	*/
	function striptags($array){

		foreach($array as $k => $v){

			if(is_array($v))
				$array[$k] = $this->striptags($v);
			else
				$array[$k] = strip_tags($v);
		}
		return $array;
	}

	/**
	* implode data from array
	* 
	* @param Integer $i
	* @param Array $array
	* 
	* @example
	* foreach($array as $key, $value){
	* 
	* $arrayNew[] = $this->implode($key, $value);
	* }
	*/
	function implode($i, $array){

		$ret = array();
		if(is_array($array)){

			foreach($array as $k => $v){

				if(is_array($v))
					$ret[$k] = $v[$i];
			}
		}
		return $ret;
	}

	/**
	* \n\r to <br>
	* 
	* @param String $string
	*/
	function nl2br($string){

		$string = str_replace("\r", '', $string);
		$string = str_replace("\n", '<br/>', $string);

		$string = str_replace('\r', '', $string);
		$string = str_replace('\n', '<br/>', $string);
		return $string;
	}

	/**
	* <br> to \n
	* 
	* @param String $string
	*/
	function br2nl($string){

		$string = str_replace("<br/>", "\n", $string);
		return $string;
	}
}

?>