<?php
error_reporting(E_ALL & ~E_NOTICE);
//$ajConn = @new mysqli("127.0.0.1", "mydesiti_admin", "uK6c0Ig]6sSW", "mydesiti_db");
$ajConn = @new mysqli("127.0.0.1", "chilscott_prosentryuser", "6Po)EJcJd%?j", "chilscott_prosentry");
class CMS
{

	public $union;
	public $error;
	public $add;
	public $edit;
	public $delete;
	public $multiple;
	public $fkeys;
	public $fvals;
	public $getdata;
	public $condition;
	public $tables;
	public $unionAll;
	public $count;
	public $paging;
	public $pagevariable;
	public $items;
	public $fields;
	public $join;
	public $errHandler;
	public $sql;
	public $totalRows;
	public $numRows;
	public $output;
	public $NRfields;
	public $affected_rows;
	public $rowCount;
	public $insert_id;
	public $last_id;
	public $pagePrefix;
	public $page = 0;

	


    public static $Stables		= [];
    public static $Sunion		= [];
    public static $SunionAll	= [];		
	function __construct()
	{	
		$this->error 		= false;
		$this->add	 		= false;
		$this->edit 		= false;			
		$this->getdata 		= false;
		$this->delete		= false;
		$this->multiple 	= true;
		$this->fkeys 		= [];
		$this->fvals 		= [];			
		$this->condition	= '';	
		$this->page	= [];	
		if(sizeof((array)self::$Stables)>0)
		$this->tables = self::$Stables;
		else
		$this->tables 	= [];	
		$this->count 	= "*";
		$this->paging	= false;
		$this->pagevariable = "page";
		$this->items	= 10;
	} 
	
	public static function tables($table = [])
	{	
		self::$Stables = [];

		if(is_array($table)) 
		{
			if(sizeof((array)$table))
				foreach($table as $key=>$tbl)
					self::$Stables[] = $tbl;	
		}
		else
			self::$Stables[] = $table;

		return (new CMS());
	}
	
	public function fields($flds)
	{	
		if(is_array($flds))
		{
			if(sizeof((array)$flds))
				foreach($flds as $key=>$fld)
				{
					if(!is_numeric ($key))
					{
						$this->fkeys[] = $key;
						$this->fvals[] = $fld;
					}
					else
					{
						$this->fkeys[] = $fld;
						$this->fvals[] = '-';
					}
				}
	
		}
		else
		{
			$this->fkeys[] = $flds;
			$this->fvals[] = '-';
		}		
		return $this;
	}
	
	public function join($table,$on,$type='inner')
	{
		$this->join[] = strtoupper($type)." JOIN ".$table." t".(sizeof((array)$this->tables)+1+sizeof((array)$this->join))." ON ".$on;
		return $this;
	}	
	
	public function rightJoin($table,$on)
	{
		return $this->join($table,$on,'RIGHT');
	}	
		
	public function leftJoin($table,$on)
	{
		return $this->join($table,$on,'LEFT');
	}
		
	public function fullOuterJoin($table,$on)
	{
		return $this->join($table,$on,'FULL OUTER');
	}	
	
	public function condition($cdn)
	{
		$this->condition.= $cdn;
		return $this;
	}
	
	public function where($fld,$cdn=NULL,$val=NULL)
	{	
		if(!is_null ($cdn))
		$this->fkeys[] = $fld;
		else
		$this->fkeys[] = ((sizeof((array)$this->join))?'t1.':'').'id';
		
		$fCnt = sizeof((array)$this->fkeys);
		if(!is_null ($val)) {
			
			$this->fvals[] = $val;
			$this->condition.= "k".$fCnt.$cdn."v".$fCnt;
		}
		else {
			
			if(!is_null ($cdn))
				$this->fvals[] = $cdn;
			else
				$this->fvals[] = $fld;

			$this->condition.= "k$fCnt=v$fCnt";
		}	
		
		return $this;	
	}	
	
	public function andWhere($fld,$cdn=NULL,$val=NULL)
	{		
		if($this->condition!='')
		$this->condition.= " and ";
	
		$this->where($fld,$cdn,$val);
		return $this;
	}
	
	public function orWhere($fld,$cdn=NULL,$val=NULL)
	{
		if($this->condition!='')		
		$this->condition.= " or ";	
	
		$this->where($fld,$cdn,$val);
		return $this;
	}
	
	public function between($fld,$val1,$val2)
	{	
		global $ajConn;	
		
		$this->fkeys[] = $fld;
		$this->fvals[] = "'".@$ajConn->real_escape_string($val1)."' AND '".@$ajConn->real_escape_string($val2)."'(F)";		
		$fCnt = sizeof((array)$this->fkeys);

		$this->condition.= "(k".$fCnt." BETWEEN v".$fCnt.")";	
		
		return $this;	
	}
	
	public function andBetween($fld,$val1,$val2)
	{			
		if($this->condition!='')		
		$this->condition.= " and ";	
	
		$this->between($fld,$val1,$val2);
		return $this;	
	}
	
	public function orBetween($fld,$val1,$val2)
	{			
		if($this->condition!='')		
		$this->condition.= " or ";	
	
		$this->between($fld,$val1,$val2);
		return $this;	
	}	
	
	public function whereIn($fld,$vals,$cdn='IN')
	{
		global $ajConn;	
		$inVal = [];		
		if(@is_array($vals) && sizeof((array)$vals)) {

			foreach($vals as $ech) {
				
				if(@preg_match("/^(.*)\(F\)$/", $ech, $matches, PREG_OFFSET_CAPTURE))
				$inVal[] = $matches[1][0];			
				else
				$inVal[] = "'".@$ajConn->real_escape_string($ech)."'";
			}
			
			$this->fvals[] = "(".@implode(',',$inVal).")(F)";
		}
		else {
						
			if(@preg_match("/^(.*)\(F\)$/", $vals, $matches, PREG_OFFSET_CAPTURE))
			$vals = $matches[1][0];	
			else
			$vals = "'".@$ajConn->real_escape_string($vals)."'";		

			$this->fvals[] = "($vals)(F)";
		}
		
		$this->fkeys[] = $fld;
		
		$fCnt = sizeof((array)$this->fkeys);

		$this->condition.= "k".$fCnt." ".$cdn." v".$fCnt;	
		
		return $this;	
	}
	
	public function andWhereIn($fld,$vals)
	{			
		if($this->condition!='')		
		$this->condition.= " and ";	
	
		$this->whereIn($fld,$vals);
		return $this;	
	}
	
	public function orWhereIn($fld,$vals)
	{			
		if($this->condition!='')		
		$this->condition.= " or ";	
	
		$this->whereIn($fld,$vals);
		return $this;	
	}	
	
	public function whereNotIn($fld,$vals)
	{			
		$this->whereIn($fld,$vals,'NOT IN');
		return $this;	
	}
	
	public function andWhereNotIn($fld,$vals)
	{			
		if($this->condition!='')		
		$this->condition.= " and ";	
	
		$this->whereIn($fld,$vals,'NOT IN');
		return $this;	
	}
	
	public function orWhereNotIn($fld,$vals)
	{			
		if($this->condition!='')		
		$this->condition.= " or ";	
	
		$this->whereIn($fld,$vals,'NOT IN');
		return $this;	
	}	
	
	public function having($fld,$cdn='',$val=NULL)
	{	
		if (strpos($this->condition, ' HAVING ') === false)
			$this->condition.= ' HAVING ';	
		
		$this->fkeys[] = $fld;
		$fCnt = sizeof((array)$this->fkeys);
		if(!is_null ($val))
		{
			$this->fvals[] = $val;
			$this->condition.= "k".$fCnt.$cdn."v".$fCnt;
		}
		else
		{
			$this->fvals[] = $cdn;
			$this->condition.= "k$fCnt=v$fCnt";	
		}	
		
		return $this;	
	}
	
	public function andHaving($fld,$cdn='',$val=NULL)
	{		
		$this->andWhere($fld,$cdn,$val);
		return $this;
	}
	
	public function orHaving($fld,$cdn='',$val='')
	{		
		$this->orWhere($fld,$cdn,$val);
		return $this;
	}	
	
	public function isNULL($fld)
	{	
		global $ajConn;
		
		$this->fkeys[] = $fld;
		$this->fvals[] = '-';		
		$fCnt = sizeof((array)$this->fkeys);

		$this->condition.= "k".$fCnt." IS NULL ";	
		
		return $this;	
	}
	
	public function isNotNULL($fld)
	{	
		
		$this->fkeys[] = $fld;
		$this->fvals[] = '-';		
		$fCnt = sizeof((array)$this->fkeys);

		$this->condition.= "k".$fCnt." IS NOT NULL ";	
		
		return $this;	
	}	
	
	public function andIsNULL($fld)
	{	
		if($this->condition!='')
		$this->condition.= " and ";
	
		$this->isNull($fld);
		return $this;
	}
	
	public function andIsNotNULL($fld)
	{	
		if($this->condition!='')
		$this->condition.= " and ";
	
		$this->isNotNull($fld);
		return $this;	
	}
	
	public function orIsNULL($fld)
	{	
		if($this->condition!='')
		$this->condition.= " or ";
	
		$this->isNull($fld);
		return $this;
	}
	
	public function orIsNotNULL($fld)
	{	
		if($this->condition!='')
		$this->condition.= " or ";
	
		$this->isNotNull($fld);
		return $this;	
	}	
	
	public function orderBy($fld,$sort='asc')
	{		
		$this->fkeys[] = $fld;
		$this->fvals[] = $sort."(F)";		
		$fCnt = sizeof((array)$this->fkeys);

		$this->condition.= ((stripos(strtolower($this->condition), "order by ")===false)?" ORDER BY ":", ")."k".$fCnt." v".$fCnt;
		
		return $this;		
	}
	
	public function orderByRandom()
	{		
		$this->condition.= ((stripos(strtolower($this->condition), "order by ")===false)?" ORDER BY":",")." rand() ";		
		
		return $this;		
	}	
	
	public function groupBy($fld)
	{	
		$this->fkeys[] = $fld;
		$this->fvals[] = '-';		
		$fCnt = sizeof((array)$this->fkeys);

		$this->condition.= ((stripos(strtolower($this->condition), "group by ")===false)?" GROUP BY ":", ")."k".$fCnt." ";
		
		return $this;		
	}	
	
	public function limit($offset,$count=NULL)
	{
		$this->condition.= " LIMIT ".(int)$offset;
		
		if(!is_null ($count))	
			$this->condition.= ", ".(int)$count;	
		
		$this->condition.= " ";
		
		return $this;		
	}	
	
	public function select($select = [])
	{	
		if(is_array($select)) 
			$this->fields = $select;
		else
			$this->fields[] = $select;

		return $this;
	}
	
	public function first()
	{	
		$this->multiple = false;
		return $this;
	}	
	
	public function paginate($items,$pageVar = "")
	{
		$this->items = $items;
		
		if($pageVar!='')
			$this->pagevariable	= $pageVar;
	
		$this->paging = true;
		return $this;
	}
	
	public function toSql()
	{
		return $this->get(false);
	}	
	
	public function get($exec=true)
	{		
		$this->errHandler = debug_backtrace();
		
		$this->getdata	= true;
		$this->add		= false;
		$this->edit		= false;			
		$this->delete	= false;		
		return $this->manageCms($exec);
	}
	
	public function delete($exec=true)
	{
		$this->errHandler = debug_backtrace();
				
		$this->delete	= true;
		$this->add		= false;
		$this->edit		= false;			
		$this->getdata	= false;		
		return $this->manageCms($exec);
	}

	private function sanitizeData($val,$type)
	{	
		$type = strtoupper($type);
		switch($type)
		{
			case 'INT'://integer
			$val = (int)($val);
			break;
			
			case 'FLOAT'://float
			$val = (float)($val);
			break;
			
			case 'HTML'://html
			$val = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $val);
			break;			
			
			default:
			if($type!="HTML")
			$val = htmlentities($val,  ENT_QUOTES | ENT_IGNORE, 'UTF-8');											
		}
        return $val;	
	}
	
	private function sanitizeRequest($key,$type)
	{
		if(@is_array($_REQUEST[$key]))
		{
			if(sizeof((array)$_REQUEST[$key]))
				foreach($_REQUEST[$key] as $ky=>$vl)
					$_REQUEST[$key][$ky] = $this->sanitizeData($_REQUEST[$key][$ky],$type);
		}
		else
		$_REQUEST[$key] = $this->sanitizeData($_REQUEST[$key],$type);
	}		
	
	public function sanitize($data,$type='string')
	{
		$this->errHandler = debug_backtrace();

		if(@is_array($data))
		{
			if(sizeof((array)$data))
				foreach($data as $key=>$val)
				{
					if(!is_numeric ($key))
						$this->sanitizeRequest($key,$val);
					else
						$this->sanitizeRequest($val,$type);
				}
		}
		else		
			$this->sanitizeRequest($data,$type);
	
		return $this;	
	}	

	private function setData($data,$exec)
	{	
		$this->fields = [];
		if(sizeof((array)$data))
			foreach($data as $key=>$fld)
			{
				if(!is_numeric ($key))
				{
					$this->fields[] = $key;
					$this->NRfields[$key] = $fld;
				}
				else
				$this->fields[] = $fld;
			}
			
		return $this->manageCms($exec);
	}
	
	public function insert($data,$exec=true)
	{
		$this->errHandler = debug_backtrace();
				
		$this->add		= true;
		$this->edit		= false;			
		$this->getdata	= false;
		$this->delete	= false;		
		return $this->setData($data,$exec);
	}	
	
	public function update($data,$exec=true)
	{
		$this->errHandler = debug_backtrace();
				
		$this->edit		= true;
		$this->add		= false;			
		$this->getdata	= false;
		$this->delete	= false;		
		return $this->setData($data,$exec);
	}	
		
	private function manageCms($exec=true)
	{		
		global $ajConn;		
		$this->page	= isset($_GET[$this->pagevariable])?(int)$_GET[$this->pagevariable]:0;
		if($this->page == "" || $this->page == 0)
		$this->page = 1;
		
		$tablesNm = $this->getTables();
		
		if($this->fkeys!="")
		{		
			if(sizeof((array)$this->fkeys)!=sizeof((array)$this->fvals))
			$this->reportErr("Count for field keys and values should match.");
			else
			$append_query = $this->genCondition();			
		}		
		
		if($this->edit)
		{
			$cnt = 0;
			foreach($this->fields as $itm)
			{
				if(preg_match("/^t[0-9]+\.(.*)/",$itm, $matches))
				{
					$fieldNm = $itm;
					$tmpEdtVal = $_REQUEST[$matches[1]];
				}
				else
				{
					$fieldNm = ("`".$itm."`");
					$tmpEdtVal = $_REQUEST[$itm];					
				}
				
				if(isset($this->NRfields) && @array_key_exists($itm, $this->NRfields) && @preg_match("/^(.*)\(F\)$/", ($this->NRfields[$itm]), $matches, PREG_OFFSET_CAPTURE))
				$val[]			= $fieldNm.'='.$matches[1][0];
				else
				{
					$tmpVals 	= (($this->NRfields) && @array_key_exists($itm, $this->NRfields))?$this->NRfields[$itm]:$tmpEdtVal;
					$val[] 		= $fieldNm.'="'.$ajConn->real_escape_string(($tmpVals)).'"';						
				}
				$cnt++;		
			}
			
			if($this->error=="")
			{
				$sql		= "update ".$tablesNm." set ".(implode(",", $val)).$append_query;
				$this->sql	= $sql;
				
				if($exec)
				{
					$rs = $ajConn->query($sql);  	
	
					if($ajConn->error)
					$this->reportErr('SQL Error: "'.$ajConn->error.'"<br/>');
					else
					return $this->affected_rows = $ajConn->affected_rows;	
				}
				else
				return $this->sql;
			}		

		}
		
		if($this->add)
		{	
			$cnt = 0;			
			foreach($this->fields as $itm)
			{
				$fld[] = "`".$itm."`";

				if(isset($this->NRfields) && @array_key_exists($itm, $this->NRfields) && @preg_match("/^(.*)\(F\)$/", ($this->NRfields[$itm]), $matches, PREG_OFFSET_CAPTURE))
				$val[]			= $matches[1][0];
				else
				{
					$tmpVals	= (($this->NRfields) && @array_key_exists($itm, $this->NRfields))?$this->NRfields[$itm]:$_REQUEST[$itm];
					$val[]		= '"'.@$ajConn->real_escape_string(($tmpVals)).'"';						
				}
				$cnt++;				
			}
			
			if($this->error=="")
			{
				$sql		= "insert into ".$tablesNm." (".(implode(",", $fld)).") values (".(implode(",", $val)).")";
				$this->sql	= $sql;
				
				if($exec)
				{				
					$rs = @$ajConn->query($sql);
					
					if($ajConn->error)
					$this->reportErr('SQL Error: "'.$ajConn->error.'"<br/>');	
					else
					return $this->insert_id = $this->last_id = $ajConn->insert_id;	
				}
				else
				return $this->sql;				
			}			
		}
		
		if($this->getdata)
		{
			$cnt = 0;
			if(sizeof((array)$this->fields)>0)
			{			
				foreach($this->fields as $itm)
				{
					if(preg_match("/^[a-zA-Z0-9_]+$/",$itm))
					$fld[] = "`".$itm."`";	
					else
					$fld[] = $itm;	
					
					$cnt++;				
				}
				$getFields = (implode(",", $fld));
			}
			else
			$getFields = "*";			

			if($this->paging)
			{					
				$start = $this->items * ($this->page-1);
				$append_query .= " LIMIT ".$start.",".$this->items;
			}
			else			
				if(!$this->multiple)
				$append_query .= " LIMIT 0,1";					

			$sql="select".(($this->paging)?" SQL_CALC_FOUND_ROWS":"")." ".$getFields." from ".$tablesNm.$append_query;
			$this->sql = $sql;
			
			if($exec)
			{			
				$rs = @$ajConn->query($sql);
							
				if(@$ajConn->error)
				$this->reportErr('SQL Error: "'.@$ajConn->error.'"<br/>');
	
				if($this->paging)
				{		
					$numres = @$ajConn->query("Select FOUND_ROWS()");
					$numrow = $numres->fetch_array(MYSQLI_ASSOC);
					$this->totalRows = $this->rowCount = $numrow["FOUND_ROWS()"];
				}
				else
				$this->totalRows = $rs->num_rows;
				$this->numRows   = $rs->num_rows;			
				
				if(@$rs->num_rows>0)			
				if(!@$ajConn->error && $this->error=="")
				{		
					if($this->multiple)
					{
						while($rw = $rs->fetch_array(MYSQLI_ASSOC))
						$this->output[] = $rw;	
						return $this->output;
					}
					else
					{
						$rw = $rs->fetch_array(MYSQLI_ASSOC);	
						return $this->output = $rw;
					}
				}
			}
			else
			return $this->sql;			
		}
		
		if($this->delete)
		{
			$delTable = "";
			
			if(sizeof((array)$this->fields)>0)
			{		
				foreach($this->fields as $itm)
				{
					if(preg_match("/^t[0-9]+$/",$itm))
					$fld[] = $itm ;					
					$cnt++;				
				}
				if(sizeof((array)$fld)>0)
				$delTable = (implode(",", $fld)).' ';
			}
						
			$sql		= "delete ".$delTable." from ".$tablesNm.$append_query;
			$this->sql	= $sql;
			
			if($exec)
			{			
				$rs = @$ajConn->query($sql);
				
				if($ajConn->error)
				$this->reportErr('SQL Error: "'.$ajConn->error.'"<br/>');
				else
				return $this->affected_rows = $ajConn->affected_rows;
			}
			else
			return $this->sql;	
			
		}
	//	echo "lll".$sql;
	}

	function getTables()
	{
		global $ajConn;	
				
		$tmpTble = '';
		if(sizeof((array)$this->tables)>1)
		{
			for($i=0;$i<sizeof((array)$this->tables);$i++)
			{
				if(@preg_match("/^\((.*)\)$/", trim($this->tables[$i]), $matches, PREG_OFFSET_CAPTURE))
					$tmpTble.= "(".trim($matches[1][0]).") AS t".($i+1);
				else
					$tmpTble.= $ajConn->real_escape_string(trim($this->tables[$i]))." AS t".($i+1);
			
				if($i!=(sizeof((array)$this->tables)-1))					
				$tmpTble.=", ";
			}
		}
		else
		{
			if(@preg_match("/^\((.*)\)$/", trim($this->tables[0]), $matches, PREG_OFFSET_CAPTURE))
				$tmpTble = "(".trim($matches[1][0]).")".(($this->add || ($this->delete && !sizeof((array)$this->join)))?'':" AS t1");	
			else	
				$tmpTble = @$ajConn->real_escape_string(trim($this->tables[0])).(($this->add || ($this->delete && !sizeof((array)$this->join)))?'':" AS t1");
		}	

		if(sizeof((array)(array)$this->join)>0 && !$this->add)
		$tmpTble.= " ".@implode(" ",$this->join);
	
		return $tmpTble;
	}
	
	function genCondition()
	{	
		global $ajConn;	
		
		if($this->condition!="")
		{			
			if((stripos($this->condition, "where ")<=5 && stripos($this->condition, "where ")!==false) || (stripos($this->condition, "order by ")<=5 && stripos($this->condition, "order by ")!==false) || (stripos($this->condition, "group by ")<=5 && stripos($this->condition, "group by ")!==false) || (stripos($this->condition, "having ")<=5 && stripos($this->condition, "having ")!==false) || (stripos($this->condition, "limit ")<=5 && stripos($this->condition, "limit ")!==false))																		
			$this->condition = " ".$this->condition;
			else	
			$this->condition = " where ".$this->condition;
								
			for($i=sizeof((array)$this->fkeys);$i>0;$i--)
			{
				$this->condition = str_replace("k".($i), "#)!".$i."!(#", $this->condition);
				$this->condition = str_replace("v".($i), "!)#".$i."#(!", $this->condition);
			}
								
			for($i=sizeof((array)$this->fkeys);$i>0;$i--)
			$this->condition = str_replace("#)!".$i."!(#", $this->fkeys[$i-1], $this->condition);																
			
			for($i=sizeof((array)$this->fvals);$i>0;$i--)
			{
				if(@preg_match("/^(.*)\(F\)$/", ($this->fvals[$i-1]), $matches, PREG_OFFSET_CAPTURE))
				$this->condition = str_replace("!)#".$i."#(!", $matches[1][0], $this->condition);	
				else
				$this->condition = str_replace("!)#".$i."#(!", "'".(@$ajConn->real_escape_string($this->fvals[$i-1]))."'", $this->condition);	
			}
		}
		else
		{
			if(sizeof((array)$this->fkeys))
			{
				for($icd=0; $icd<sizeof((array)$this->fkeys); $icd++)
				{
					if(@preg_match("/^(.*)\(F\)$/", ($this->fvals[$icd]), $matches, PREG_OFFSET_CAPTURE))
					$this->condition.= (($icd!=0)?" and ":" where ")."`".$this->fkeys[$icd]."`=".@$ajConn->real_escape_string($matches[1][0]);				
					else					
					$this->condition.= (($icd!=0)?" and ":" where ")."`".$this->fkeys[$icd]."`='".@$ajConn->real_escape_string($this->fvals[$icd])."'";
				}				
			}	
		}
		return $this->condition;		
	}
	
	
	function validate($phrase,$type,$string='')
	{
		global $ajConn;			
		$this->errHandler = debug_backtrace();
		
		$err_sts = true;
		
		if($string=='' && $phrase=='custom')
		{
			$string = $type;
			$type = $phrase;
			$phrase = '';
		}
		
		if($_POST)
		switch($type)
		{
			
			case "name":
				if(!$err_sts = preg_match("/^[a-zA-Z .'\-]{2,50}$/", $phrase))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;
			
			case "phone":
				if(!$err_sts = preg_match("/^[0-9 .'\-\+,]{10,50}$/", $phrase))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;			
			
			case "username":
				if(!$err_sts = preg_match("/^[a-z0-9_.\.-]{2,25}$/", $phrase))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;	
			
			case "password":
				if(!$err_sts = preg_match("/^[a-zA-Z0-9]{2,50}$/", $phrase))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;						
			
			case "email":
				if(!$err_sts = (bool)filter_var($phrase, FILTER_VALIDATE_EMAIL))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;	
			
			case "address":
				if(!$err_sts = (strlen($phrase)<=255))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;
			
			
			case "null":			
			case "not null":
				if(!$err_sts = ($phrase!=""))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;
			
			
			case "price":
			case "amount":					
			case "numeric":			
				if(!$err_sts = is_numeric($phrase))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;					
			
			
			case "no":
			case "number":	
			case "integer":	
				if(!$err_sts = (bool)(filter_var($phrase, FILTER_VALIDATE_INT) || $phrase=='0'))
				{
					$this->error.= ucfirst($string)."<br/>";
				}			
			break;		
			
			
			case "exists":
				
				$append_query = $this->genCondition();

				if(preg_match("/^t[0-9]+\.(.*)/",$phrase[0], $matches))
					$phrase[0] = $phrase[0];
				else
					$phrase[0] = ("`".$phrase[0]."`");				
				
				if(stripos($append_query, "where ")<=5 && stripos($append_query, "where ")!==false)									
				$append_query = preg_replace("/where /","where ".$phrase[0]."='".$ajConn->real_escape_string($phrase[1])."' and ",$append_query, 1);				
				else
				$append_query = ' where '.$phrase[0].'="'.$ajConn->real_escape_string($phrase[1]).'" '.$append_query;
				
				$tablesNm = $this->getTables();
				$sql="select ".$phrase[0]." from ".$tablesNm.$append_query;
				$this->sql = $sql;
				$rs = $ajConn->query($sql);
				
				if(!$err_sts = ($rs->num_rows<1))
				$this->error.= ucfirst($string)."<br/>";
		
			break;			
			
			
			case "compare":
				if(!$err_sts = ($phrase[0]==$phrase[1]))
				{	
					$this->error.= ucfirst($string)."<br/>";
				}		
			break;	
			
			
			case "pattern":
				if(!$err_sts = preg_match("/".$phrase[1]."/",$phrase[0]))
				{
					$this->error.= ucfirst($string)."<br/>";
				}	
			break;
			
			
			case "patterni":
				if(!$err_sts = preg_match("/".$phrase[1]."/i",$phrase[0]))
				{
					$this->error.= ucfirst($string)."<br/>";
				}	
			break;				
			
			
			case "date":
				if((@is_array($phrase) && sizeof((array)$phrase)==2) || (!@is_array($phrase) && $phrase!=''))	
				{
					if((@is_array($phrase) && sizeof((array)$phrase)==2))
					{
						if(!$err_sts = $this->validateDate($phrase[0], $phrase[1]))
						$this->error.= ucfirst($string)."<br/>";
					}
					else
					{
						if(!$err_sts = !$this->validateDate($phrase))
						$this->error.= ucfirst($string)."<br/>";						
					}
				}
	
			break;
			
			
			case "compareDate":
				if($err_sts = (@is_array($phrase) && sizeof((array)$phrase)==4 && ($this->validateDate($phrase[0], $phrase[3]) || strtolower($phrase[0])=="now") && ($this->validateDate($phrase[2], $phrase[3]) || strtolower($phrase[2])=="now")))
				{
					$dte1Fmt = (strtolower($phrase[0])=='now')?@date('Y-m-d'):$this->dateFormat($phrase[0],$phrase[3],"2DB");					
					$compDte1 = new DateTime($dte1Fmt);
					$dte2Fmt = (strtolower($phrase[2])=='now')?@date('Y-m-d'):$this->dateFormat($phrase[2],$phrase[3],"2DB");					
					$compDte2 = new DateTime($dte2Fmt);
				
					switch($phrase[1])
					{
						case "!=":
						case "!==":								
						case "<>":												
						$err_sts = ($compDte1 != $compDte2);					
						break;
						
						case "<":												
						$err_sts = ($compDte1 < $compDte2);					
						break;
						
						case "<=":
						case "=<":																		
						$err_sts = ($compDte1 <= $compDte2);					
						break;	
						
						case ">":												
						$err_sts = ($compDte1 > $compDte2);					
						break;
						
						case ">=":
						case "=>":																		
						$err_sts = ($compDte1 >= $compDte2);					
						break;																									
												
						case "=":						
						case "==":
						case "===":	
						default:
						$err_sts = ($compDte1 == $compDte2);					
						break;
					}

				}			

				if(!$err_sts)						
				$this->error.= ucfirst($string)."<br/>";				

			break;			
			
			
			case "custom":
				if($phrase=='')
				{	
					$this->error.= ucfirst($string)."<br/>";
				}
	
			break;									
			
		}
		
		return $err_sts;		
	}
	
	function reportErr($msg)
	{
		$msg = "<b>Error:</b> ".$msg." <br>in <b>".$this->errHandler[0]["file"]."</b> on line <b>".$this->errHandler[0]["line"]."</b>";
		exit($msg);
	}
		
	function showMsg($msgText='',$msgTitle='',$msgType='')
	{
		if($msgText!="" || $this->error!="" || @$_REQUEST["success"]!="" || @$_REQUEST["error"]!="" || @$_REQUEST["warning"]!="" || @$_REQUEST["info"]!="")
		{
			if($msgType=='')
			{
				if($_REQUEST["success"]!='')
				$msgType = "success";
				
				if($_REQUEST["error"]!='')
				$msgType = "danger";
					
				if($_REQUEST["warning"]!='')
				$msgType = "warning";
				
				if($_REQUEST["info"]!='')
				$msgType = "info";	
				
				if($_REQUEST["success"]=='' && $_REQUEST["error"]=='' && $_REQUEST["warning"]=='' && $_REQUEST["info"]=='')	
				$msgType = "info";						
			}
			if($msgText=='')
			{
				if($_REQUEST["success"]!='')
				$msgText = $_REQUEST["success"];
				
				if($_REQUEST["error"]!='')
				$msgText = $_REQUEST["error"];
					
				if($_REQUEST["warning"]!='')
				$msgText = $_REQUEST["warning"];
				
				if($_REQUEST["info"]!='')
				$msgText = $_REQUEST["info"];								
			}			
			
			echo '
            <div class="alert alert-'.(($this->error!='')?'danger':$msgType).' alert-dismissible" role="alert">
				<button type="button" class="close" data-dismiss="alert">
                <span aria-hidden="true">&times;</span><span class="sr-only">Close</span>
                </button>';
				
			if($msgTitle!="")
			echo '<strong>'.$msgTitle.'</strong>';
			 
			if($msgTitle=="" && $this->error!="")
			echo '<strong>Error(s)</strong>'; 
			
			echo '<p>'; 				           

			if($this->error!="")
			echo $this->error;							
			else
			echo $msgText;	
			
			
			echo '</p>'; 			
			echo '
            </div>';			
		}
	}
	
	function ajPage()
	{
		global $ajConn;			
		$rs = $ajConn->query(current(explode(" limit ",$this->sql)));
		
		if($ajConn->error)
		$this->reportErr('SQL Error: "'.$ajConn->error.'"<br/>');
		
		$totalCnt = $rs->num_rows;
	}
		
	
	function sendEmail()
	{
		$this->errHandler = debug_backtrace();
		
		if($this->template!="" && $this->sendTo!="" && $this->sendFrom!="" && $this->subject!="" && sizeof((array)$this->keywords))
		{
			$content = file_get_contents($this->template);
			
			foreach($this->keywords as $key=>$val)
			$content = str_replace("|@|".$key."|@|",$val,$content);

			$headers  = "MIME-Version: 1.0\r\n";
			$headers .= "Content-type: text/html;  charset=UTF-8\r\n";
			if($this->companyName!='')
			$headers .= "Organization:".$this->companyName."\r\n";
		
			$headers .= "To:<".stripslashes(filter_var($this->sendTo, FILTER_SANITIZE_EMAIL)).">\r\n";			
			$headers .= "From:".stripslashes(($this->sendName!="")?$this->sendName:"")."<".stripslashes(filter_var($this->sendFrom, FILTER_SANITIZE_EMAIL)).">\r\n";		
			$headers .= "Reply-To:".stripslashes(($this->sendName!="")?$this->sendName:"")."<".stripslashes(filter_var($this->sendFrom, FILTER_SANITIZE_EMAIL)).">\r\n";
			$headers .= "Return-Path:".stripslashes(($this->sendName!="")?$this->sendName:"")."<".stripslashes(filter_var($this->sendFrom, FILTER_SANITIZE_EMAIL)).">\r\n";
			
			if($this->Cc!='')
			$headers .= "Cc:<".stripslashes(filter_var($this->Cc, FILTER_SANITIZE_EMAIL)).">\r\n";	
			
			if($this->Bcc!='')
			$headers .= "Bcc:<".stripslashes(filter_var($this->Bcc, FILTER_SANITIZE_EMAIL)).">\r\n";

			$headers .= "X-Priority: 3\r\n";
			$headers .= "X-Mailer: PHP". phpversion() ."\r\n" ;		
			
			@mail(filter_var($this->sendTo, FILTER_SANITIZE_EMAIL), $this->subject, str_replace(array("\r\n", "\n", "\r"),array("", "", ""),stripslashes($content)), $headers);
			$this->content = stripslashes($content);
			
		}
		else
		$this->error.= "Some required fields are missing.<br/>";
	}	
	
	
	function dateFormat($date,$format,$type='2DB',$time=false)
	{
		if($date!='' && $format!='')
		{
			switch($type)
			{
				case "2DT": //TO DATE FORMAT
				$this->errHandler = debug_backtrace();	  
				$temp = explode(" ",$date);
				$date = explode("-",$temp[0]);
				$time = explode(":",($temp[1]!="")?$temp[1]:"00:00:00");
				return date($format, @mktime($time[0], $time[1], $time[2], $date[1], $date[2], $date[0]));
				break;
		
				case "2DB":	//TO DB FORMAT
				$this->errHandler = debug_backtrace();	  
				$myDateTime = DateTime::createFromFormat($format, $date);
				return $myDateTime->format(($time)?'Y-m-d H:i:s':'Y-m-d');
				break;
			}
		}
		else
		return '';
		
	}
	
		
	function validateDate($date, $format = 'Y-m-d H:i:s')
	{
		$d = DateTime::createFromFormat($format, $date);
		return $d && $d->format($format) == $date;
	}		
	
	
	function toRequest($output)
	{
		if(!$this->multiple)
		{
			if(@is_array($output))
			foreach($output as $key=>$val)
			{
				unset($_REQUEST[$key]);
				$_REQUEST[$key] = @stripslashes($val);
			}
		}
		else
		{
			if(sizeof((array)$output))
			{
				$cnt = 0;
				foreach($output as $arr)
				{
					if(is_array($arr))
					{
						if($cnt==0)
						foreach($arr as $key=>$val)
						unset($_REQUEST[$key]);
						
						foreach($arr as $key=>$val)
						$_REQUEST[$key][$cnt] = @stripslashes($val);				
						$cnt++;
					}
				}
			}
		}	
	}
	
	
	function pager($url='')
	{
		$pageURL = ($url=='')?$_SERVER['REQUEST_URI']:$url;
		$urlGet = preg_replace('/&?'.$this->pagevariable.'\=[0-9]+/i', '', $pageURL).(preg_match("/\\?/",$pageURL)?'&':'?');
		
		$last = ceil($this->rowCount/$this->items);		
		$page = ($this->page>$last)?$last:(($this->page<1)?1:$this->page);
		$previous = $this->page - 1;
		$next = $this->page + 1;
		
		
		
		?>
		<ul class="pagination no-margin pull-right">
		<?php

			// Check if on page 1	  
			if($this->page == 1)
			{ 
				?>
				<li class="disabled"><a>|< <span class="hidden-xs">First</span></a></li>
				<li class="disabled"><a>< <span class="hidden-xs">Prev</span></a></li>
				<?php
			}
			else
			{
				?>
				<li><a href="<?php echo $urlGet.$this->pagevariable."=1"?>">|< <span class="hidden-xs">First</span></a></li>
				<li><a href="<?php echo $urlGet.$this->pagevariable."=".$previous?>">< <span class="hidden-xs">Prev</span></a></li>
				<?php	
			}


			// For showing nearest 2 page numbers			
			for($i = ((($page-2)<1)?1:($page-2)); $i <= ((($page+2)>$last)?$last:($page+2)); $i++)
			{
				?>
				<li <?php echo ($page==$i)?'class="active"':''?>>
				<a href="<?php echo $urlGet.$this->pagevariable."=".$i?>"><?php echo $i?></a>
				</li>
				<?php
			}

			//Check if on last pages
			if($page == $last)
			{ 
				?>
				<li class="disabled"><a><span class="hidden-xs">Next</span> ></a></li>
				<li class="disabled"><a><span class="hidden-xs">Last</span> >|</a></li>
				<?php
			}
			else
			{
				?>
				<li><a href="<?php echo $urlGet.$this->pagevariable."=".$next?>"><span class="hidden-xs">Next</span> ></a></li>
				<li><a href="<?php echo $urlGet.$this->pagevariable."=".$last?>"><span class="hidden-xs">Last</span> >|</a></li>
				<?php	
			}			

	   
	   ?>
	   </ul>
	   <?php

	}
}	

class Storage
{
	
	public static function local()
	{
		$SObj			=  (new Storage());		
		$SObj->local	=	true;
		return  $SObj;		
	}	
	
	public static function FTP($server,$username,$password)
	{
		$SObj			=	(new Storage());		
		$SObj->FTPconn	=	@ftp_connect($server) or die("Could not connect to $server");
		$login			=	@ftp_login($SObj->FTPconn, $username, $password);	
		return  $SObj;
	}
	
	public function save($fname,$content,$path="",$mode="w+")
	{
		if($this->local) {
						
			if($path!="" && substr($path, -1)!='/') $path.= "/";
				$splitPath = explode('/',$path);
			
			$currPath = '';
			for($i=0; $i<(sizeof((array)$splitPath)-1);$i++) {
				
				$currPath.= $splitPath[$i].'/';
				
				if(!is_dir($currPath)) 
					@mkdir($currPath, 0777);	
			}

			$file = fopen($currPath.$fname,$mode);
			fwrite($file,$content);
			fclose($file);
		}		
	}
	
	public function put($data)
	{
		$upldSts = true;
		
		if(is_array($data)) {
			
			if(sizeof((array)$data)) {
				
				foreach($data as $each) {
					
						if(is_array($each)) {
							if(sizeof((array)$each)==2)						
								if(@is_file($each[0]))
									if (!@ftp_put($this->FTPconn, $each[1], $each[0], FTP_ASCII))
										$upldSts = false;
						}
						else {
							
							if(@is_file($each))
								if (!@ftp_put($this->FTPconn, basename($each), $each, FTP_ASCII))
									$upldSts = false;
						}
				}
			}
			else
			$upldSts = false;
		}
		else {
			
			if(@is_file($data)) {
				
				if (!@ftp_put($this->FTPconn, basename($data), $data, FTP_ASCII))
					$upldSts = false;
			}	
			else
			$upldSts = false;				
		}
		@ftp_close($this->FTPconn);

		return $upldSts;
	}	
	
	public function delete($path)
	{		
		if($this->local) {
			
			if (is_dir($path) === true) {
				
				$files = array_diff(scandir($path), array('.', '..'));
				
				if(sizeof((array)$files)) {
					
					foreach ($files as $file)
					self::delete(realpath($path) . '/' . $file);
				}
		
				return rmdir($path);
			}	
			else if (is_file($path) === true)
			return @unlink($path);
		
			return false;
		}

		if($this->FTPconn) {
			
			$deleteSts = true;		
			
			if(is_array($path)) {
				
				if(sizeof((array)$path))				
					foreach($path as $each)
						if(!@ftp_delete($this->FTPconn, $path))
							$deleteSts = false;
			}
			else
				$deleteSts = @ftp_delete($this->FTPconn, $path);	
			
			@ftp_close($this->FTPconn);			
			return $deleteSts;
		}		
	}
	
	//Get the list of files and folders from a folder
	private static function getfilesNfolder($source,$dirPath=false)
	{
		$fileList = [];
		
		if($dirPath!==false) {
			
		}		
		
		$stripLen = strlen($source)-1;		
		if ($handle = opendir($source)) {
			
			while (false !== ($entry = readdir($handle))) {
				
				if ($entry != "." && $entry != ".." && !strstr($entry,'.php')) {
					
					$filePath = "$source$entry";				
					$localPath = substr($filePath,$stripLen+1);	
					
					if(is_file($filePath)) 
						$fileList[] = $filePath;
					
					

					if(is_dir($filePath)) { 
						
						if($dirPath!==false)
							$localPath = $dirPath.'/'.$localPath;
					
						$fileList[$localPath] = self::getfilesNfolder($filePath.'/',$localPath);
					}						
				}
			}
			closedir($handle);
		}

		return $fileList;
	}
	
	//Zip files & folders
	private static function zipAddFile($zObj,$fileList,$srcLen)
	{

		if(sizeof((array)$fileList))
			foreach($fileList as $key=>$ech) {
				
				if(!is_array($ech))
					$zObj->addFile($ech,substr($ech,$srcLen));
				else {
					
					$zObj->addEmptyDir($key);					
					self::zipAddFile($zObj,$ech,$srcLen);
				}					
			}
	}	
	
	//Zip files & folders
	public static function createZip($zipname,$source)
	{
		$z = new ZipArchive();
		$z->open($zipname, ZIPARCHIVE::CREATE);
		
		$fileList = [];
		if(is_string($source)) {
			
			if($source!="" && substr($source, -1)!='/') $source.= "/";
			
			$fileList = self::getfilesNfolder($source);		
			self::zipAddFile($z,$fileList,strlen($source));			
		}
		else {
			
			if(sizeof((array)$source))
				foreach($source as $each) {
					
					if(is_array($each)) {
						if(sizeof((array)$each)==2)
							$z->addFile($each[0],$each[1]);	
					}
					else
					$z->addFile($each,basename($each));	
				}				
		}
		$z->close();		
	}

}
?>