<?php
// EasyGiant is a PHP framework for creating and managing dynamic content
//
// Copyright (C) 2009 - 2011 Antonio Gallo
// See COPYRIGHT.txt and LICENSE.txt.
//
// This file is part of EasyGiant
//
// EasyGiant is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// EasyGiant is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with EasyGiant. If not, see <http://www.gnu.org/licenses/>.
if (!defined('EG')) die('Direct access not allowed!');
class Model_Tree extends Model_Base {
public function __construct() {
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 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
//$tableName: the table name ($this->_tablesArray)
//$choice:all->all the tables in $this->_arrayTables, other value->only the table of $this->_arrayTables ad index $index
//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))
{
$on = array();
if (isset($where) and isset($wherePlus))
{
$where .= ' AND ' . $wherePlus;
}
else if (!isset($where) and isset($wherePlus))
{
$where .= $wherePlus;
}
}
else
{
$on = (isset($where[0]) and strcmp($where[0],'-') !== 0) ? $where : array();
$where = $wherePlus;
}
return array('tables' => $tables,'where' => $where,'fields'=>$fields,'on'=>$on);
}
//method to obtain the values of the whole tree
//$choice:all->all the tables in $this->_arrayTables, other value->only the table of $this->_arrayTables ad index $index
public function getAll($choice = 'all') {
return $this->getFields('',$choice);
}
//method to get the values of the selected fields
//it walks the tree by means of a join query
//$fields: the fields that have to be excracted from the tableName
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);
}
public function send()
{
$table = $this->getFields($this->select);
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;
}
}
//call the getAll method with $tableName = $this->_tablesArray[0]
//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) {
$tempWhere = $this->where;
$this->setWhereQueryClause(array($this->_idFieldsArray[0] => (int)$id));
$this->using = null;
if (isset($fields))
{
$values = $this->getFields($fields,'other');
}
else
{
$values = $this->getAll('other');
}
$this->where = $tempWhere;
return (count($values) > 0) ? $values[0][$this->_tablesArray[0]] : array();
}
//get the number of records ()
//the number of records of the table $tableName is returned
public function rowNumber() {
$elements = $this->treeQueryElements($this->_tablesArray[0]);
return $this->db->get_num_rows($elements['tables'],$elements['where'],$this->groupBy,$elements['on'],$this->using,$this->join);
}
public function getMax($field)
{
$elements = $this->treeQueryElements($this->_tablesArray[0]);
return $this->db->getMax($elements['tables'],$field,$elements['where'],$this->groupBy,$elements['on'],$this->using,$this->join);
}
public function getMin($field)
{
$elements = $this->treeQueryElements($this->_tablesArray[0]);
return $this->db->getMin($elements['tables'],$field,$elements['where'],$this->groupBy,$elements['on'],$this->using,$this->join);
}
public function getSum($field)
{
$elements = $this->treeQueryElements($this->_tablesArray[0]);
return $this->db->getSum($elements['tables'],$field,$elements['where'],$this->groupBy,$elements['on'],$this->using,$this->join);
}
public function getAvg($field)
{
$elements = $this->treeQueryElements($this->_tablesArray[0]);
return $this->db->getAvg($elements['tables'],$field,$elements['where'],$this->groupBy,$elements['on'],$this->using,$this->join);
}
//check if the table has the field $field equal to $value
public function has($field,$value)
{
$elements = $this->treeQueryElements($this->_tablesArray[0]);
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)
{
$this->queryResult = 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
//$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
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();
if (strcmp($keyFieldTable,$valueFieldTable) !== 0) {
throw new Exception("the tables '$valueFieldTable' and '$keyFieldTable' do not match in ".__METHOD__);
}
if (!in_array($keyFieldTable,$this->_tablesArray)) {
throw new Exception("the table '$keyFieldTable' is not allowed in ".__METHOD__);
}
$elements = $this->treeQueryElements($keyFieldTable,'');
$table = $this->db->select($elements['tables'],$fields,$elements['where'],$groupBy,$orderBy,$limit,$elements['on'],$this->using);
$this->where = $temp;
$returnArray = array();
foreach ($table as $record) {
$returnArray[$record[$keyFieldTable][$keyFieldName]] = $record[$valueFieldTable][$valueFieldName];
}
return $returnArray;
}
}