<?php

/**
 * @see MyWeb_Model_Abstract
 */
require_once 'MyWeb/Model/Abstract.php';

/**
 * Abstraktní třída modelů pro databáze
 *
 * @package    MyWebBlog
 * @author     Marian Böhmer
 */
abstract class MyWeb_Model_Database extends MyWeb_Model_Abstract
{
    /**
     * Úprava údajů před vložením
     *
     * @param array $data údaje na vložení
     * @return array doplněné údaje
     */
    protected function _preInsert(array $data)
    {
    	self::addLog('MyWeb_Model_Database',1,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
        return $data;
    }
    
    /**
     * Vykonání doplňkových příkazů po vložení
     *
     * @param array $data předané údaje
     */
    protected function _postInsert(array $data)
    {
    	self::addLog('MyWeb_Model_Database',2,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
    }

    /**
     * Vložení údajů
     *
     * @param array $data údaje na vložení
     * @throws MyWeb_Model_Exception 
     * @return string nový primární klíč
     */
    public function insert(array $data)
    {
    	self::addLog('MyWeb_Model_Database',3,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
        
        try {
            // načítá formulář
            $form = $this->getForm('insert');
            
            // otestuje údaje
            if (!$form->isValid($data)) {
                // vyvolá vlastní výjimku
                require_once 'MyWeb/Model/Exception.php';
                throw new MyWeb_Model_Exception('Neplatné údaje');
            }
            
            // filtrované a validované údaje
            //$values = $data;
            $values = $form->getValues();
            // doplní údaje
            $values = $this->_preInsert($values);
            // vytvoří nový řádek
            $row = $this->getStorage()->createRow($values);
            // uloží řádek
            //pokud jmeno sloupce obsahuje passwd ulozi se jako hash
        	foreach ($values as $key => $value) {
        		if (false !== strpos($key, 'passwd')){
        			$hash = md5($value);
            		$row->$key =md5($hash);
        		}
        	}
            
            $id = $row->save();
            // prida do vtupnich dat id vytvoreneho zaznamu
            $primaryKey = $this->getStorage()->info('primary');
            $data[$primaryKey[1]] = $id;
            // doplňující úkony
            $this->_postInsert($data);
        } catch (Zend_Db_Exception $e) {
            // vyvolá vlastní výjimku
            require_once 'MyWeb/Model/Exception.php';
            throw new MyWeb_Model_Exception('Vložení nebylo úspěšné'.$e->getLine().$e->getFile());
        }
        
        // uložení bylo úspěšné
        return $id;
    }
    
    /**
     * Úprava údajů před aktualizací
     *
     * @param array $data údaje na vložení
     * @return array doplněné údaje
     */
    protected function _preUpdate(array $data)
    {
    	self::addLog('MyWeb_Model_Database',4,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
        return $data;
    }
    
    /**
     * Vykonání doplňkových příkazů po aktualizaci
     *
     * @param array $data předané údaje
     */
    protected function _postUpdate(array $data)
    {
    	self::addLog('MyWeb_Model_Database',5,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
    }
    
    /**
     * Změna údajů
     *
     * @param array $data údaje na změnění
     * @param string|array $id primární klíč
     * @throws MyWeb_Model_Exception 
     * @return boolean
     */
    public function update(array $data, $id)
    {
    	self::addLog('MyWeb_Model_Database',6,4,'ABSTRACT');
    	self::showMe(self::showLog(),'LOG2');
    	
        try {
            // načítá formulář
            $form = $this->getForm('update');
            
            // otestuje údaje
            if (!$form->isValid($data)) {
                // vyvolá vlastní výjimku
                require_once 'MyWeb/Model/Exception.php';
                throw new MyWeb_Model_Exception('Neplatné údaje');
            }
            
            // filtrované a validované údaje
            $values = $form->getValues();
            
            // doplní údaje
            $values = $this->_preUpdate($values);
                        
            $id = (array) $id;
            
            // načítá řádek
            $storage = $this->getStorage();
            $rowset = call_user_func_array(array($storage, 'find'), $id);
            $row = $rowset->current();
            
            // zahashovani hesla
        	foreach ($data as $key => $value) {
        		if (false !== strpos($key, 'passwd')){
        			if (!empty($value)){
            			$row->$key =md5($value);
            			unset($data[$key]);
            			reset($data);
            			break;
        			}else {
        				unset($data[$key]);
        				reset($data);
        				break;
        			}
        		}
        	}
            // naplní řádek údaji
            $row->setFromArray($data);
            
            // uloží řádek
            $row->save();
            
            // doplňující úkony
            $this->_postUpdate($values);
            
        } catch (Zend_Db_Exception $e) {
            // vyvolá vlastní výjimku
            require_once 'MyWeb/Model/Exception.php';
            throw new MyWeb_Model_Exception('Aktualizace nebyla úspěšná');
        }
        
        // uložení bylo úspěšné
        return true;
    }
    
    /**
     * Smazání údajů
     *
     * @param string|array $id primární klíč
     * @throws MyWeb_Model_Exception 
     * @return boolean
     */
    public function delete($id)
    {
    	self::addLog('MyWeb_Model_Database',7,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
        try {
            $id = (array) $id;
            
            // načítá řádek
            $storage = $this->getStorage();
            $rowset = call_user_func_array(array($storage, 'find'), $id);
            $row = $rowset->current();
            
            // smaže řádek
            $row->delete();
        } catch (Zend_Db_Exception $e) {
            // vyvolá vlastní výjimku
            require_once 'MyWeb/Model/Exception.php';
            throw new MyWeb_Model_Exception('Smazání nebylo úspěšné');
        }
        
        // smazání bylo úspěšné
        return true;
    }
    
    
    
    /**
     * 
     * funkce overi zdali hodnota jiz v danem sloupci existuje
     * 
     * @return bool
     */
    public function isExists($column, $value,$id){
    	// načítá řádek
    	//echo "<p>"."is exist"."</p>";
        $storage = $this->getStorage();
        if (is_null($id)){
        	$select = $storage	->select(current($storage->info('primary')))
        					->where($column.' = ?',$value);
        }else {
        	$select = $storage	->select(current($storage->info('primary')))
        						->where($column.' = ?',$value)
        						->where(current($storage->info('primary')).' != ?',$id);
        }
        
        $sameRow = $storage	->fetchAll($select);
        if (count($sameRow) > 0){
        	return TRUE;
        }else {
        	return FALSE;
        }
        
    }
    
    
    
    
    /**
     * Načítá všechny údaje
     *
     * @return array
     */
    public function fetchEntries($data)
    {
    	self::addLog('MyWeb_Model_Database',8,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
        // vrátí údaje z řádků
        return $this->getStorage()->fetchAll()->toArray();
    }
    /**
     * Vrati select pro fetch entries
     * 
     * @param unknown_type $data
     */
    public function getFetchEntrySelect($data)
    {
    	self::addLog('MyWeb_Model_Database',8,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
        // vrátí údaje z řádků
        $db = $this->getStorage()->getAdapter();
        return $db->select();
    }
    
    /**
     * Vrátí jeden řádek
     *
     * @param string|array $id primární klíč
     * @return array
     */
    public function fetchEntry($id)
    {
    	self::addLog('MyWeb_Model_Database',9,4,'ABSTRACT');
        self::showMe(self::showLog(),'LOG2');
        // vrátí údaje z jednoho řádku
        $id = (array) $id;
           
        // načítá řádek
        $storage = $this->getStorage();
        $rowset = call_user_func_array(array($storage, 'find'), $id);
        $row = $rowset->current();
        return is_null($row) ? null : $row->toArray();
    }
    
    /**
     * funkce vrati id stavu pro danou tabulku
     * @param $column
     * @param $value
     */
    public function getIdState($stateName, $tableName)
    {
    	//echo "<p>"."getIdState"."</p>";
        $db = $this->getStorage()->getAdapter();
        
        // vytvoří SELECT
        $select = $db	->	select()
        				->	from(array('S' => 'State'),
        						array('id_state','state_state','NameState_id_NameState','TableDatabase_id_tableDatabase'))
        				->	join(array('N' => 'NameState'),
        						'S.NameState_id_NameState=N.id_NameState',
        						array('id_NameState','nameState_name'))
        				->	join(array('T' => 'TableDatabase'),
        						'S.TableDatabase_id_tableDatabase=T.id_tableDatabase',
        						array('id_tableDatabase','tableDatabase_table'))
        			->	where('N.nameState_name = ?',$stateName)
        			->	where('T.tableDatabase_table = ?',$tableName);
        //echo "<p>".$select."</p>";
        $db->setFetchMode(Zend_Db::FETCH_ASSOC);
        $sameRow = $db	->fetchAll($select);
        
        if (count($sameRow) > 0){
        	//echo "<p>".$sameRow[0]['id_state']."</p>";
        	return $sameRow[0]['id_state'];
        }else {
        	return FALSE;
        }
    }
    
    
    
	/**
     * funkce vrati id role
     * @param $column
     * @param $value
     */
    public function getIdRole($roleName)
    {
    	//echo "<p>"."getIdState"."</p>";
        $db = $this->getStorage()->getAdapter();
        
        // vytvoří SELECT
        $select = $db	->	select()
        				->	from(array('R' => 'Role'),
        						array('id_role', 'role_role', 'State_id_state'))
        			->	where('R.role_role = ?',$roleName);
        //echo "<p>".$select."</p>";
        $db->setFetchMode(Zend_Db::FETCH_ASSOC);
        $sameRow = $db	->fetchAll($select);
        
        if (count($sameRow) > 0){
        	//echo "<p>".$sameRow[0]['id_state']."</p>";
        	return $sameRow[0]['id_role'];
        }else {
        	return FALSE;
        }
    }
    
    /**
     * matoda zpracuje data odeslana formularem a vytvori z nich where pro search mimo stav
     * Enter description here ...
     * @param unknown_type $data
     * @param unknown_type $mainTable
     */
    public function createWhere($select,$data,$mainTable)
    {
    	//echo "<p>"."createWhere"."</p>";
    	
    	$hiddenIndex = 'Value';
		$hiddenIndexInputValue = 'InputValue';
		$hiddenIndexInputName = 'InputName';
    	$foreignTables = array();
    	
    	$db = $this->getStorage();
    	$table = $db->info('referenceMap');
    	try {
    	if (is_array($table)) {
    		foreach ($table as $referenceMap => $valueReferenceMap) {
    			$nameForeignTable = end(explode('_',$valueReferenceMap['refTableClass']));
    			$foreignTables[strtolower($nameForeignTable)] = $this->loadStorage($nameForeignTable);
    		}
    	}else {
    		$zprava = "MyWeb_Model_Database: referenceMap not array: "."\n";
        	throw new Exception($zprava);
    	}
    	
    	foreach ($data as $columName => $dataValue) {
    		//echo "<p>column name: ".$columName."</p>";
    		if ((!empty($dataValue)) && (strcmp($dataValue,"none") !== 0)){
    		//echo "<p>column neni empty: ".$columName."</p>";
    		$describeMainTable = $this->getStorage()->info('metadata');
    		foreach ($describeMainTable as $columNameMainTable => $columValueMainTable) {// sloupec hlavni tabulky
    			if (strcmp($columNameMainTable, $columName) != 0){
    				//echo "<p>column neni v man table: ".$columName."</p>";
    				if (substr_count($columName, $hiddenIndex) > 0) {//pokud obsahuje value
    					//echo "<p>column obsahuje value: ".$columName."*********************</p>";
    					if (substr_count($columName, $hiddenIndexInputValue) > 0) {//pokud obsahuje InputValue
    						//echo "<p>sloupec obsahuje: ".$hiddenIndexInputValue."********************</p>";
    						break;
    					}
    					if (substr_count($columName, $hiddenIndexInputName) > 0) {//pokud obsahuje InputName
    						//echo "<p>sloupec obsahuje: ".$hiddenIndexInputName."******************</p>";
    						break;
    					}
    					$nameForeignColumn = substr($columName, 0, -strlen($hiddenIndex));
    					//naleznu cizy sloupec v cizy tabulce
    					$foreignTable = strtolower(current(explode('_', $nameForeignColumn)));
    					if (array_key_exists($foreignTable, $foreignTables)){// pokud existuje cizy tabulka
    						//echo "<p>existuje cizy tabulka: ".$nameForeignColumn."</p>";
    						$describe = $foreignTables[$foreignTable]->info('metadata');
    						if (array_key_exists($nameForeignColumn, $describe)){// pokud existuje cizy sloupec
    							//echo "<p>existuje cizy sloupec: ".$nameForeignColumn."</p>";
    							//pridani klauzule where do selectu
    							$aliasTable = substr(ucfirst($foreignTable),0,1);
    							$select	->	where($aliasTable.".".$nameForeignColumn." = ?",$dataValue);
    							break;
    						}
    					}
    				}
    			}
    		}
    		
    	}
    	}
    	}catch (Exception $e){
    		echo $e->getMessage();
		}
    	return $select;
    }
}
