. if (!defined('EG')) die('Direct access not allowed!'); abstract class Model_Base { 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 $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 have to be satisfied before applying the query //Ex: 'update'=>'checkEmpty:titolo,autore','submitName'=>'conditions' 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 public $softConditions = 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 $select = null; //fields that have to be selected in select queries 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 $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 $_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 $_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 public $db; //reference to the database layer class protected $_lang = 'En'; //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(); //initialize the validate objects $this->_arrayStrongCheck = new Array_Validate_Strong($this->_lang); $this->_arraySoftCheck = new Array_Validate_Soft($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(); //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() { $keys = implode(',',array_keys($this->values)); $this->values = $this->arrayExt->subset($this->values,$keys,'sanitizeDb'); } //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 (strstr($value,$symbol)) { //check if write or not the table name $tableName = strstr($field,'n!') ? null : $this->getTableName($field).'.'; $whereClauseArray[] = $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[] = $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]; } //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 //$id: if $queryType='update' that the values are taken from the record (of the main table of this model) having the primary key equal to $id //$defaultValues = associative array of the form: array($entry=>$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); $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[$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') { $tempArray = is_array($defaultValues) ? $defaultValues : array(); $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) { 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 (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; } } } //method to call the insert query (overriding of the base_db del method) public function insert() { $this->queryResult = false; if (!is_array($this->supplInsertValues)) { throw new Exception('error in ' . __METHOD__ . ': the supplInsertValues property has to be an array.'); } 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; } //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->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 (strcmp($values,'all') === 0 or strstr($values,'all|')) { if (strstr($values,'all|')) { $values = str_replace('all|',$this->fields.'|',$values); } else { $values = $this->fields; } } if (strstr($values,'|')) { $temp = explode('|',$values); $altErrorString = "