.
if (!defined('EG')) die('Direct access not allowed!');
class Model_Map extends Model_Base {
// //many to many model
public $printAssError = 'yes'; //'yes': print association error if the association/dissociation is already present. 'no': doen't print association error
public $boxIdentifierName = 'boxIdentifier';//key of the value of the $_POST array that represent the id of the Box that we want to associate with the Item having the id $_POST[$this->identifierName]
protected $_boxIdentifierValue = null; //the id of the box that has to be associated with the item
public function __construct()
{
//add some submit names (method => form_submit_value)
$this->submitNames['associate'] = 'associateAction';
$this->submitNames['dissociate'] = 'dissociateAction';
//add the allowed methods
$this->_allowedDbMethods[] = 'associate';
$this->_allowedDbMethods[] = 'dissociate';
parent::__construct();
}
public function createMapWhere($choice)
{ //create the where join clause
//$choice=(first,last,all)
$first = $this->_tablesArray[0].'.'.$this->_idFieldsArray[0].'='.$this->_tablesArray[2].'.'.$this->_idFieldsArray[0];
$last = $this->_tablesArray[1].'.'.$this->_idFieldsArray[1].'='.$this->_tablesArray[2].'.'.$this->_idFieldsArray[1];
switch ($choice) {
case 'first':
return $first;
break;
case 'last':
return $last;
break;
case 'all':
return $first. ' and '.$last;
break;
}
}
//check if a join query is necessary or not
//$val: 0 or 1 (items or boxes)
//$whereClauseLevel: array containing the field=>value statements of the where clause. If $whereClause = null than $this->where is considered
public function checkIfJoinNeeded($val, $whereClauseLevel = null)
{
$whereClause = isset($whereClauseLevel) ? $whereClauseLevel : $this->where;
foreach ($whereClause as $field => $value)
{
if (is_array($value))
{
if ($this->checkIfJoinNeeded($val, $value) === true) return true;
}
else
{
if (strcmp($this->getTableName($field),$this->_tablesArray[$val]) !== 0)
{
if (strcmp($value,Params::$nullQueryValue) !== 0 or (Params::$nullQueryValue === false)) return true;
}
}
}
//return false if no where clause has been defined
return false;
}
//method to create the where clause and the list of tables of the select query
public function mapQueryElements($val)
{
// $val = $element === 'Items' ? 0 : 1;
$tables = $this->_tablesArray[$val];
$where = null;
$fields = $this->_tablesArray[$val].'.*';
if ($this->checkIfJoinNeeded($val))
{
$tables = $this->_tables;
$fields = $this->_tablesArray[$val].'.*';
$wherePlus = $this->createWhereClause();
$wherePlus = isset($wherePlus) ? ' AND ' . $wherePlus : null;
$where = $this->createMapWhere('all') . $wherePlus;
}
else
{
$where = $this->createWhereClause();
}
return array('tables' => $tables,'where' => $where,'fields' => $fields);
}
//$element: Items or Boxes.
//get all Item or Boxes
public function getAll($element = 'Items')
{
return $this->getFields('',$element);
}
//method to get the values of the selected fields
//$fields: the fields that have to be excracted from the tableName
public function getFields($fields = '',$element = 'Items')
{
//get all Item or Boxes
if ((strcmp($element,'Items') !== 0) and (strcmp($element,'Boxes') !== 0))
{
throw new Exception('"'.$element. '" argument not allowed in '.__METHOD__.' method');
}
$val = $element === 'Items' ? 0 : 1;
$elements = $this->mapQueryElements($val);
$queryFields = (strcmp($fields,'') === 0) ? $elements['fields'] : $fields;
return $row = $this->db->select($elements['tables'],$queryFields,$elements['where'],$this->groupBy,$this->orderBy,$this->limit);
}
public function send($element = 'Items')
{
$table = $this->getFields($this->select, $element);
if ($this->toList)
{
$key = $this->listArray[0];
$value = isset($this->listArray[1]) ? $this->listArray[1] : null;
$this->toList = false;
return $this->getList($table, $key, $value);
}
else
{
return $table;
}
}
//the fields that have to be extracted from the table
public function getTable($fields = null)
{
return isset($fields) ? $this->getFields($fields) : $this->getAll();
}
//select the values of a specified record
//$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)
{
$id = (int)$id;
$tempWhere = $this->where;
$this->setWhereQueryClause(array($this->_idFieldsArray[0] => $id));
if (isset($fields))
{
$values = $this->getFields($fields,'Items');
}
else
{
$values = $this->getAll('Items');
}
$this->where = $tempWhere;
return (count($values) > 0) ? $values[0][$this->_tablesArray[0]] : array();
}
//get the number of records (items or boxes)
public function recordNumber($element)
{
$val = $element === 'Items' ? 0 : 1;
$elements = $this->mapQueryElements($val);
return $this->db->get_num_rows($elements['tables'],$elements['where'],$this->groupBy);
}
//get the number of records (only items)
public function rowNumber()
{
return $this->recordNumber('Items');
}
public function getMax($field)
{
$elements = $this->mapQueryElements(0);
return $this->db->getMax($elements['tables'],$field,$elements['where'],$this->groupBy);
}
public function getMin($field)
{
$elements = $this->mapQueryElements(0);
return $this->db->getMin($elements['tables'],$field,$elements['where'],$this->groupBy);
}
public function getSum($field)
{
$elements = $this->mapQueryElements(0);
return $this->db->getSum($elements['tables'],$field,$elements['where'],$this->groupBy);
}
public function getAvg($field)
{
$elements = $this->mapQueryElements(0);
return $this->db->getAvg($elements['tables'],$field,$elements['where'],$this->groupBy);
}
//check if the table has the field $field equal to $value
public function has($field,$value)
{
$elements = $this->mapQueryElements(0);
return $this->db->recordExists($elements['tables'],$field,$value,$elements['where'],$this->groupBy);
}
//associate an item with a box
//$idItem : name of the field of the Items table, $idGroup : name of the field of the Boxes table
public function associate($idItem = null,$idGroup = null)
{
$this->queryResult = false;
if (isset($idItem) and isset($idGroup))
{
$idItem = (int)$idItem;
$idGroup = (int)$idGroup;
$values = array($idItem,$idGroup); //values relative to the fields $this->_idFields
$var = $this->checkAssociation($idItem,$idGroup);
if (!$var)
{
$result = $this->db->insert($this->_tablesArray[2],$this->_idFields,$values);
$this->setNotice($result);
return $result;
}
else
{
if (strcmp($this->printAssError,'yes') === 0) $this->notice = $this->_resultString->getString('linked');
$this->result = false;
}
}
else
{
$this->notice = $this->_resultString->getString('no-id');
$this->result = false;
}
return false;
}
//associate an item with a box
//$idItem : name of the field of the Items table, $idGroup : name of the field of the Boxes table
public function dissociate($idItem = null,$idGroup = null)
{
$this->queryResult = false;
if (isset($idItem) and isset($idGroup))
{
$idItem = (int)$idItem;
$idGroup = (int)$idGroup;
$var = $this->checkAssociation($idItem,$idGroup);
if ($var)
{
$result = $this->db->del($this->_tablesArray[2],$this->_idFieldsArray[0].'='.$idItem.' and '.$this->_idFieldsArray[1].'='.$idGroup);
$this->setNotice($result);
return $result;
}
else
{
if (strcmp($this->printAssError,'yes') === 0) $this->notice = $this->_resultString->getString('not-linked');
$this->result = false;
}
}
else
{
$this->notice = $this->_resultString->getString('no-id');
$this->result = false;
}
return false;
}
public function checkAssociation($idItem,$idGroup)
{
$idItem = (int)$idItem;
$idGroup = (int)$idGroup;
$numRow = $this->db->get_num_rows($this->_tablesArray[2],$this->_idFieldsArray[0].'='.$idItem.' and '.$this->_idFieldsArray[1].'='.$idGroup);
if ($numRow === 1)
{
return true;
}
else
{
return false;
}
}
//check what items are associate to a box
//itemsArray:array of items to check
public function checkAssociationDeep($itemsArray)
{
$associatedItems = array();
$itemsArray = is_array($itemsArray) ? array_values($itemsArray) : array($itemsArray);
foreach ($itemsArray as $item) {
if ($this->db->recordExists($this->_tablesArray[2],$this->_idFieldsArray[0],$item))
{
$associatedItems[] = $item;
}
}
return $associatedItems;
}
//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->queryResult = false;
if (isset($whereClause))
{
return parent::del(null,$whereClause);
}
else
{
if ($this->_onDelete === 'check')
{
if ($this->db->recordExists($this->_tablesArray[2],$this->_idFieldsArray[0],(int)$id))
{
$this->notice = $this->_resultString->getString('associate');
$this->identifierValue = null;
$this->result = false;
}
else
{
return parent::del((int)$id);
}
}
else if ($this->_onDelete === 'nocheck')
{
return parent::del((int)$id);
}
}
return false;
}
//override of the updateTable method of the parent class
//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 (in_array($methodName,$allowedMethodsArray))
{
if ($this->checkConditions($methodName,$this->identifierValue))
{
$this->notice = null;
$methodArray = array('associate','dissociate');
if (in_array($methodName,$methodArray))
{
$this->_boxIdentifierValue = null;
if (isset($_POST[$this->boxIdentifierName]))
{
$this->_boxIdentifierValue = (int)$_POST[$this->boxIdentifierName];
}
call_user_func_array(array($this,$methodName),array($this->identifierValue,$this->_boxIdentifierValue));
}
else
{
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 obtain one columns from the tables $this->_tablesArray as an associative array
//$valueField: the column that have to be extracted (array_values of the resulting associative array), $keyField: the column that have to play the role of array_keys
//$valueField = field:table, $keyField = field:table
public function getFieldArray($valueField,$keyField = null, $groupBy = null, $orderBy = null, $limit = null)
{
$keyField = isset($keyField) ? $keyField : $valueField;
$valueFieldArray = explode(':',$valueField);
$keyFieldArray = explode(':',$keyField);
$keyFieldTable = $keyFieldArray[0];
$valueFieldTable = $valueFieldArray[0];
$keyFieldName = $keyFieldArray[1];
$valueFieldName = $valueFieldArray[1];
$fields = implode('.',$keyFieldArray) . ',' . implode('.',$valueFieldArray);
$temp = $this->where; //save the $this->where array
$this->where = array();
$val = array_search($keyFieldTable,$this->_tablesArray);
if (strcmp($keyFieldTable,$valueFieldTable) !== 0)
{
throw new Exception("the tables '$valueFieldTable' and '$keyFieldTable' do not match in ".__METHOD__);
}
if ($val === false or !in_array($val,array(0,1)))
{
throw new Exception("the table '$keyFieldTable' is not allowed in ".__METHOD__);
}
$elements = $this->mapQueryElements($val);
$table = $this->db->select($elements['tables'],$fields,$elements['where'],$groupBy,$orderBy,$limit);
$this->where = $temp;
$returnArray = array();
foreach ($table as $record) {
$returnArray[$record[$keyFieldTable][$keyFieldName]] = $record[$valueFieldTable][$valueFieldName];
}
return $returnArray;
}
}