diff options
Diffstat (limited to 'h-source/Library/Model')
-rwxr-xr-x | h-source/Library/Model/Base.php | 520 | ||||
-rwxr-xr-x | h-source/Library/Model/Map.php | 2 | ||||
-rwxr-xr-x | h-source/Library/Model/Tree.php | 560 |
3 files changed, 931 insertions, 151 deletions
diff --git a/h-source/Library/Model/Base.php b/h-source/Library/Model/Base.php index cdd1843..67bd91c 100755 --- a/h-source/Library/Model/Base.php +++ b/h-source/Library/Model/Base.php @@ -2,7 +2,7 @@ // EasyGiant is a PHP framework for creating and managing dynamic content // -// Copyright (C) 2009 - 2011 Antonio Gallo +// Copyright (C) 2009 - 2014 Antonio Gallo (info@laboratoriolibero.com) // See COPYRIGHT.txt and LICENSE.txt. // // This file is part of EasyGiant @@ -25,10 +25,12 @@ if (!defined('EG')) die('Direct access not allowed!'); abstract class Model_Base { + public $foreignKeys = array(); //list of foreign keys + public $fields = ''; //the fields that have to be manipulated by the update and insert query public $values = array(); //the values that corresponding to the $this->fields fields public $form = null; //reference to a Form_Form object - public $formStruct = null; //the form structure + public $formStruct = array("entries" => array()); //the form structure public $submitName = null; //the current submitName (from the form) public $identifierName = 'identifier'; @@ -37,15 +39,18 @@ abstract class Model_Base public $result = true; //the result of validate conditions, database conditions and query. It can be 'true' or 'false' public $queryResult = false; //the result of the query - //conditions that have to be satisfied before applying the query - //Ex: 'update'=>'checkEmpty:titolo,autore','submitName'=>'conditions' + //conditions that the $_POST array has to satisfy (strong) public $strongConditions = array(); - //conditions that have to be satisfied before applying the query - //Ex: 'update'=>'checkEmpty:titolo,autore','submitName'=>'conditions' - //do not return error if a value is equal to '' or null + //conditions that the $_POST array has to satisfy (soft) public $softConditions = array(); + //conditions that $this->values has to satisfy (strong) + public $valuesConditions = array(); + + //array where the conditions are temporary saved when the saveConditions is called + public $backupConditions = array(); + //conditions that have to be satisfied before applying the query //check that the new values inserted satisfy some conditions //Ex: 'update'=>'checkUniqueCompl:titolo,autore;checkUnique:titolo','insert'=>'checkUnique:titolo' @@ -57,13 +62,17 @@ abstract class Model_Base public $supplUpdateValues = array(); //associative array defining supplementary values to be inserted on each update query. It has to have the following form: array(field1 => value1,field2 => value2, ...) + public $backupSelect = array(); //where the status of the where clause is stored when the save() method is called public $select = null; //fields that have to be selected in select queries + public $sWhere = null; //string: free where clause public $where = array(); //associative array containing all the where clauses ($field => $value) //group by, order by and limit clauses public $groupBy = null; public $orderBy = null; public $limit = null; + public $convert = false; //It can be tru or false. If true the extracted values are converted from MySQL format to $_lang format + public $from = null; //from clause of the select queries public $on = array(); //on array public $using = array(); //using array @@ -104,6 +113,9 @@ abstract class Model_Base protected $_resultString; //reference to the class containing all the result strings of the db queries protected $_dbCondString; //reference to the class containing all the result strings of the database conditions + protected $_conversionToDbObject = null; //reference to the class to convert the values from current lang formats to MySQL formats + protected $_conversionFromDbObject = null; //reference to the class to convert the values from MySQL formats to current lang formats + protected $_backupFields = ''; //field saved after the delFields method has been applied protected $_backupValues = array(); //values saved after the delFields method has been applied protected $_allowedDbMethods = array('update','insert','del','moveup','movedown'); //methods that can be called by the updateTable method @@ -121,6 +133,7 @@ abstract class Model_Base protected $_arrayStrongCheck; //Array_Validate_Strong object protected $_arraySoftCheck; //Array_Validate_Soft object + protected $_arrayValuesCheck; //Array_Validate_Values object public $db; //reference to the database layer class protected $_lang = null; //language of notices @@ -138,6 +151,7 @@ abstract class Model_Base //initialize the validate objects $this->_arrayStrongCheck = new Array_Validate_Strong($this->_lang); $this->_arraySoftCheck = new Array_Validate_Soft($this->_lang); + $this->_arrayValuesCheck = new Array_Validate_Values($this->_lang); $this->identifierName = $this->_idFieldsArray[0]; @@ -157,6 +171,24 @@ abstract class Model_Base } $this->_dbCondString = new $dbCondStringClass(); + //create the references of the classes to convert to e from MySQL formats + if (DATABASE_TYPE === "Mysqli" or DATABASE_TYPE === "Mysql") + { + $_conversionToDbObject = 'Lang_'.$this->_lang.'_Formats_To_Mysql'; + if (!class_exists($_conversionToDbObject)) + { + $_conversionToDbObject = 'Lang_En_Formats_To_Mysql'; + } + $this->_conversionToDbObject = new $_conversionToDbObject(); + + $_conversionFromDbObject = 'Lang_'.$this->_lang.'_Formats_From_Mysql'; + if (!class_exists($_conversionFromDbObject)) + { + $_conversionFromDbObject = 'Lang_En_Formats_From_Mysql'; + } + $this->_conversionFromDbObject = new $_conversionFromDbObject(); + } + //instantiate the database class $this->db = Factory_Db::getInstance(DATABASE_TYPE); @@ -173,12 +205,22 @@ abstract class Model_Base } //sanitize all the $values property - public function sanitize() + public function sanitize($function = "sanitizeDb") { + if (!function_exists($function)) { + throw new Exception('Error in <b>'.__METHOD__.'</b>: function <b>'.$function.'</b> does not exists.'); + } + $keys = implode(',',array_keys($this->values)); - $this->values = $this->arrayExt->subset($this->values,$keys,'sanitizeDb'); + $this->values = $this->arrayExt->subset($this->values,$keys,$function); } + //return the name of the primary key + public function getPrimaryKey() + { + return $this->_idFields; + } + //change a resulting string from a db query public function setString($key,$value) { @@ -326,7 +368,129 @@ abstract class Model_Base } - + //converts values from MySQl to $_lang format when filling the form with values coming from the DB + public function convertFromMysql($values) + { + if (Params::$automaticConversionFromDbFormat) + { + if (isset($this->_conversionFromDbObject)) + { + //get all types as associative array + $types = $this->db->getTypes($this->_tables, "*", false, true); + + if ($types) + { + $values = $this->convertFromMysqlT($types, $values, $this->db->getEnumTypes()); + } + } + } + + return $values; + } + + //convert an array associaive from MySQL format to $_lang format + //$values: array associative to convert + //$types: types of the elements of the associative array + //$excludeTypes: array of type whose conversion has to be avoided + public function convertFromMysqlT($types, $values, $excludeTypes = array()) + { + foreach ($values as $field => $value) + { + if (array_key_exists($field, $types)) + { + if (!in_array(strtolower($types[$field]),$excludeTypes)) + { + if (method_exists($this->_conversionFromDbObject,strtolower($types[$field]))) + { + $values[$field] = call_user_func(array($this->_conversionFromDbObject, strtolower($types[$field])), $values[$field]); + } + } + } + } + return $values; + } + + //set the default values taking it from DB or from type definition + public function setDefaultFormValues($fields) + { + $returnDefaultValues = array(); + + if (Params::$automaticallySetFormDefaultValues) + { + if (isset($this->_conversionFromDbObject)) + { + //get all types as associative array + $types = $this->db->getTypes($this->_tables, "*", true, true); + + //get all default values as associative array + $defaultValues = $this->db->getDefaultValues($this->_tables, "*", false, true); + + $fieldsArray = explode(",",$fields); + + foreach ($fieldsArray as $field) + { + if (array_key_exists($field,$defaultValues)) + { + if (preg_match('/^('.implode("|",$this->db->getCharTypes()).')/i',$types[$field],$matches) or preg_match('/^('.implode("|",$this->db->getTextTypes()).')/i',$types[$field],$matches)) + { + if (strcmp($defaultValues[$field],"") !== 0) + { + $returnDefaultValues[$field] = $defaultValues[$field]; + } + } + else if (preg_match('/^('.implode("|",$this->db->getIntegerTypes()).')/i',$types[$field],$matches) or preg_match('/^('.implode("|",$this->db->getFloatTypes()).')$/i',$types[$field],$matches) or preg_match('/^('.implode("|",$this->db->getDecimalTypes()).')/i',$types[$field],$matches)) + { + if (strcmp($defaultValues[$field],"") !== 0) + { + $returnDefaultValues[$field] = method_exists($this->_conversionFromDbObject,strtolower($matches[1])) ? call_user_func(array($this->_conversionFromDbObject, strtolower($matches[1])), $defaultValues[$field]) : $defaultValues[$field]; + } + else + { + $returnDefaultValues[$field] = 0; + } + } + else if (preg_match('/^('.implode("|",$this->db->getDateTypes()).')$/i',$types[$field],$matches)) + { + $defDate = Params::$useCurrentDateAsDefaultDate ? date("Y-m-d") : ""; + if (strcmp($defaultValues[$field],"") !== 0) + { + $defDate = $defaultValues[$field]; + } + + if (method_exists($this->_conversionFromDbObject,strtolower($types[$field]))) + { + $returnDefaultValues[$field] = call_user_func(array($this->_conversionFromDbObject, strtolower($types[$field])), $defDate); + } + else + { + $returnDefaultValues[$field] = $defDate; + } + } + else if (preg_match('/^('.implode("|",$this->db->getEnumTypes()).')\((.*?)\)$/i',$types[$field],$matches)) + { + if (strcmp($defaultValues[$field],"") !== 0) + { + $returnDefaultValues[$field] = $defaultValues[$field]; + } + else + { + $temp = array(); + $strings = explode(",",$matches[2]); + for ($i=0;$i<count($strings);$i++) + { + $returnDefaultValues[$field] = trim($strings[$i],"'\""); + break; + } + } + } + } + } + } + } + + return $returnDefaultValues; + } + //return the values, taken from the $_POST array, to be inserted inside the forms //$queryType: insert or update //$func: sanitize function to apply upon each value @@ -369,14 +533,11 @@ abstract class Model_Base { $recordArray = $this->selectId($ident); + $recordArray = $this->convertFromMysql($recordArray); + $fieldsArray = explode(',',$this->fields); - - $values = $this->arrayExt->subset($recordArray,$this->fields,$funcDb); -// foreach ($fieldsArray as $field) -// { -// $values[$field] = array_key_exists($field,$recordArray) ? $recordArray[$field] : ''; -// } + $values = $this->arrayExt->subset($recordArray,$this->fields,$funcDb); $values[$idName] = $ident; @@ -408,8 +569,16 @@ abstract class Model_Base } else if ($queryType === 'insert') { + //set the default values taking it from DB or from type definition + $tempArray = $this->setDefaultFormValues($this->fields); - $tempArray = is_array($defaultValues) ? $defaultValues : array(); + if (is_array($defaultValues)) + { + foreach ($defaultValues as $field => $value) + { + $tempArray[$field] = $value; + } + } $values = $this->arrayExt->subset($tempArray,$this->fields,$funcPost); @@ -528,6 +697,8 @@ abstract class Model_Base //if $whereClause is set then use $whereClause as where clause of the update query public function update($id = null, $whereClause = null) { + $this->notice = null; + if (!is_array($this->supplUpdateValues)) { throw new Exception('error in <b>' . __METHOD__ . '</b>: the <b>supplUpdateValues</b> property has to be an array.'); @@ -535,50 +706,70 @@ abstract class Model_Base $el = $this->setSupplValues('update'); $this->queryResult = false; - if (isset($whereClause)) - { - $result = $this->db->update($this->_tablesArray[0],$el[0],$el[1],$whereClause); - $this->setNotice($result); - return $result; - } - else + if (count($this->values) > 0) { - if (isset($id)) + if (isset($whereClause)) { - $where = $this->_idFieldsArray[0].'='.(int)($id); - $result = $this->db->update($this->_tablesArray[0],$el[0],$el[1],$where); + $result = $this->db->update($this->_tablesArray[0],$el[0],$el[1],$whereClause); $this->setNotice($result); return $result; } else { - $this->notice = $this->_resultString->getString('no-id'); - $this->result = false; - $this->identifierValue = null; - return false; + if (isset($id)) + { + $where = $this->_idFieldsArray[0].'='.(int)($id); + $result = $this->db->update($this->_tablesArray[0],$el[0],$el[1],$where); + $this->setNotice($result); + return $result; + } + else + { + $this->notice .= $this->_resultString->getString('no-id'); + $this->result = false; + $this->identifierValue = null; + return false; + } } } + else + { + $this->notice .= $this->_resultString->getString('no-fields'); + $this->result = true; + $this->queryResult = true; + return false; + } } //method to call the insert query (overriding of the base_db del method) public function insert() { - + $this->notice = null; $this->queryResult = false; if (!is_array($this->supplInsertValues)) { throw new Exception('error in <b>' . __METHOD__ . '</b>: the <b>supplInsertValues</b> property has to be an array.'); } - if (isset($this->_idOrder)) + if (count($this->values) > 0) { - $maxValue = $this->db->getMax($this->_tablesArray[0],$this->_idOrder); - $this->supplInsertValues[$this->_idOrder] = (int)$maxValue + 1; - } - - $el = $this->setSupplValues('insert'); + if (isset($this->_idOrder)) + { + $maxValue = $this->db->getMax($this->_tablesArray[0],$this->_idOrder); + $this->supplInsertValues[$this->_idOrder] = (int)$maxValue + 1; + } + + $el = $this->setSupplValues('insert'); - $result = $this->db->insert($this->_tablesArray[0],$el[0],$el[1]); - $this->setNotice($result); - return $result; + $result = $this->db->insert($this->_tablesArray[0],$el[0],$el[1]); + $this->setNotice($result); + return $result; + } + else + { + $this->notice .= $this->_resultString->getString('no-fields'); + $this->result = true; + $this->queryResult = true; + return false; + } } //method to call the delete query (overriding of the base_db del method) @@ -600,7 +791,7 @@ abstract class Model_Base $this->setNotice($result); return $result; } else { - $this->notice = $this->_resultString->getString('no-id'); + $this->notice .= $this->_resultString->getString('no-id'); $this->result = false; $this->identifierValue = null; return false; @@ -627,6 +818,8 @@ abstract class Model_Base //where clause public function move($id,$par = 'up') { + $this->notice = null; + $this->queryResult = false; if (isset($id)) { @@ -662,7 +855,7 @@ abstract class Model_Base } else { - $this->notice = $this->_resultString->getString('no-id'); + $this->notice .= $this->_resultString->getString('no-id'); $this->result = false; $this->identifierValue = null; return false; @@ -672,11 +865,11 @@ abstract class Model_Base public function setNotice($result) { if ($result) { - $this->notice = $this->_resultString->getString('executed'); + $this->notice .= $this->_resultString->getString('executed'); $this->result = true; $this->queryResult = true; } else { - $this->notice = $this->_resultString->getString('error'); + $this->notice .= $this->_resultString->getString('error'); $this->result = false; $this->queryResult = false; } @@ -798,39 +991,107 @@ abstract class Model_Base } //add a condition to the strongCondition array + public function addDatabaseCondition($queryType,$condition,$field) + { + if ($queryType === "both") + { + $this->addChooseCondition($this->databaseConditions,"insert",$condition,$field); + $this->addChooseCondition($this->databaseConditions,"update",$condition."Compl",$field); + } + else + { + $this->addChooseCondition($this->databaseConditions,$queryType,$condition,$field); + } + } + + //add a condition to the strongCondition array public function addStrongCondition($queryType,$condition,$field) { $this->addChooseCondition($this->strongConditions,$queryType,$condition,$field); } - //add a condition to the strongCondition array + //add a condition to the softCondition array public function addSoftCondition($queryType,$condition,$field) { $this->addChooseCondition($this->softConditions,$queryType,$condition,$field); } + //add a condition to the valuesCondition array + public function addValuesCondition($queryType,$condition,$field) + { + $this->addChooseCondition($this->valuesConditions,$queryType,$condition,$field); + } + + //return the correct conditions array + //$strength: strong,soft,values + public function &getConditions($strength) + { + if ($strength === 'strong') + { + return $this->strongConditions; + } + else if ($strength === 'values') + { + return $this->valuesConditions; + } + else if ($strength === 'database') + { + return $this->databaseConditions; + } + + return $this->softConditions; + } + + //save the conditions + //$strength: strong,soft,values + public function saveConditions($strength) + { + $this->backupConditions[$strength] = $this->getConditions($strength); + } + + //restore the conditions taking them from $this->backupConditions + public function restoreConditions($strength) + { + $c = &$this->getConditions($strength); + + if (isset($this->backupConditions[$strength])) + { + $c = $this->backupConditions[$strength]; + } + } + + //clear the conditions + //$strength: strong,soft,values + public function clearConditions($strength) + { + $c = &$this->getConditions($strength); + $c = array(); + } + //method to apply the validate conditions listed in the $this->strongConditions associative array //$queryType: indicates what set of validate conditions has to be considered (it's the key of the associative array) - //$strength: 'strong' or 'soft' + //$strength: strong,soft,values public function applyValidateConditions($queryType,$strength = 'strong') { + $arrayToCheck = $_POST; if ($strength === 'strong') { $validateObj = $this->_arrayStrongCheck; $conditions = $this->strongConditions; $errString = 'strongConditions'; } + else if ($strength === 'values') + { + $validateObj = $this->_arrayValuesCheck; + $conditions = $this->valuesConditions; + $errString = 'valuesConditions'; + $arrayToCheck = $this->values; + } else { $validateObj = $this->_arraySoftCheck; $conditions = $this->softConditions; $errString = 'softConditions'; - -// if (Params::$nullQueryValue !== false) -// { -// $conditions['insert']['+++++checkIsNotStrings|'.Params::$nullQueryValue] = 'all'; -// $conditions['update']['+++++checkIsNotStrings|'.Params::$nullQueryValue] = 'all'; -// } } if (array_key_exists($queryType,$conditions)) @@ -856,7 +1117,7 @@ abstract class Model_Base $values = $temp[0]; } - $baseArgs = array($_POST,$values); + $baseArgs = array($arrayToCheck,$values); if (strstr($key,'|')) { @@ -889,7 +1150,6 @@ abstract class Model_Base } } - //apply, in sequence, the strong,soft and database conditions //$methodName: insert,update //$id: the id of the record. It is necessary for database conditions @@ -1046,6 +1306,13 @@ abstract class Model_Base return $this; } + //set the $convert property and return the current object + public function convert($convert = true) + { + $this->convert = $convert; + return $this; + } + //set the $from property and return the current object public function from($tables = null) { @@ -1104,6 +1371,12 @@ abstract class Model_Base return $this; } + public function sWhere($sWhere) + { + $this->sWhere = $sWhere; + return $this; + } + //set the $groupBy property and return the current object public function groupBy($groupBy = null) { @@ -1138,6 +1411,7 @@ abstract class Model_Base { $this->select = null; $this->where = array(); + $this->sWhere = null; $this->groupBy = null; $this->orderBy = null; $this->limit = null; @@ -1146,9 +1420,84 @@ abstract class Model_Base $this->using = array(); $this->join = array(); $this->toList = false; + $this->convert = false; return $this; } + //save all the clauses of the select query + public function save() + { + $this->backupSelect["select"] = $this->select; + $this->backupSelect["where"] = $this->where; + $this->backupSelect["sWhere"] = $this->sWhere; + $this->backupSelect["groupBy"] = $this->groupBy; + $this->backupSelect["orderBy"] = $this->orderBy; + $this->backupSelect["limit"] = $this->limit; + $this->backupSelect["from"] = $this->from; + $this->backupSelect["on"] = $this->on; + $this->backupSelect["using"] = $this->using; + $this->backupSelect["join"] = $this->join; + $this->backupSelect["toList"] = $this->toList; + $this->backupSelect["convert"] = $this->convert; + return $this; + } + + //restored all the saved clauses of the select query + public function restore() + { + if (count($this->backupSelect) > 0) + { + $this->select = $this->backupSelect["select"]; + $this->where = $this->backupSelect["where"]; + $this->sWhere = $this->backupSelect["sWhere"]; + $this->groupBy = $this->backupSelect["groupBy"]; + $this->orderBy = $this->backupSelect["orderBy"]; + $this->limit = $this->backupSelect["limit"]; + $this->from = $this->backupSelect["from"]; + $this->on = $this->backupSelect["on"]; + $this->using = $this->backupSelect["using"]; + $this->join = $this->backupSelect["join"]; + $this->toList = $this->backupSelect["toList"]; + $this->convert = $this->backupSelect["convert"]; + } + return $this; + } + + public function getSelectArrayFromEnumField($fieldName) + { + $types = $this->db->getTypes($this->_tables, $fieldName, true, true); + + if ($types) + { + if (preg_match('/^('.implode("|",$this->db->getEnumTypes()).')\((.*?)\)/i',$types[$fieldName],$matches)) + { + return $this->getSelectArrayFromEnumValues($matches[1], $matches[2]); + } + } + } + + public function getSelectArrayFromEnumValues($enumFunc, $enumValues) + { + $enumFunc = strtolower($enumFunc); + + $temp = array(); + $strings = explode(",",$enumValues); + for ($i=0;$i<count($strings);$i++) + { + $val = trim($strings[$i],"'\""); + + if (isset($this->_conversionFromDbObject) and method_exists($this->_conversionFromDbObject, $enumFunc)) + { + $temp[$val] = call_user_func(array($this->_conversionFromDbObject, $enumFunc), $val); + } + else + { + $temp[$val] = $val; + } + } + return $temp; + } + //initialize and populate the ::form property (reference to a Form_Form object) public function setForm($defAction = null, $defSubmit = array(), $defMethod = 'POST', $defEnctype = null) { @@ -1162,6 +1511,67 @@ abstract class Model_Base $this->form = new Form_Form($action,$submit,$method,$enctype); + //get the entries from DB definition + $types = $this->db->getTypes($this->_tables, "*", true, true); + + foreach ($types as $field => $type) + { + $entryType = "InputText"; + $classType = "varchar_input"; + $options = null; + + if (strcmp($field, $this->_idFieldsArray[0]) === 0) + { + $entryType = "Hidden"; + } + else if (preg_match('/^('.implode("|",$this->db->getTextTypes()).')/i',$type,$matches)) + { + $entryType = "Textarea"; + $classType = "text_input"; + } + else if (preg_match('/^('.implode("|",$this->db->getDateTypes()).')/i',$type,$matches)) + { + $classType = "date_input"; + } + else if (preg_match('/^('.implode("|",$this->db->getEnumTypes()).')\((.*?)\)/i',$type,$matches)) + { + $entryType = "Select"; + $classType = "select_input"; + $options = $this->getSelectArrayFromEnumValues($matches[1], $matches[2]); + } + + if (array_key_exists($field,$entries)) + { + if (!array_key_exists("type",$entries[$field])) + { + $entries[$field]["type"] = $entryType; + } + + if ($entryType === "Select" and !array_key_exists("options",$entries[$field])) + { + $entries[$field]["options"] = $options; + $entries[$field]["reverse"] = "yes"; + } + + if (!array_key_exists("className",$entries[$field])) + { + $entries[$field]["className"] = $classType." ".Form_Form::$defaultEntryAttributes['className']; + } + } + else + { + $entries[$field]["type"] = $entryType; + + if ($entryType === "Select") + { + $entries[$field]["options"] = $options; + $entries[$field]["reverse"] = "yes"; + } + + $entries[$field]["className"] = $classType." ".Form_Form::$defaultEntryAttributes['className']; + } + } + if (isset($entries)) { $this->form->setEntries($entries); diff --git a/h-source/Library/Model/Map.php b/h-source/Library/Model/Map.php index 7a093e1..e6d9f6b 100755 --- a/h-source/Library/Model/Map.php +++ b/h-source/Library/Model/Map.php @@ -2,7 +2,7 @@ // EasyGiant is a PHP framework for creating and managing dynamic content // -// Copyright (C) 2009 - 2011 Antonio Gallo +// Copyright (C) 2009 - 2014 Antonio Gallo (info@laboratoriolibero.com) // See COPYRIGHT.txt and LICENSE.txt. // // This file is part of EasyGiant diff --git a/h-source/Library/Model/Tree.php b/h-source/Library/Model/Tree.php index f7f95ea..849fd7d 100755 --- a/h-source/Library/Model/Tree.php +++ b/h-source/Library/Model/Tree.php @@ -2,7 +2,7 @@ // EasyGiant is a PHP framework for creating and managing dynamic content // -// Copyright (C) 2009 - 2011 Antonio Gallo +// Copyright (C) 2009 - 2014 Antonio Gallo (info@laboratoriolibero.com) // See COPYRIGHT.txt and LICENSE.txt. // // This file is part of EasyGiant @@ -28,54 +28,54 @@ class Model_Tree extends Model_Base { parent::__construct(); } - //method to create the first part of where clause - //$index: the index of $this->_tablesArray - public function createTreeWhere($index) { - if (!empty($this->on)) - { - return $this->on; - } - else - { - $whereArray = array(); - for ($i = $index; $i < (count($this->_tablesArray)-1); $i++) - { - $whereArray[] = $this->_tablesArray[$i].'.'.$this->_idFieldsArray[$i+1].'='.$this->_tablesArray[$i+1].'.'.$this->_idFieldsArray[$i+1]; - } - $whereString = !empty($whereArray) ? implode(' and ',$whereArray) : null; - return $whereString; - } - } - - //create the list of tables of the select query - //$index: the index of $this->_tablesArray - public function createTablesList($index) { - if (isset($this->from)) - { - return $this->from; - } - else - { - $tablesString = null; - for ($i = $index; $i < (count($this->_tablesArray)-1); $i++) - { - $tablesString .= $this->_tablesArray[$i] . ','; - } - $tablesString .= $this->_tablesArray[count($this->_tablesArray)-1]; - return $tablesString; - } - } +// //method to create the first part of where clause +// //$index: the index of $this->_tablesArray +// public function createTreeWhere($index) { +// if (!empty($this->on)) +// { +// return $this->on; +// } +// else +// { +// $whereArray = array(); +// for ($i = $index; $i < (count($this->_tablesArray)-1); $i++) +// { +// $whereArray[] = $this->_tablesArray[$i].'.'.$this->_idFieldsArray[$i+1].'='.$this->_tablesArray[$i+1].'.'.$this->_idFieldsArray[$i+1]; +// } +// $whereString = !empty($whereArray) ? implode(' and ',$whereArray) : null; +// return $whereString; +// } +// } - //method to create the list of fields of the select query - public function createFieldsList($index) { - $fieldsString = null; - for ($i = $index; $i < (count($this->_tablesArray)-1); $i++) - { - $fieldsString .= $this->_tablesArray[$i] . '.*,'; - } - $fieldsString .= $this->_tablesArray[count($this->_tablesArray)-1].'.*'; - return $fieldsString; - } +// //create the list of tables of the select query +// //$index: the index of $this->_tablesArray +// public function createTablesList($index) { +// if (isset($this->from)) +// { +// return $this->from; +// } +// else +// { +// $tablesString = null; +// for ($i = $index; $i < (count($this->_tablesArray)-1); $i++) +// { +// $tablesString .= $this->_tablesArray[$i] . ','; +// } +// $tablesString .= $this->_tablesArray[count($this->_tablesArray)-1]; +// return $tablesString; +// } +// } +// +// //method to create the list of fields of the select query +// public function createFieldsList($index) { +// $fieldsString = null; +// for ($i = $index; $i < (count($this->_tablesArray)-1); $i++) +// { +// $fieldsString .= $this->_tablesArray[$i] . '.*,'; +// } +// $fieldsString .= $this->_tablesArray[count($this->_tablesArray)-1].'.*'; +// return $fieldsString; +// } //method to create the where clause and the list of tables and fields of the select query @@ -84,32 +84,51 @@ class Model_Tree extends Model_Base { //return: $elements = array('tables'=>$tables,'where'=>$where,'fields'=>$fields) public function treeQueryElements($tableName,$choice = 'all') { - $index = array_search($tableName,$this->_tablesArray); - $subArray = ($choice === 'all') ? array_slice($this->_tablesArray,$index) : array($tableName); //this array is necessary to verify that the where clause makes sense - $tables = ($choice === 'all') ? $this->createTablesList($index) : $tableName; - $where = ($choice === 'all') ? $this->createTreeWhere($index) : null; - $fields = ($choice === 'all') ? $this->createFieldsList($index) : $tableName.'.*'; - - $wherePlus = $this->createWhereClause(); - - if (empty($this->on)) +// $index = array_search($tableName,$this->_tablesArray); +// $subArray = ($choice === 'all') ? array_slice($this->_tablesArray,$index) : array($tableName); //this array is necessary to verify that the where clause makes sense +// $tables = ($choice === 'all') ? $this->createTablesList($index) : $tableName; +// $where = ($choice === 'all') ? $this->createTreeWhere($index) : null; +// $fields = ($choice === 'all') ? $this->createFieldsList($index) : $tableName.'.*'; +// +// $wherePlus = $this->createWhereClause(); +// +// if (empty($this->on)) +// { +// $on = array(); +// +// if (isset($where) and isset($wherePlus)) +// { +// $where .= ' AND ' . $wherePlus; +// } +// else if (!isset($where) and isset($wherePlus)) +// { +// $where .= $wherePlus; +// } +// } +// else +// { +// $on = $where; +// $where = $wherePlus; +// } + + $where = $this->createWhereClause(); + + if (isset($where)) { - $on = array(); - - if (isset($where) and isset($wherePlus)) + if (isset($this->sWhere)) { - $where .= ' AND ' . $wherePlus; - } - else if (!isset($where) and isset($wherePlus)) - { - $where .= $wherePlus; + $where .= " AND " . $this->sWhere; } } else { - $on = $where; - $where = $wherePlus; + $where = $this->sWhere; } + + $tables = isset($this->from) ? $this->from : $tableName; + + $fields = $tableName.".*"; + $on = $this->on; return array('tables' => $tables,'where' => $where,'fields'=>$fields,'on'=>$on); } @@ -127,10 +146,37 @@ class Model_Tree extends Model_Base { public function getFields($fields = '',$choice = 'all') { $elements = $this->treeQueryElements($this->_tablesArray[0],$choice); - + $queryFields = (strcmp($fields,'') === 0) ? $elements['fields'] : $fields; - return $row = $this->db->select($elements['tables'],$queryFields,$elements['where'],$this->groupBy,$this->orderBy,$this->limit,$elements['on'],$this->using,$this->join); + $row = $this->db->select($elements['tables'],$queryFields,$elements['where'],$this->groupBy,$this->orderBy,$this->limit,$elements['on'],$this->using,$this->join); + + //convert from MySQL values + if ($this->convert) + { + if (count($row) > 0) + { + $types = array(); + + $tablesList = array_keys($row[0]); + + foreach ($tablesList as $table) + { + $types[$table] = $this->db->getTypes($table, "*", false, true); + } + + for ($i=0;$i< count ($row); $i++) + { + foreach ($tablesList as $table) + { + $row[$i][$table] = $this->convertFromMysqlT($types[$table], $row[$i][$table]); + } + + } + } + } + + return $row; } public function send() @@ -160,8 +206,8 @@ class Model_Tree extends Model_Base { //$id: the id (primary key) of the record //$fields: the comma separated list of fields that have to be extracted public function selectId($id,$fields = null) { - $tempWhere = $this->where; - $this->setWhereQueryClause(array($this->_idFieldsArray[0] => (int)$id)); + + $this->save()->clear()->setWhereQueryClause(array($this->_idFieldsArray[0] => (int)$id)); $this->using = null; @@ -174,7 +220,7 @@ class Model_Tree extends Model_Base { $values = $this->getAll('other'); } - $this->where = $tempWhere; + $this->restore(); return (count($values) > 0) ? $values[0][$this->_tablesArray[0]] : array(); @@ -218,49 +264,373 @@ class Model_Tree extends Model_Base { return $this->db->recordExists($elements['tables'],$field,$value,$elements['where'],$this->groupBy,$elements['on'],$this->using,$this->join); } -// //get the number of records of the table $this->_tablesArray[0] -// public function rowNumber() { -// return $this->recordNumber($this->_tablesArray[0]); -// } - - //method to call the delete query (overriding of the del method of Model.php) - //check the referential integrity - public function del($id = null, $whereClause = null) + //check referential integrity during delete + public function checkOnDeleteIntegrity($id = null, $whereClause = null) { - $this->queryResult = false; + $this->save(); - if (isset($whereClause)) + $result = true; + + if (count($this->foreignKeys) > 0) { - return parent::del(null,$whereClause); + foreach ($this->foreignKeys as $f) + { + if (preg_match('/^(.*?)\s(parent of)\s(.*?)\((.*?)\)(\s(on delete)\s(cascade|restrict)\s\((.*?)\))?$/i',$f,$matches)) + { + $parentKey = $matches[1]; + $childModel = $matches[3]; + $childField = $matches[4]; + + if (isset($whereClause)) + { + $this->clear()->sWhere($whereClause); + } + else + { + $this->clear()->where(array($this->_idFields=>(int)$id)); + } + + $keys = sanitizeDbDeep($this->toList($parentKey)->send()); + $this->restore(); + + if (count($keys) > 0) + { + $child = new $childModel(); + $childrenIds = $child->clear()->where(array($childField=>"in('".implode("','",$keys)."')"))->toList($child->getPrimaryKey())->send(); + + if (count($childrenIds) > 0) + { + if (isset($matches[7]) and strcmp($matches[7],"cascade") === 0) + { + foreach ($childrenIds as $childId) + { + $child->del((int)$childId); + } + + if (strcmp($matches[8],"") !== 0) + { + $this->notice .= "<div class='".Params::$infoStringClassName."'>".$matches[8]."</div>"; + } + } + else + { + $this->notice .= isset($matches[8]) ? "<div class='".Params::$errorStringClassName."'>".$matches[8]."</div>" : $this->_resultString->getString('associate'); + $result = false; + } + } + } + + } + } } - else + + return $result; + } + + //check referential integrity during insert or update + public function checkOnUpdateIntegrity($queryType) + { + $result = true; + + if (count($this->foreignKeys) > 0) { - if ($this->_onDelete === 'check' and isset($this->_reference)) + foreach ($this->foreignKeys as $f) { - if (isset($this->_reference[0]) and isset($this->_reference[1])) + if (preg_match('/^(.*?)\s(child of)\s(.*?)\((.*?)\)(\s(on update)\s(restrict)\s\((.*?)\))?$/i',$f,$matches)) { - if ($this->db->recordExists($this->_reference[0],$this->_reference[1],(int)$id)) + $childKey = $matches[1]; + $ParentModel = $matches[3]; + $ParentField = $matches[4]; + + $notice = isset($matches[8]) ? "<div class='".Params::$errorStringClassName."'>".$matches[8]."</div>" : ""; + + if (array_key_exists($childKey,$this->values)) { - $this->notice = $this->_resultString->getString('associate'); - $this->identifierValue = null; + $parent = new $ParentModel(); + $res = $parent->clear()->where(array($ParentField=>sanitizeDb($this->values[$childKey])))->send(); + + if (count($res) === 0) + { + $this->notice .= $notice; + $this->result = false; + $result = false; + } + } + else if ($queryType === "insert") + { + $this->notice .= $notice; $this->result = false; + $result = false; } - else + } + } + } + + return $result; + } + + //get the first extracted full record + public function record() + { + $res = $this->getFields($this->select); + + if (count($res) > 0) + { + return $res[0][$this->_tables]; + } + return array(); + } + + //get a single field from the first extracted record + public function field($fieldName) + { + $res = $this->save()->select($fieldName)->send(); + $this->restore(); + + if (count($res) > 0 and isset($res[0][$this->_tables][$fieldName])) + { + return $res[0][$this->_tables][$fieldName]; + } + return ""; + } + + //get the types of the fields in $this->values + public function getTypes($full = false) + { + return $types = $this->db->getTypes($this->_tables,implode(",",array_keys($this->values)),$full); + } + + //automatically set the values conditions + public function setValuesConditionsFromDbFields($queryType) + { + $fields = array_keys($this->values); + $fieldsAsString = implode(",",$fields); + + $types = $this->getTypes(true); + $fieldKeys = $this->db->getKeys($this->_tables,$fieldsAsString,true,false); + + if (count($this->values) > 0) + { + if (!$types) + { + $this->notice .= $this->_resultString->getString('not-existing-fields'); + $this->result = false; + return false; + } + else + { + $this->saveConditions("values"); + $this->saveConditions("database"); + + if (Params::$setValuesConditionsFromDbTableStruct) + { + foreach ($types as $index => $t) + { + if (preg_match('/^('.implode("|",$this->db->getCharTypes()).')\(([0-9]*?)\)$/i',$t,$matches)) + { + $this->addValuesCondition($queryType,'checkLength|'.$matches[2],$fields[$index]); + } + else if (preg_match('/^('.implode("|",$this->db->getIntegerTypes()).')/i',$t,$matches)) + { + $this->addValuesCondition($queryType,'checkInteger',$fields[$index]); + } + else if (preg_match('/^('.implode("|",$this->db->getFloatTypes()).')$/i',$t,$matches)) + { + $this->addValuesCondition($queryType,'checkNumeric',$fields[$index]); + } + else if (preg_match('/^('.implode("|",$this->db->getDateTypes()).')$/i',$t,$matches)) + { + $this->addValuesCondition($queryType,'checkIsoDate',$fields[$index]); + } + else if (preg_match('/^('.implode("|",$this->db->getEnumTypes()).')\((.*?)\)$/i',$t,$matches)) + { + $temp = array(); + $strings = explode(",",$matches[2]); + for ($i=0;$i<count($strings);$i++) + { + $temp[] = trim($strings[$i],"'\""); + } + $this->addValuesCondition($queryType,'checkIsStrings|'.implode(",",$temp),$fields[$index]); + } + else if (preg_match('/^('.implode("|",$this->db->getDecimalTypes()).')\((.*?)\)$/i',$t,$matches)) + { + $this->addValuesCondition($queryType,'checkDecimal|'.$matches[2],$fields[$index]); + } + } + + //set unique conditions + foreach ($fieldKeys as $index => $fk) { - return parent::del((int)$id); + if (preg_match('/^('.implode("|",$this->db->getUniqueIndexStrings()).')$/i',$fk,$matches)) + { + if ($queryType === "insert") + { + $this->addDatabaseCondition($queryType,'checkUnique',$fields[$index]); + } + else + { + $this->addDatabaseCondition($queryType,'checkUniqueCompl',$fields[$index]); + } + } } } - else + + foreach (Params::$valuesConditionsFromFormatsOfFieldsNames as $regExpr => $function) { - throw new Exception('you have forgotten to set \'$this->_reference\' or you have forgotten to set $this->_onDelete = \'nocheck\''); + foreach ($fields as $f) + { + if (preg_match($regExpr,$f,$matches)) + { + $this->addValuesCondition($queryType,$function,$f); + } + } + } } - else + } + +// print_r($fields); +// print_r($types); + + return true; + } + + //convert values of the $this->values to MySQL formats + public function convertValuesToDb() + { + if (Params::$automaticConversionToDbFormat) + { + if (isset($this->_conversionToDbObject)) { - return parent::del((int)$id); + $types = $this->getTypes(); + + if ($types) + { + $fields = array_keys($this->values); + + foreach ($types as $index => $t) + { + if (method_exists($this->_conversionToDbObject,strtolower($t))) + { + $this->values[$fields[$index]] = call_user_func(array($this->_conversionToDbObject, strtolower($t)), $this->values[$fields[$index]]); + } + } + } } } + } + + public function insert() + { + $this->db->setAutocommit(true); + + $this->notice = null; + $this->queryResult = false; + + $this->convertValuesToDb(); + + if ($this->checkOnUpdateIntegrity("insert")) + { + //set the values conditions from the table description + if ($this->setValuesConditionsFromDbFields("insert")) + { + if ($this->applyDatabaseConditions("insert",null)) + { + $this->restoreConditions("database"); + if ($this->applyValidateConditions("insert",'values')) + { + $this->restoreConditions("values"); + return parent::insert(); + } + $this->restoreConditions("values"); + } + $this->restoreConditions("database"); + } + } + return false; + + } + + public function update($id = null, $whereClause = null) + { + $this->db->setAutocommit(true); + + $this->notice = null; + $this->queryResult = false; + + $this->convertValuesToDb(); + + if ($this->checkOnUpdateIntegrity("update")) + { + //set the values conditions from the table description + if ($this->setValuesConditionsFromDbFields("update")) + { + if (!isset($id) or $this->applyDatabaseConditions("update",(int)$id)) + { + $this->restoreConditions("database"); + //check the values conditions + if ($this->applyValidateConditions("update",'values')) + { + $this->restoreConditions("values"); + return parent::update($id, $whereClause); + } + $this->restoreConditions("values"); + } + $this->restoreConditions("database"); + } + } + + return false; + } + + //method to call the delete query (overriding of the del method of Model.php) + //check the referential integrity + public function del($id = null, $whereClause = null) + { + $this->notice = null; + $this->queryResult = false; + + if ($this->checkOnDeleteIntegrity($id, $whereClause)) + { + return parent::del($id, $whereClause); + } + else + { + return false; + } +// if (isset($whereClause)) +// { +// return parent::del(null,$whereClause); +// } +// else +// { +// if ($this->_onDelete === 'check' and isset($this->_reference)) +// { +// if (isset($this->_reference[0]) and isset($this->_reference[1])) +// { +// if ($this->db->recordExists($this->_reference[0],$this->_reference[1],(int)$id)) +// { +// $this->notice = $this->_resultString->getString('associate'); +// $this->identifierValue = null; +// $this->result = false; +// } +// else +// { +// return parent::del((int)$id); +// } +// } +// else +// { +// throw new Exception('you have forgotten to set \'$this->_reference\' or you have forgotten to set $this->_onDelete = \'nocheck\''); +// } +// } +// else +// { +// return parent::del((int)$id); +// } +// } +// return false; } //method to obtain one columns from the tables $this->_tablesArray as an associative array |