aboutsummaryrefslogtreecommitdiff
path: root/h-source/Library/Model/Tree.php
diff options
context:
space:
mode:
Diffstat (limited to 'h-source/Library/Model/Tree.php')
-rwxr-xr-xh-source/Library/Model/Tree.php560
1 files changed, 465 insertions, 95 deletions
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