<?php

class cData extends cApp {
	
	public $oDb, $oDbDef, $oUrl, $oSession, $oForm, $oMenu, $oFunctions, $pluginPath, $pluginURL;
	public $primaryTable, $primaryKey, $iId, $query, $zebraCounter, $row, $countRows;
	public $action, $MSG, $formError;
	public $searchDb, $readFormInPP;
	protected $workingID;
	private $dataFields, $dbFields, $fieldSeparator;
	
	function __construct($oDb, $oUrl, $oSession, $action) {
		/*if (is_array($oDb)) {
			$this->oDb = $oDb[1];
			$this->oDbDef = $oDb[0];
		} else*/
			$this->oDb = $this->oDbDef = $oDb;
		$this->oUrl = $oUrl;
		$this->oSession = $oSession;
		parent::__construct();
		$this->oForm = new cForm(" &nbsp; ", $this->cfg['button_reset'], $this->cfg['button_back']);
		$this->oMenu = new cMenu($this->oDbDef, $this->oUrl);
		$this->oFunctions = new cFunctions($this->oDb, $this->oUrl, $this->oSession, $this->oForm);
		$this->action = $action;
		$this->searchDb = Array();
		$this->dataFields = "";
		$this->dbFields = Array();
		$this->row = Array();
		$this->countRows = 0;
		$this->MSG = "";
		$this->formError = FALSE;
		$this->readFormInPP = FALSE;
		$this->filterErrorMessages = Array();
		$this->fieldSeparator = $this->cfg['field_separator'];
		$this->pluginPaths();
		$this->sessionBuild();
	}
	
	function __set($name, $value) {
		if ($this->dbFields && in_array($name,$this->dbFields[$this->primaryTable])) {
			if (!get_magic_quotes_gpc())
				$value = addslashes($value);
			if (!is_null($value))
				$value = "'".$value."'";
			else
				$value = "NULL";
			if ($this->langActive()) {
				$ar = $this->multilangKeysGet();
				if (@$ar[$this->primaryTable][$name])
					$name .= "_".$this->lang;
			}
			$sql = "UPDATE `".$this->primaryTable."` SET `".$name."` = {$value}
				WHERE `".$this->primaryKey."` = '".$this->workingID."'";
			$this->oDb->query($sql);
			
		}
	}
	
	final function pluginPaths() {
		if ($this->moduleType != "core") {
			$this->pluginPath = $this->path['plugins'];
			$this->pluginURL = $this->path['plugins_url'];
		} else {
			$this->pluginPath = $this->path['core_plugin'];
			$this->pluginURL = $this->path['core_plugin_url'];
		}
		$this->pluginPath .= $this->childClass . "/";
		$this->pluginURL .= $this->childClass . "/";
	}
	
	protected function tableHead($caption, $array, $operations = TRUE) {
		$this->zebraCounter = 0;
		$string = '<table cellspacing="1" cellpadding="0">'."\n";
		if (strlen($caption) > 0)
			$string .= '		<caption>'.$caption.'</caption>'."\n";
		$string .= '	<tr>'."\n";
		for ($i=0;$i<count($array);$i++)
			$string .= '		<th>'.$array[$i].'</th>'."\n";
		if ($operations)
			$string .= '		<th></th>'."\n";
		$string .= '	</tr>'."\n";
		return $string;
	}
	
	final function tableEnd() {
		return '</table>'."\n";
	}
	
	protected function inTable($array, $id, $operations = TRUE, $specialClass = false) {
		$className = fmod($this->zebraCounter,2) == 0 ? 'zebra' : 'cebra';
		
		if ($specialClass) {
			$className .= ' '.$specialClass;
		}
		
		$string = '	<tr class="'.$className.'">'."\n";
		for ($i=0;$i<count($array);$i++)
			$string .= '		<td>'.$array[$i].'</td>'."\n";
		if ($operations)
			$string .= '		<td class="buttons">'.$this->buttons($id).'</td>'."\n";
		else
			$string .= '		<td class="buttons">&nbsp;</td>'."\n";
		$string .= '	</tr>'."\n";
		$this->zebraCounter++;
		return $string;
	}
	
	protected function buttons($id, $anotherButtons = "") {
		$pageID = $this->oMenu->getID($this->oUrl->page);
		$fullWrite = $this->hasRights("can_write", $pageID, 0);
		if ($this->oUrl->action || $fullWrite);
		else {
			$addRights = $this->oSession->getRights($pageID, $id);
			foreach ($addRights[$pageID][$id] as $key => $val)
				$this->rights[$pageID][$id][$key] = $val;
		}
		$ret = "";
		if ($this->hasRights("can_write", $pageID, $id) || $fullWrite) {
			$ret = $this->buttonEdit($id);
			$ret .= $this->buttonDelete($id);
		}
		$ret .= $anotherButtons;
		return $ret;
	}
	
	protected function buttonEdit($id,$valueOverride="",$extraHidden="") {
		$valueOverride = empty($valueOverride) ? $this->cfg['button_edit'] : $valueOverride;
		$string = '	<input type="hidden" name="action" value="edit" /><input type="hidden" name="id" value="'.$id.'" /><input type="hidden" name="table" value="'.$this->primaryTable.'" />'."\n";
		$string .= '	<input type="hidden" name="submit" value="Edit" />'.$extraHidden.'<input type="submit" name="sub" value="'.$valueOverride.'" class="submit input_edit" />'."\n";
		return $this->HTMLForm($string);
	}
	
	protected function buttonDelete($id) {
		$string = '	<input type="hidden" name="action" value="delete" /><input type="hidden" name="id" value="'.$id.'" /><input type="hidden" name="table" value="'.$this->primaryTable.'" />'."\n";
		$string .= '	<input type="hidden" name="submit" value="Delete" /><input type="submit" name="sub" value="'.$this->cfg['button_delete'].'" class="submit input_delete" onclick="if (confirm(\''.$this->cfg['text_delete'].'\')) return true; else return false;" />'."\n";
		return $this->HTMLForm($string);
	}
	
	final function sessionBuild() {
		$this->primaryTable = $this->tables[0]['name'];
		$key = $this->oDb->obtain("SHOW COLUMNS FROM `".$this->primaryTable."` WHERE `Key` = 'PRI'");
		$this->primaryKey = $key['Field'];
		$this->iId = $this->oUrl->action;
		
		$this->dbFields($this->primaryTable);
	}

	final function pp($var, $key, $table="") {
		if ($this->readFormInPP)
			if (array_key_exists($key,$_POST)) return $_POST[$key];
		if (empty($table)) $table = $this->primaryTable;
		if ($this->langActive()) {
			$ar = $this->multilangKeysGet();
			if (@$ar[$table][$key])
				$key .= "_".$this->lang;
		}
		$index = $table . $this->fieldSeparator . $key;
		if (is_array($var) && array_key_exists($index,$var))
			return $var[$index];
		return "";
	}
	
	protected function getDb($id = 0) {
		
		$this->doSql($id);
		if ($id > 0)
			$this->row = $this->oDb->get($this->query);
	}
	
	final function errorMsg($msg, $formError = TRUE) {
		$this->MSG = '<div class="chyba">'.$msg.'</div>'."\n";
		$this->formError = $formError;
	}
	
	final function okMsg($msg) {
		$this->MSG = '<div class="okmsg">'.$msg.'</div>'."\n";
	}
	
	protected function validateData($array) {
		if ($this->action == "Insert") $this->okMsg($this->cfg['action_insert']);
		if ($this->action == "Save") $this->okMsg($this->cfg['action_save']);
	}
	
	protected function printListing() {
		$ret = "";
		$ret .= "\n" . '<div class="pageList">'."\n";
		$nav = Array();
		$deleno = $this->countRows / $this->perPage;
		$max = floor($deleno);
		if ($deleno == $max && $max > 0)
			$max -= 1;
		if ($max == 0)
			return "";
		if ($this->oUrl->pos > $max || $this->oUrl->pos < 0)
			$this->_home($this->oUrl->hrefCat());
		$zaznamy = $this->cfg['list_05'];
		if ($this->perPage == 1) $zaznamy = $this->cfg['list_1'];
		if (in_array($this->perPage,Array(2,3,4))) $zaznamy = $this->cfg['list_234'];
		$nav[] = "<p>{$this->cfg['list_strana']} ".($this->oUrl->pos+1)." / ".($max+1).". {$this->cfg['list_zobrazujem']} {$this->perPage} {$zaznamy} {$this->cfg['list_z']} {$this->countRows}.</p>"."\n";
		$nav[] = '<a href="'.$this->oUrl->pageLink(0).'">&laquo;&laquo;&laquo;</a>';
		$lower = $this->oUrl->pos;
		if ($lower > 0) $lower -= 1;
		$nav[] = '<a href="'.$this->oUrl->pageLink($lower).'">&laquo;&laquo;</a>';
		$odchylka = 5;
		$start = 0;
		$pridajStart = 0;
		$end = $max;
		$pridajEnd = 0;
		if ($this->oUrl->pos - $odchylka > 0)
			$start = $this->oUrl->pos - $odchylka;
		if ($this->oUrl->pos + $odchylka < $max)
			$end = $this->oUrl->pos + $odchylka;
		for ($i=$start;$i<$end+1;$i++) {
			$sel = $i == $this->oUrl->pos ? 'class="active"' : "";
			$nav[] = '<a href="'.$this->oUrl->pageLink($i).'"'.$sel.'>'.($i+1).'</a>';
		}
		$highler = $this->oUrl->pos;
		if ($highler < $max) $highler += 1;
		$nav[] = '<a href="'.$this->oUrl->pageLink($highler).'">&raquo;&raquo;</a>';
		$nav[] = '<a href="'.$this->oUrl->pageLink($max).'">&raquo;&raquo;&raquo;</a>';
		$ret .= implode(" ",$nav);
		$ret .= '<div class="clear"></div>'."\n";
		$ret .= '</div>'."\n";
		return $ret;
	}
	
	protected function printList($ret) {
		if ($this->oUrl->pos > 0)
			$ret = $this->printListing() . $ret;
		$ret = $this->insertButton() . $ret;
		$ret = $ret . $this->printListing();
		return $ret;
	}
	
	protected function canInsert() {
		return $this->hasRights("can_insert") && !empty($this->insertText);
	}
	
	protected function insertButton() {
		if ($this->canInsert()) {
			$insert = '<input type="hidden" name="submit" value="New" /><input type="submit" name="sub" class="submit input_new" value="'.$this->insertText.'" />'."\n";
			return '<div class="insert">' . $this->HTMLForm($insert) . '</div>' . "\n";
		}
	}
	
	protected function printForm($action, $id, $ret, $reset=TRUE) {
		$tagTitle = "h3";
		$saveAsNew = FALSE;
		if ($action == "New") {
			$act = "Insert";
			$buttonLabel = $this->cfg['button_insert'];
		} elseif ($action == "Edit") {
			$act = "Save";
			$buttonLabel = $this->cfg['button_save'];
			if ($this->canInsert())
				$saveAsNew = TRUE;
		} else {
			$act = $action;
			$buttonLabel = $action;
		}
		$ret .= '<div class="submit">'."\n";
		$ret .= $this->oForm->submitButton($id, $buttonLabel, $reset, $act, $saveAsNew);
		$ret .= '</div>'."\n";
		return $this->HTMLForm($ret, "", "form");
	}
	
	protected function printDetail($ret) {
		return $ret;
	}
	
	protected function HTMLForm($content, $action="", $class="") {
		if (empty($action)) $action = $this->oUrl->fullHref();
		$ret = "";
		$ret .= '<form method="post" action="'.$action.'" enctype="multipart/form-data"'.($class ? ' class="'.$class.'"' : "").'>'."\n";
		$ret .= $content;
		$ret .= '</form>'."\n";
		return $ret;
	}
	
	/*
	 * vytvori sql to co potrebuje je v dataFields a z coho je v primaryTable
	 */
	protected function doSql($id=0, $count=FALSE) {
		$cntVar = $count ? "COUNT(1) AS pocet" : $this->dataFields();
		$sql = "SELECT {$cntVar} FROM `".$this->primaryTable."` ";
		if ($this->joins)
		foreach ($this->joins as $key => $val) {
			$key = explode("|",$key);
			if (count($key) > 1)
				$sql .= "LEFT JOIN `{$key[0]}` AS `{$key[1]}` ON {$val} ";
			else				
				$sql .= "LEFT JOIN `{$key[0]}` ON {$val} ";
		}
		$sql .= "WHERE ";
		$conditions = Array();
		$limit = "";
		if (!$count && !$id)
			$limit .= " LIMIT " . ($this->perPage * $this->oUrl->pos).",{$this->perPage}";
		if ($id > 0)
			$conditions[] = "{$this->primaryTable}.{$this->primaryKey} = '{$id}'";
		if (count($this->searchDb) > 0)
			for ($i=0;$i<count($this->searchDb);$i++)
				$conditions[] = $this->searchDb[$i];
		if (count($conditions) > 0)
			$sql .= implode(" AND ",$conditions);
		else
			$sql .= "1 ";
		// echo $sql . "<br />\n";
		if (!$count) {
			$sql .= " ORDER BY ".(strlen($this->oUrl->order) > 0 ? str_replace("-"," ",$this->oUrl->order) : $this->order)."";
			$sql .= $limit;
			$this->query = $this->oDb->query($sql);
			
			$this->doSql($id, TRUE);
		} else {
			$obt = $this->oDb->obtain($sql);
			$this->countRows = $obt['pocet'];
		}
	}
	
	private function dataFields() {
		if (strlen($this->dataFields) == 0) {
			$fields = Array();

			for ($i=0;$i<count($this->tables);$i++)
				for ($j=0;$j<count($this->dbFields($this->tables[$i]['name']));$j++) {
				
					if (array_key_exists("as",$this->tables[$i]))
						$prefix = $this->tables[$i]['as'];
					else
						$prefix = $this->tables[$i]['name'];
					$fields[] = $prefix . "." . $this->dbFields[$this->tables[$i]['name']][$j] . 
						" AS " . $prefix . $this->fieldSeparator . 
						$this->dbFields[$this->tables[$i]['name']][$j];					
				}
				
			return implode(", ",$fields);
		} else
			return $this->dataFields;
	}
	
	protected function dbFields($table) {
		$result = Array();
		//echo 'table '.$table.'<br>';
		if (!array_key_exists($table,$this->dbFields)) {
			$q = "SHOW COLUMNS FROM `".$table."`";
			$query = $this->oDb->query($q);
			
			while ($row = $this->oDb->get($query))
				$result[] = $row['Field']; // Field name
			$this->dbFields[$table] = $result;
		} else
			$result = $this->dbFields[$table];
		return $result;
	}

	/*
	 * najprv si vytvori prazdny riadok potom ho zmeni..picovina
	 * toto bude treba pomenit neskor
	 */
	public function dbInsert() {
//		var_dump($_POST);
		if (!$this->validateData($_POST)) return;
		if ($this->primaryTable=="users") {
			$sql ="INSERT INTO `users` (`login`, `meno`, `priezvisko`, `vek`, `klub_id`, `salt`, `heslo`, `reg_time`, `last_login`, `email`, `respekt`, `prava`, `foto`)
					 VALUES (?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, NULL, ?, NULL);";
			$salt=uniqid();
			$q= $this->oDb->queryWithBids($sql, array( $_POST['login'],$_POST['meno'],$_POST['priezvisko'],$_POST['vek'],$_POST['klub'],
					$salt, MD5($salt.$_POST['p1']), date('Y-m-d H:i:s'),$_POST['email'], $_POST['prava'] ));
			$insertID= $this->oDb->insertID();
			$pageID = $this->oMenu->getID($this->oUrl->page);
			//echo 'insertID:'.$insertID;
			$this->insertRights($pageID, $insertID);
			$this->workingID=$insertID;
		}
		else {
		//	 if (!$this->validateData($_POST)) return;
			$sql = "INSERT INTO `{$this->primaryTable}` () VALUES ()";
			$this->oDb->query($sql);
			$insertID = $this->oDb->insertID();
			// Global rights handling
			$pageID = $this->oMenu->getID($this->oUrl->page);
			$this->insertRights($pageID, $insertID);
			$this->dbUpdate($insertID);
		}
	}
	
	public function insertRights($pageID, $insertID) {
		//$qR = $this->oDbDef->query("SELECT * FROM perms_init WHERE id_menu = '{$pageID}'");
		$qR = $this->oDbDef->queryWithBids("SELECT * FROM perms_init WHERE id_menu = ?", array($pageID));
		$this->insertRightsSql($qR, $pageID, $insertID);
	}
	
	public function insertRightsSql($query, $pageID, $insertID) {
		if ($this->oDb->numrows($query) > 0)
			while ($resR = $this->oDb->get($query)) {
				$sql = "INSERT INTO perms 
					(id_menu,id_namespace,id_element,id_user,owner_type,id_owner,can_read,can_write,can_grant,can_comment)
					VALUES
					('".$pageID."','".$resR['id_namespace']."','".$insertID."','".$resR['id_user']."','".$resR['owner_type']."','".$resR['id_owner']."',
					'".$resR['can_read']."','".$resR['can_write']."','".$resR['can_grant']."','".$resR['can_comment']."')";
				$this->oDbDef->query($sql);
			}
	}
	
	public function dbUpdate($id) {
		//		echo 'update'.$id.'<br>';
		$postData = $_POST;
		if (!$this->validateData($postData)) return;
		$this->workingID = $id;
		$postData = $this->beforeSubmit($postData);
		foreach ($this->dbFields($this->primaryTable) as $key => $val) {
			if (array_key_exists($val,$postData))
				$this->$val = $postData[$val]; 
		}
		// Global tags handling
		$tagID = property_exists($this,"tagID") ? $this->tagID : $this->oMenu->pageID();
		if (array_key_exists("tags",$postData))
			$this->oFunctions->setTags($tagID, $id, $postData['tags']);
	}
	
	public function beforeSubmit($postData) {
		return $postData;
	}
	
	public function dbDelete($id) {
		if ($this->oDb->query("DELETE FROM `{$this->primaryTable}` WHERE {$this->primaryKey} = '".$id."'"))
			$this->okMsg($this->cfg['action_deleted']);
		else
			$this->errorMsg($this->cfg['action_ndeleted'], FALSE);
		$sql = "DELETE FROM perms
			WHERE id_menu = '".$this->oMenu->getID($this->oUrl->page)."'
			AND id_element = '".$id."'";
		$this->oDbDef->query($sql);
	}
	
}

?>
