. 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 = array("entries" => array()); //the form structure public $submitName = null; //the current submitName (from the form) public $identifierName = 'identifier'; public $notice = null; //a string explaining the result of the query applied (or not if an error occured): executed, error, etc 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 the $_POST array has to satisfy (strong) public $strongConditions = array(); //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' public $databaseConditions = array(); public $popupArray = array(); //array of popup objects (see popup.php) public $supplInsertValues = array(); //associative array defining supplementary values to be inserted on each insert query. It has to have the following form: array(field1 => value1,field2 => value2, ...) 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 public $join = array(); //join array public $toList = false; //if the result have to be given in a list format public $listArray = array(); //array containing the $key and the $value to be used to extract a list from a resultSet //logic operator between statements in the where clause of select queries public $logicalOperators = array('AND'); public $files = null; //reference to the Files_Upload class protected $_tables='itemTable,boxTable,item_boxTable'; protected $_idFields='id_item,id_box'; protected $_tablesArray=array(); protected $_idFieldsArray=array(); protected $_where = array(); //the name of the field that has to be used to order the rows of the main table of the model protected $_idOrder = null; protected $_onDelete = 'check'; //can be 'nocheck' or 'check'. check: referential integrity check. nocheck: no referential integrity check protected $_reference = null; //array containing the child table that have a reference to this table and the foreign key of the child table-> array($childTable,$foreignKey) protected $_popupItemNames = array(); //the fields to be used as names in the popupArray elements. Associative array ($itemNameField1 => $itemNameValue1, ...) //the labels of the pop-up menus protected $_popupLabels = array(); //functions that have to be applied upon the label fields of the popup menu protected $_popupFunctions = array(); protected $_popupWhere = array(); //where clause for the pupup menu protected $_popupOrderBy = array(); //order by clause for the pupup menu 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 protected $submitNames = array( 'update' => 'updateAction', 'insert' => 'insertAction', 'del' =>'delAction', 'moveup' =>'moveupAction', 'movedown' =>'movedownAction' ); protected $identifierValue = null; //the value of the identifier ($_POST[$this->identifier]) protected $arrayExt; //arrayExt object (see library/arrayExt.php) 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 public function __construct() { $this->_tablesArray = explode(',',$this->_tables); $this->_idFieldsArray = explode(',',$this->_idFields); $this->_where[$this->_idFieldsArray[0]] = $this->_tablesArray[0]; $this->arrayExt = new ArrayExt(); //set the language of notices $this->_lang = Params::$language; //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]; //create the $_resultString object (result strings of the db queries) $modelStringClass = 'Lang_'.$this->_lang.'_ModelStrings'; if (!class_exists($modelStringClass)) { $modelStringClass = 'Lang_En_ModelStrings'; } $this->_resultString = new $modelStringClass(); //create the $_dbCondString object (result strings of the database conditions) $dbCondStringClass = 'Lang_'.$this->_lang.'_DbCondStrings'; if (!class_exists($dbCondStringClass)) { $dbCondStringClass = 'Lang_En_DbCondStrings'; } $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); //instantiate the Files_Upload class $params = array( 'filesPermission' => 0777, 'language' => $this->_lang, 'allowedExtensions' => 'png,jpg,jpeg,gif', 'maxFileSize' => 20000000, 'fileUploadKey' => 'userfile' ); $this->files = new Files_Upload(ROOT."/media/",$params); } //sanitize all the $values property public function sanitize($function = "sanitizeDb") { if (!function_exists($function)) { throw new Exception('Error in '.__METHOD__.': function '.$function.' does not exists.'); } $keys = implode(',',array_keys($this->values)); $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) { $this->_resultString->string[$key] = $value; } //set the submitNames property (array) //$methodName : the method name, $submitName: the submit name of the submit action of the form public function setSubmitNames($methodName,$submitName) { if (!in_array($methodName,$this->_allowedDbMethods)) { throw new Exception('query type "'.$methodName. '" not allowed in '. __METHOD__); } $this->submitNames[$methodName] = $submitName; } //get the last query executed public function getQuery() { return $this->db->query; } //get the where clause of the select query public function getWhereQueryClause() { return $this->where; } //set the where clause of the select query //whereArray = array ($table_field => $value) public function setWhereQueryClause($whereArray) { $this->where = $whereArray; } //append the whereArray clause to $this_->whereClause //whereArray = array ($table_field => $value) public function appendWhereQueryClause($whereArray) { $this->where = array_merge($this->where,$whereArray); } //drop the char $char from the beginning of the string $string public function dropStartChar($string,$char) { while(strcmp($string[0],$char) === 0) { $string = substr($string,1); } return $string; } //get the table name from $this->_where. If the table is not present then return $this->_tablesArray[0] public function getTableName($field) { return isset($this->_where[$field]) ? $this->_where[$field] : $this->_tablesArray[0]; } //method to create the where clause of the select query from the $this->where array //$level: level of the ricorsion //$whereClauseLevel: array containing the field=>value statements of the where clause. If $whereClause = null than $this->where is considered public function createWhereClause($level = 0, $whereClauseLevel = null, $operator = null) { $whereClause = null; $whereClauseArray = array(); $whereClause = isset($whereClauseLevel) ? $whereClauseLevel : $this->where; foreach ($whereClause as $field => $value) { if (is_array($value)) { if (strstr($field,"OR")) { $op = " OR "; } else if (strstr($field,"AND")) { $op = " AND "; } else { $op = null; } $newValue = $this->createWhereClause($level+1, $value, $op); if (isset($newValue)) $whereClauseArray[] = $newValue; } else { $flag = 0; //equal where clause if (isset($field)) { //drop the 'n:' and '-' chars from $field $fieldClean = str_replace('n!',null,$field); $fieldClean = $this->dropStartChar($fieldClean,'-'); if (strcmp($value,Params::$nullQueryValue) !== 0 or (Params::$nullQueryValue === false)) { foreach (params::$whereClauseSymbolArray as $symbol) { if (stristr($value,$symbol)) { //check if write or not the table name $tableName = strstr($field,'n!') ? null : $this->getTableName($field).'.'; $whereClauseArray[] = strstr($field,'n!n!') ? $value : $tableName.$fieldClean.' '.$value; $flag = 1; //not equal where clause break; } } if ($flag === 0) { $value = '"'.$value.'"'; //check if write or not the table name $tableName = strstr($field,'n!') ? null : $this->getTableName($field).'.'; $whereClauseArray[] = strstr($field,'n!n!') ? $value : $tableName.$fieldClean.'='.$value; } } } } } //get the logic operator at the current level if (isset($operator)) { $logicOper = $operator; } else { $logicOper = isset($this->logicalOperators[$level]) ? ' '.$this->logicalOperators[$level].' ' : ' AND '; } $whereClause = !empty($whereClauseArray) ? implode($logicOper,$whereClauseArray) : null; $whereClause = (isset($whereClause) and $level>0) ? '('.$whereClause.')' : $whereClause; return $whereClause; } //get the submitName having its key (the method name) public function getSubmitName($key) { if (!array_key_exists($key,$this->submitNames)) { return 'generalAction'; // throw new Exception('query type "'.$key. '" not allowed in '.__METHOD__); } return $this->submitNames[$key]; } //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$defaultValue) //$functionsIfFromDb = associative array of the form: array($entry=>$function_to_be_applied) public function getFormValues($queryType = 'insert', $func = 'sanitizeHtml',$id = null,$defaultValues = array(),$functionsIfFromDb = array()) { @session_start(); if (is_array($func)) { $funcPost = $func[0]; $funcDb = $func[1]; } else { $funcPost = $func; $funcDb = 'none'; } $arrayType = array('update','insert'); $values = array(); $idName = $this->identifierName; if (in_array($queryType,$arrayType)) { $ident = null; if (isset($id)) { $ident = (int)$id; } else if (isset($_POST[$idName])) { $ident = (int)$_POST[$idName]; } if ($this->result) { if ($queryType === 'update') { if (isset($ident)) { $recordArray = $this->selectId($ident); $recordArray = $this->convertFromMysql($recordArray); $fieldsArray = explode(',',$this->fields); $values = $this->arrayExt->subset($recordArray,$this->fields,$funcDb); $values[$idName] = $ident; //apply the functions upon entries foreach ($functionsIfFromDb as $entry => $funcUponEntry) { if (array_key_exists($entry,$values)) { if (!function_exists($funcUponEntry)) { throw new Exception('Error in '.__METHOD__.': function '.$funcUponEntry. ' does not exist'); } $values[$entry] = call_user_func($funcUponEntry,$values[$entry]); } } //set values of $_SESSION array foreach ($values as $k => $v) { if (isset($this->formStruct['entries'][$k]['type'])) { if ($this->formStruct['entries'][$k]['type'] === 'File') { $_SESSION['form_'.$k] = $v; } } } } } else if ($queryType === 'insert') { //set the default values taking it from DB or from type definition $tempArray = $this->setDefaultFormValues($this->fields); if (is_array($defaultValues)) { foreach ($defaultValues as $field => $value) { $tempArray[$field] = $value; } } $values = $this->arrayExt->subset($tempArray,$this->fields,$funcPost); } } else { $values = $this->arrayExt->subset($_POST,$this->fields,$funcPost); if ($queryType === 'update') { $values[$idName] = $ident; //take values from $_SESSION array $tempFieldArray = explode(',',$this->fields); for ($i = 0; $i < count($tempFieldArray); $i++) { if (isset($this->formStruct['entries'][$tempFieldArray[$i]]['type'])) { if ($this->formStruct['entries'][$tempFieldArray[$i]]['type'] === 'File') { if (isset($_SESSION['form_'.$tempFieldArray[$i]])) { $values[$tempFieldArray[$i]] = $_SESSION['form_'.$tempFieldArray[$i]]; } } } } } } } return $values; } //method to set the properties $this->fields and $this->values public function setFields($fields,$func = 'sanitizeAll') { $this->values = $this->arrayExt->subset($_POST,$fields,$func); $this->fields = $this->extractFields($fields); //set the backup variables $this->_backupFields = $this->fields; $this->_backupValues = $this->values; } //clear the fields list public function clearFields() { $this->_backupFields = $this->fields; $this->_backupValues = $this->values; $this->fields = ''; $this->values = array(); } //del the fields written in the $list argument. The $list argument has to be of the type: field1,field2,... public function delFields($list) { $this->_backupFields = $this->fields; $this->_backupValues = $this->values; $this->values = $this->arrayExt->subsetComplementary($this->values,$list); // $this->fields = implode(',',array_keys($this->values)); } //restore the fields and values saved in $_backupFields and $_backupValues public function restoreFields() { $this->fields = $this->_backupFields; $this->values = $this->_backupValues; } //method to clean the $fields string deleting the colons (and the word after the colon) public function extractFields($fields) { $fieldsArray = explode(',',$fields); $resultString = array(); foreach ($fieldsArray as $field) { if (strstr($field,':')) { $temp = explode(':',$field); $resultString[] = $temp[0]; } else { $resultString[] = $field; } } return implode(',',$resultString); } //add the supplementary value on insert and update queries //$queryType: insert or update public function setSupplValues($queryType) { if ($queryType === 'insert') { $supplValues = $this->supplInsertValues; } else if ($queryType === 'update') { $supplValues = $this->supplUpdateValues; } $baseFields = implode(',',array_keys($this->values)); $supplFields = implode(',',array_keys($supplValues)); $supplFields = (strcmp($supplFields,'') === 0) ? $supplFields : ',' . $supplFields; $fields = $baseFields . $supplFields; $values = array_merge(array_values($this->values),array_values($supplValues)); return array($fields,$values); } //method to call the update query (overriding of the base_db del method) //update the record with the primary key equal to $id (default) //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 ' . __METHOD__ . ': the supplUpdateValues property has to be an array.'); } $el = $this->setSupplValues('update'); $this->queryResult = false; if (count($this->values) > 0) { if (isset($whereClause)) { $result = $this->db->update($this->_tablesArray[0],$el[0],$el[1],$whereClause); $this->setNotice($result); return $result; } else { 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 ' . __METHOD__ . ': the supplInsertValues property has to be an array.'); } if (count($this->values) > 0) { 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; } 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) public function del($id = null, $whereClause = null) { $this->queryResult = false; if (isset($whereClause)) { $result = $this->db->del($this->_tablesArray[0],$whereClause); $this->setNotice($result); return $result; } else { if (isset($id)) { $where = $this->_idFieldsArray[0].'='.(int)$id; $result = $this->db->del($this->_tablesArray[0],$where); $this->setNotice($result); return $result; } else { $this->notice .= $this->_resultString->getString('no-id'); $this->result = false; $this->identifierValue = null; return false; } } } //move to the top the record having $this->_idOrder = $id //where clause public function moveup($id) { return $this->move($id,'up'); } //move to the top the record having $this->_idOrder = $id //where clause public function movedown($id) { return $this->move($id,'down'); } //move the record having $this->_tablesArray[0] = $id //$par: 'up' or 'down' //where clause public function move($id,$par = 'up') { $this->notice = null; $this->queryResult = false; if (isset($id)) { $increm = ($par === 'up') ? 1 : -1; $backupLimit = $this->limit; $this->limit = null; $data = $this->getFields($this->_tablesArray[0].'.'.$this->_idFieldsArray[0].','.$this->_tablesArray[0].'.'.$this->_idOrder); for($i = 0; $i < count($data); $i++) { if (strcmp($data[$i][$this->_tablesArray[0]][$this->_idFieldsArray[0]],$id) === 0) { if (($par === 'up' and $i !== 0) or ($par === 'down' and $i !== (count($data)-1))) { $prevOrder = $data[$i-$increm][$this->_tablesArray[0]][$this->_idOrder]; $prevId = $data[$i-$increm][$this->_tablesArray[0]][$this->_idFieldsArray[0]]; $currentOrder = $data[$i][$this->_tablesArray[0]][$this->_idOrder]; $currentId = $data[$i][$this->_tablesArray[0]][$this->_idFieldsArray[0]]; //exchange the id_order of the two record $res1 = $this->db->update($this->_tablesArray[0],$this->_idOrder,array($prevOrder),$this->_idFieldsArray[0]."='$currentId'"); $res2 = $this->db->update($this->_tablesArray[0],$this->_idOrder,array($currentOrder),$this->_idFieldsArray[0]."='$prevId'"); $result = ($res1 and $res2); $this->setNotice($result); return $result; } } } $this->limit = $backupLimit; } else { $this->notice .= $this->_resultString->getString('no-id'); $this->result = false; $this->identifierValue = null; return false; } return false; } public function setNotice($result) { if ($result) { $this->notice .= $this->_resultString->getString('executed'); $this->result = true; $this->queryResult = true; } else { $this->notice .= $this->_resultString->getString('error'); $this->result = false; $this->queryResult = false; } } //method used to verify that the value of a field is not duplicated //$fieldsList: list of fields to check. Ex: field1,field2,... //$where: the where clause public function checkUnique($fieldsList,$where = null) { $errorString = null; $numb = 0; $fieldsArray = explode(',',$fieldsList); $queryFieldsArray = explode(',',$this->fields); foreach ($fieldsArray as $field) { if (in_array($field,$queryFieldsArray)) { if ($this->db->recordExists($this->_tablesArray[0],$field,$this->values[$field],$where)) { $errorString .= $this->_dbCondString->getNotUniqueString($field); $numb++; } } } $this->notice = $errorString; return $numb === 0 ? true : false; } //like checkUnique: check all the records of the table apart from the record that has to be modified public function checkUniqueCompl($fieldsList,$id = null) { if (isset($id)) { $where = $this->_idFieldsArray[0].'!='.(int)($id); return $this->checkUnique($fieldsList,$where); } else { $this->notice = $this->_resultString->getString('no-id'); return false; } } //method to apply the database conditions listed in the $this->databaseConditions associative array //$queryType: indicates what set of validate conditions has to be considered (it's the key of the associative array) public function applyDatabaseConditions($queryType,$id = null) { if (array_key_exists($queryType,$this->databaseConditions)) { if (!is_array($this->databaseConditions[$queryType])) { throw new Exception('error in method '.__METHOD__.' : databaseConditions['.$queryType.'] has to be an associative array'); } foreach ($this->databaseConditions[$queryType] as $key => $values) { //personalized error string $altErrorString = null; //delete all the '+' chars $key = $this->dropStartChar($key,'+'); if (strstr($values,'|')) { $temp = explode('|',$values); $altErrorString = "
".$temp[1]."
\n"; $values = $temp[0]; } $allowedMethod = array('checkUnique','checkUniqueCompl'); if (!in_array($key,$allowedMethod)) { throw new Exception('error in method '.__METHOD__.' : method "'.$key. '" not allowed in the property named databaseConditions'); } if (!call_user_func_array(array($this,$key),array($values,$id))) { if (isset($altErrorString)) $this->notice = $altErrorString; $this->result = false; $this->queryResult = false; return false; } } return true; } else { return true; } } //add a condition //$condArray: it can be $this->strongConditions, $this->softConditions or $this->databaseConditions //$queryType: insert, update //$condition: the condition //$field: comma separated list of fields private function addCondition(&$condArray,$queryType,$condition,$field) { if (isset($condArray[$queryType]) and array_key_exists($condition,$condArray[$queryType])) { $condition = "+".$condition; $this->addCondition($condArray,$queryType,$condition,$field); } else { $condArray[$queryType][$condition] = $field; } } //choose if to apply insert, update or both conditions private function addChooseCondition(&$condArray,$queryType,$condition,$field) { if ($queryType === "both") { $this->addCondition($condArray,"insert",$condition,$field); $this->addCondition($condArray,"update",$condition,$field); } else { $this->addCondition($condArray,$queryType,$condition,$field); } } //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 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,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 (array_key_exists($queryType,$conditions)) { if (!is_array($conditions[$queryType])) { throw new Exception('error in method '.__METHOD__.' : '.$errString.'['.$queryType.'] has to be an associative array'); } foreach ($conditions[$queryType] as $key => $values) { //personalized error string $altErrorString = null; //delete all the '+' chars $key = $this->dropStartChar($key,'+'); if (strstr($values,'|')) { $temp = explode('|',$values); $altErrorString = "
".$temp[1]."
\n"; $values = $temp[0]; } $baseArgs = array($arrayToCheck,$values); if (strstr($key,'|')) { $funcArray = explode('|',$key); $funcName = $funcArray[0]; array_shift($funcArray); $funcArgs = array_merge($baseArgs,$funcArray); } else { $funcName = $key; $funcArgs = $baseArgs; } if (!method_exists($validateObj,$funcName) or $funcName === 'checkGeneric') { throw new Exception('error in method '.__METHOD__.' :method "'.$funcName. '" not allowed in '.$errString); } if (!call_user_func_array(array($validateObj,$funcName),$funcArgs)) { $this->notice .= (isset($altErrorString)) ? $altErrorString : $validateObj->errorString; $this->result = false; $this->queryResult = false; return false; } } return true; } else { return true; } } //apply, in sequence, the strong,soft and database conditions //$methodName: insert,update //$id: the id of the record. It is necessary for database conditions public function checkConditions($methodName,$id = null) { if ($this->applyValidateConditions($methodName,'strong')) { if ($this->applyValidateConditions($methodName,'soft')) { if ($this->applyDatabaseConditions($methodName,$id)) { return true; } } } return false; } //method that calls the function indicated in $this->submitNames. Ex: if $_POST['delAction'] is found, then the "del" method is called. public function updateTable($methodsList = '',$id = null) { $allowedMethodsArray = explode(',',$methodsList); $resultArray = array(); $this->identifierValue = null; if (isset($id)) { $this->identifierValue = (int)$id; } else if (isset($_POST[$this->identifierName])) { $this->identifierValue = (int)$_POST[$this->identifierName]; } foreach ($this->submitNames as $methodName => $submitName) { if (array_key_exists($submitName,$_POST)) { $this->submitName = $submitName; if (method_exists($this,$methodName)) { if (strcmp($methodName,"insert") === 0) { $this->identifierValue = null; } //if the method is allowed if (in_array($methodName,$allowedMethodsArray)) { if ($this->checkConditions($methodName,$this->identifierValue)) { $this->notice = null; call_user_func_array(array($this,$methodName),array($this->identifierValue)); } } } else { throw new Exception('method '.$methodName.' not defined in class '.__CLASS__.'; error in method '.__METHOD__.''); } return; //only one cycle! } } } //method to build the array of popup objects public function popupBuild() { foreach ($this->_popupItemNames as $field => $itemName) { // if (array_key_exists($field,$this->_where)) // { $fieldClean = str_replace('n!',null,$field); $itemNameClean = str_replace('n!',null,$itemName); $fieldClean = $this->dropStartChar($fieldClean,'-'); $itemNameClean = $this->dropStartChar($itemNameClean,'-'); //fields that have to be extracted $queryFields = ($fieldClean === $itemNameClean) ? $fieldClean : $fieldClean.','.$itemNameClean; $table = $this->getTableName($field); $this->popupArray[$field] = new Popup(); $popupWhereClause = array_key_exists($field,$this->_popupWhere) ? $this->_popupWhere[$field] : null; $popupOrderBy = array_key_exists($field,$this->_popupOrderBy) ? $this->_popupOrderBy[$field] : null; $result = $this->db->select($table,$queryFields,$popupWhereClause,$fieldClean,$popupOrderBy); if ($result and $result !== false) { //get the label of the popup menu $label = array_key_exists($field,$this->_popupLabels) ? $this->_popupLabels[$field] : $table.' : '.$itemNameClean; $this->popupArray[$field]->name = $label; //get the table name $fieldTable = isset($result[0][$table][$fieldClean]) ? $table : Params::$aggregateKey; $itemNameTable = isset($result[0][$table][$itemNameClean]) ? $table : Params::$aggregateKey; foreach ($result as $row) { $this->popupArray[$field]->itemsValue[] = $row[$fieldTable][$fieldClean]; if (array_key_exists($field,$this->_popupFunctions)) { if (!function_exists($this->_popupFunctions[$field])) { throw new Exception('Error in '.__METHOD__.': function '.$this->_popupFunctions[$field]. ' does not exist'); } $tempName = call_user_func($this->_popupFunctions[$field],$row[$itemNameTable][$itemNameClean]); } else { $tempName = $row[$itemNameTable][$itemNameClean]; } $this->popupArray[$field]->itemsName[] = $tempName; } } // } } } //get the element before and after the current one //$key: the key of the self::$where array that indicates the field to be used in order to find out the records before and after //$fields: the fields that have to be extracted public function getNeighbours($key,$fields = '') { //backup of the values $tempWhere = $this->where; $tempLimit = $this->limit; $tempOrderBy = $this->orderBy; $this->limit = 1; //before $this->where[$key] = '<'.$tempWhere[$key]; $this->orderBy = $this->getTableName($key).'.'.$key.' DESC'; $dataAfter = $this->getFields($fields); //after $this->where[$key] = '>'.$tempWhere[$key]; $this->orderBy = $this->getTableName($key).'.'.$key; $dataBefore = $this->getFields($fields); //restore the previous values $this->where = $tempWhere; $this->limit = $tempLimit; $this->orderBy = $tempOrderBy; $result[0] = isset($dataBefore[0]) ? $dataBefore[0] : null; $result[1] = isset($dataAfter[0]) ? $dataAfter[0] : null; return $result; } //set the $select property and return the current object public function select($fields = null) { $this->select = $fields; 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) { $this->from = isset($tables) ? $tables : $this->_tables; return $this; } //set the on property and return the current object public function on($joinClause = '-') { $this->on[] = $joinClause; $this->using[] = null; return $this; } //set the $using property and return the current object public function using($using = null) { $this->using[] = $using; $this->on[] = null; return $this; } //set the $join property and return the current object public function left($string = null) { $this->join[] = "l:$string"; return $this; } //set the $join property and return the current object public function right($string = null) { $this->join[] = "r:$string"; return $this; } //set the $join property and return the current object public function inner($string = null) { $this->join[] = "i:$string"; return $this; } //set the $where property and return the current object public function where($where = array()) { $this->where = $where; return $this; } //append the $where array to the ::where property and return the current object public function aWhere($where = array()) { $this->appendWhereQueryClause($where); 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) { $this->groupBy = $groupBy; return $this; } //set the $orderBy property and return the current object public function orderBy($orderBy = null) { $this->orderBy = $orderBy; return $this; } //set the $limit property and return the current object public function limit($limit = null) { $this->limit = $limit; return $this; } //set the $listArray property public function toList($key, $value = null) { $this->listArray = array($key,$value); $this->toList = true; return $this; } //reset all the clauses of the select query public function clear() { $this->select = null; $this->where = array(); $this->sWhere = null; $this->groupBy = null; $this->orderBy = null; $this->limit = null; $this->from = null; $this->on = array(); $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_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) { if (isset($this->formStruct)) { $action = array_key_exists('action',$this->formStruct) ? $this->formStruct['action'] : $defAction; $submit = array_key_exists('submit',$this->formStruct) ? $this->formStruct['submit'] : $defSubmit; $entries = array_key_exists('entries',$this->formStruct) ? $this->formStruct['entries'] : null; $method = array_key_exists('post',$this->formStruct) ? $this->formStruct['post'] : $defMethod; $enctype = array_key_exists('enctype',$this->formStruct) ? $this->formStruct['enctype'] : $defEnctype; $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); } $copy = $this->form->entry; foreach ($copy as $name => $entry) { if (strcmp($entry->type,'Select') === 0 and isset($entry->options)) { if (!is_array($entry->options)) { if (strstr($entry->options,'foreign::')) { $elements = explode('::',$entry->options); for ($i = 0; $i < count($elements); $i++) { if (strcmp($elements[$i],'--') === 0) $elements[$i] = null; } //send the query array_shift($elements); $resultSet = call_user_func_array(array($this->db,'select'),$elements); $single = true; if (strstr($elements[1],',')) { $args = explode(',',$elements[1]); //add the table name $args[0] = $elements[0].'.'.$args[0]; $args[1] = $elements[0].'.'.$args[1]; //associative array $single = false; } else { $args[0] = $elements[0].'.'.$elements[1]; $args[1] = null; } $list = $this->getList($resultSet,$args[0],$args[1]); $this->form->entry[$name]->options = ($single) ? implode(',',array_values($list)) : $list; } } } } } else { $this->form = new Form_Form($defAction,$defSubmit,$defMethod,$defEnctype); } } //get a list from a result set //$resultSet: the result set coming from a select query public function getList($resultSet, $key, $value = null) { $list = array(); if (strstr($key,'.')) { $arr = explode('.',$key); $keyTable = $arr[0]; $keyField = $arr[1]; } else { $keyTable = $this->_tablesArray[0]; $keyField = $key; } if (!isset($value)) { foreach ($resultSet as $row) { $list[] = $row[$keyTable][$keyField]; } } else { if (strstr($value,'.')) { $arr = explode('.',$value); $valueTable = $arr[0]; $valueField = $arr[1]; } else { $valueTable = $this->_tablesArray[0]; $valueField = $value; } foreach ($resultSet as $row) { $list[$row[$keyTable][$keyField]] = $row[$valueTable][$valueField]; } } return $list; } // Retrieves the ID generated for an AUTO_INCREMENT column by the previous query (usually INSERT). public function lastId() { return $this->db->lastId(); } //send a free query public function query($query) { return $this->db->query($query); } //the text of the error message from previous MySQL operation public function getError() { return $this->db->getError(); } //the numerical value of the error message from previous MySQL operation public function getErrno() { return $this->db->getErrno(); } //define the abstract method to get the value of the record $id of the main table abstract public function selectId($id); //define the abstract method to get the fields from the tables abstract public function getFields(); }