<?php
/**
 * @package Simple MVC
 * @version 1.0
 * 
 * Data Acces Object for PHP.
 * Provides simple crud actions
 * - Create
 * - Read
 * - Update
 * - Delete()
 * 
 * @todo
 * Implement support for multiple primary keys
 * Implement support for updating individual fields
 * Implement validation before creation
 * 
 *  */

abstract class dao {
	
	const WHERE_IN = 2;
	const WHERE_NOT = 4;
	
	const ORDER_DESC = 8;
	const ORDER_ASC = 16;
	
	public $arAssoc = array ();
	
	
	public static $arTableFields = array(					
	);
	
	/**
	 * Returns an array of objects
	 * 
	 * @param $filter array       	
	 * @param $filterWay array       	
	 * @param $orderField array       	
	 */
	public static function getArObj($filter = array(), $filterWay = array(), $orderField = array(), $limit = array()) {
		$oObj = new static ();
		$query = queryBuilder::buildSelect ( $db, $oObj->table, $filter, $filterWay, $orderField , $limit);
		$res = $db->query ( $query )->allAssoc ();
		return $this->createObjects($res);
	}
	
	/**
 	 * Creates a new objects and returns
  	 * the created one
	 */
	public function create(){
		$query = queryBuilder::buildInsert($db, $this);
		$db->query($query);				
		$query2 = queryBuilder::simpleSelect($this->table, $this->primaryKey, $db->insert_id);
		$res = $db->query($query2)->allAssoc();
		$this->fillObject($res);		
	}
	/**
	 * Updates an object
	 */
	public function update(){
		$query = queryBuilder::buildUpdate($db, $this);
		$db->query($query);
		$query2 = queryBuilder::simpleSelect($this->table, $this->primaryKey, $db->insert_id);
		$res = $db->query($query2)->allAssoc();
		$this->fillObject($res);
	}
	/**
	 * Deletes an object
	 */
	public function delete(){
		$query = queryBuilder::buildDelete($db, $this);
		$db->query($query);
	}
	/**
	 * Creates an array of objects
	 * @param array $res
	 * @return array
	 */
	private function createObjects($res = array()){
		$arObj = array();
		foreach($res as $row){
			$oObj = new static ();
			foreach($row as $key=>$value)
				$oObj->arAssoc [$key] = $value;
		
			$arObj [] = $oObj;
		}
		
		return $arObj;		
	}
	private function fillObject($res = array()){

		foreach($res as $row){
					foreach($row as $key=>$value)
						$this->arAssoc [$key] = $value;
					
					$this->arAssoc ['saved'] = true;
				}
	
	
	}
	
	public function __get($name) {
		
		switch ($name){
			case 'saved':
				return empty($this->arAssoc['saved']) ? false : true;
			default :
				return $this->arAssoc [$name];
		}
	}
	
	public function __construct($primaryKey = null) {
		if(! is_null ( $primaryKey )){		
			
			$query = queryBuilder::buildSelect ($db, $this->table, array (	$this->primaryKey => $primaryKey ) );
			$res = $db->query ( $query )->allAssoc ();
			if(! empty ( $res )){
				foreach($res as $row){
					foreach($row as $key=>$value)
						$this->arAssoc [$key] = $value;					
					$this->arAssoc ['saved'] = true;
				}
			} else {
				$this->arAssoc['saved'] = false;
			}
		}
		
		$this->getTableFields();

		
	}
	
	private function getTableFields(){
		if(empty(self::$arTableFields)){
			$db = db::get();
			$res = $db->query("SHOW FIELDS FROM ".$this->table)->allAssoc();
			if(!empty($res)){
				foreach($res as $row){
					self::$arTableFields [$row['Field']] = $row['Field'];
				}
			}
		}
		
	}
	
	public function __set($name, $val) {
		$this->arAssoc [$name] = $val;
	}
	

}