PHP Classes

File: ohdb.class.php

Recommend this page to a friend!
  Classes of Leonardo Alberto Celis   Oh!DB Table Data Gateway   ohdb.class.php   Download  
File: ohdb.class.php
Role: Class source
Content type: text/plain
Description: Oh!DB Class
Class: Oh!DB Table Data Gateway
TDG (Table Data Gateway) for ADODB
Author: By
Last change: Fix in register navigator
Date: 16 years ago
Size: 33,093 bytes
 

Contents

Class file image Download
<? /** * @author Leonardo Alberto Celis * @name Oh!DB * @desc TDG (Table Data Gateway) for ADODB * @copyright 2005-2007 (c) Leonardo Alberto Celis * @blog http://leocelis.blogspot.com * @email celisla@hotmail.com * * Thanks to: * Mario Garcia: for find the being of this class and for put some good features * Federico Bergero: for find some catastrofics errores * Juan Cruz Borba: for find some catastrofics errores * * Related: * Martin Fowler: http://www.martinfowler.com/eaaCatalog/tableDataGateway.html * * * @todo * Make a Singleton, the schema could be in memory for every object table * Puts some examples in all the methods * Relocate all the names from the data model to properties * Multiple objects intances can interact with their own joins and filters * * @features * 13:14 25/06/2007 object suppor in addOrder method * 13:14 25/06/2007 setters and getters * 13:14 25/06/2007 addFunction for sum, max, min * 12:56 19/06/2007 add the filters of all de objects that is joined with this * 12:54 11/05/2007 join to oh!db objects support * * @bugs * 11:34 29/06/2007 Federico Bergero: if the value is empty, don't unset the field * 11:33 29/06/2007 Federico Bergero: if the field type is int and the send value is 0, set to null * 16:59 27/06/2007 Zend Code Analyzer free bugs * 14:00 27/06/2007 Federico Bergero: bug in buildFields, the secondary fields have precedence * 11:01 26/06/2007 Juan Cruz Borba: bug in buildFields and getMetaColumns methods, the fields in the object table must have * the "table." prefix only in the buildFields method. * 14:53 22/06/2007 still catastrofics errors in save method, now is fine * 18:38 20/06/2007 error with save method, the condition for insert/update was wrong * 15:00 20/06/2007 catastrofic error with save method, this convert the blank into null * 11:16 19/06/2007 buildJoins bug, if the table is an object the method add the logic field filter and the * left join become useless * 13:30 14/06/2007 Federico Bergero: bug in ohdb::buildFilters - precedence in logic field with other filters * 10:44 p.m. 05/06/2007 fix compatibility with logic field in save method * 09:44 p.m. 05/06/2007 fix compatibility with older version that doesn't have metacolumns * 09:29 05/06/2007 fix delete logic bug, delete the values of all the fields * */ class ohdb { // the ADODB object connection public $oADODB = ""; public $Table = ""; public $PrimaryKey = ""; public $Order = ""; public $joins = array(); public $filters = ""; public $functions = ""; public $Debug = false; public $LogicField = ""; public $ChildsTables = array(); public $xmlSQL = ""; public $sql = ""; public $bCache = false; public $nCacheTime = 0; public $bFirstRegister = false; public $bLastRegister = false; public $bLogic = false; // to upper public $bUpper = false; // validations public $RelatedTables = array(); // check relations public $sCodeErrorRelations = ""; //check for this fields public $sDuplicatedField = ""; public $sCodeErrorDuplicated = ""; // navigations constants public $nav_first = 1; public $nav_next = 2; public $nav_prev = 4; public $nav_last = 8; public $Limit = 0; public $Offset = 0; public $iLastID = 0; // private properties public $Fields = ""; private $DefaultField = ""; // MetaData array protected $aMetaColumns = ""; // MetaRules array protected $aMetaRules = ""; // Fields array private $aFields = ""; // String join protected $sJoinFields = ""; // xml dom object public $oDomIt = null; // validation object public $oValidation = null; // recycled public $oRecycled = null; // construct and destruct! function __construct($oADODB = null) { $this->oADODB = $oADODB; } function __destruct() { } /** * ======================================================= * Connection * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc ADODB Connection * * @todo handled multiple objects connections * */ function connectTo() { // by default take a global ADODB object if ($this->oADODB == '') { global $gobjADODB; $this->oADODB = $gobjADODB; } // if debug is active show the error message if ($this->Debug) { $this->oADODB->debug = true; } return $this->oADODB; } /** * ======================================================= * Setters and Getters * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc set the table * * @param unknown_type $psTableName */ public function setTable($psTableName) { $this->Table = $psTableName; } /** * @author Leonardo Alberto Celis * @desc set the primary key * * @param unknown_type $psPrimaryKey */ public function setPrimaryKey($psPrimaryKey) { $this->PrimaryKey = $psPrimaryKey; } /** * @author Leonardo Alberto Celis * @desc get all the selected rows by filters and joins * */ function getAll() { $sSQL = 'SELECT '; $sSQL .= self::buildFields(); $sSQL .= " FROM ".$this->Table; return self::RunSQL($sSQL); } /** * @author Leonardo Alberto Celis * @desc get max id * */ function getMaxID() { self::clean(); return self::RunSQL("SELECT MAX(" . $this->PrimaryKey . ") AS MaxID FROM " . $this->Table)->fields['MaxID']; } /** * @author Leonardo Alberto Celis * @desc get min id * */ function getMinID() { self::clean(); return self::RunSQL("SELECT MIN(" . $this->PrimaryKey . ") AS MinID FROM " . $this->Table)->fields['MinID']; } /** * @author Leonardo Alberto Celis * @desc get one row by id * */ public function getOne($id) { self::cleanFilters(); self::addFilter($this->PrimaryKey, "=", $id); return self::getAll(); } /** * @author Leonardo Alberto Celis * @desc get the first row * */ function getFirst() { self::clean(); $sSQL = "SELECT * FROM ".$this->Table . " order by " . $this->PrimaryKey . " LIMIT 0,1"; $this->Limit = 0; return self::RunSQL($sSQL); } /** * @author Leonardo Alberto Celis * @desc count rows * */ function getCount() { self::clean(); $sSQL = "SELECT COUNT(*) AS COUNT FROM ".$this->Table; $rs = self::RunSQL($sSQL); if ($rs->EOF) { return 0; } else { return $rs->fields['COUNT']; } } /** * @author Leonardo Alberto Celis * @desc sum all the values from the given field * */ function getSum($field) { //$this->clean(); //$sSQL = "SELECT SUM(" . $field . ") AS TOTAL FROM ".$this->Table; self::addFunction($field, $field, "SUM"); //return self::RunSQL($sSQL); } /** * @name Mario Garcia * @desc Get the recordset schema * */ function getRecordsetSchema($poRs) { $arrFields = array(); for($i=0; $i < $poRs->_numOfFields; $i++ ) { $arrFields[$poRs->FetchField($i)->name] = ""; } return array($arrFields); } /** * @author Emanuel Goette. * * @desc * * $primerRegistro: el registro donde empiesa a mostrar los datos * * $cantidad: cantidad de datos a mostrar. * */ function getAllPage($primerRegistro, $cantidad) { $sql = "SELECT * FROM ".$this->Table; $connect = self::connectTo(); $sql = self::buildJoins($sql); $sql = self::buildFilters($sql); $sql = self::buildOrder($sql); $sql = $sql." limit ".$primerRegistro." , ".$cantidad; $rs = $connect->Execute($sql); if (!$rs) { // if debug is active show the error message if ($this->Debug) { print $connect->ErrorMsg(); } } else { return $rs; //$rs->Close(); } return array(); } // spanish version public function getAllPagina($firstRegister, $count) { return self::getAllPage($firstRegister, $count); } /** * @author Leonardo Alberto Celis * @desc get rows, but not a rs object, an array! * */ function getOneToArray($id) { $rs = self::getOne($id); if ($rs->EOF) { return array(); } else { return $rs->GetRows(); } } function getAllToArray() { $rs = self::getAll(); if ($rs->EOF) { return array(); } else { return $rs->GetRows(); } } /** * @author Leonardo Alberto Celis * @desc set the fields to retrieve * * separate by comas */ public function setFields($string) { $this->Fields = $string; } /** * ======================================================= * Friendly methods * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc add functions to fields * */ public function addFunction($psField, $psAlias, $psFunction) { $this->functions[] = array($psField, $psAlias, $psFunction); } /** * @author Mario Garcia * @desc friendly method for add joins * * @param * xSecondaryTable: join to secondary table (not this object table) * */ function addJoin($psTableName, $paKeys = null, $paReturnFields = null, $psDirection = null, $xSecondaryTable = null) { // fields // if the pair paKeys is not defined if ($paKeys == null) { // primary $paKeys[0] // foreign $paKeys[0] if (is_object($psTableName)) { if ($this->PrimaryKey == '') die("Oh!DB: The primary key is not defined"); $paKeys[0] = $this->PrimaryKey; $paKeys[1] = $this->PrimaryKey; } if (is_object($xSecondaryTable)) { if ($xSecondaryTable->PrimaryKey == '' || $psTableName->PrimaryKey) die("ohdb::addJoin - The primary key is not defined"); $paKeys[0] = $xSecondaryTable->PrimaryKey; $paKeys[1] = $psTableName->PrimaryKey; } } // join secondary table if ($xSecondaryTable != null) { if (is_object($xSecondaryTable)) { $paKeys[0] = $xSecondaryTable->Table . "." . $paKeys[0]; } else { $paKeys[0] = $xSecondaryTable. "." . $paKeys[0]; } } // $psTableName could be an another Oh!DB object $aJoin = array ( 'table' => $psTableName, 'primary' => $paKeys[0], 'foreign' => $paKeys[1], 'direction' => $psDirection, ); $this->joins[] = $aJoin; // preserve the object table if (is_object($psTableName)) { $sTable = $psTableName->Table; } else { $sTable = $psTableName; } // return fields if (is_array($paReturnFields)) { //foreach($paReturnFields as $sKey => $sValue) foreach($paReturnFields as $sValue) { if (stripos($sValue, ".") === false ) { $this->sJoinFields .= ",$sTable.$sValue"; } else { $this->sJoinFields .= ",$sValue"; } } } else { $this->sJoinFields .= ",{$sTable}.*"; } } /** * @author Mario Garcia * @desc friendly method for add filters * */ function addFilter($psField = null, $psCriteria, $psValue, $psTableName = null, $psOperador = null, $psFunction = null) { // by default the primarykey if (is_null($psField)) $psField = $this->PrimaryKey; if (is_null($psTableName)) { $psTableName = $this->Table; } $aFilter = array ( 'field' => $psTableName.'.'.$psField, 'condition' =>$psCriteria, 'value' => $psValue ); if(!empty($psOperador)) { $aFilter['operator'] = $psOperador; } if(!empty($psFunction)) { $aFilter['function'] = $psFunction; } $this->filters[] = $aFilter; } /** * @author Mario Garcia * @desc friendly method for add rules * */ function addRules($psCriteria, $psFieldName, $psMessageError) { $this->aMetaRules[] = $psCriteria.','.$psFieldName.','.$psMessageError; } /** * @author Mario Garcia * @desc friendly method for add orders * */ function addOrder($psTableName = null, $psField , $psDirection = null) { // if it's a object if (is_object($psTableName)) { $psTableName = $psTableName->Table; } // if it's null if ($psTableName == null) { $psTableName = $this->Table; } $this->Order[] = $psTableName.'.'.$psField.' '.$psDirection; } /** * ======================================================= * Transactions * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc handled transactions * */ public function startTransaction() { $connect = self::connectTo(); $connect->StartTrans(); } public function endTransaction() { $connect = self::connectTo(); return $connect->CompleteTrans(); } /** * ======================================================= * Core * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc this is the core baby! * */ public function RunSQL($sql) { $connect = self::connectTo(); $sql = self::buildJoins($sql); $sql = self::buildFilters($sql); $sql = self::buildOrder($sql); // if it has function used group by if ($this->functions != '') { $sql .= " GROUP BY " . $this->Table . "." . $this->PrimaryKey; } // if it the cache is on if ($this->bCache) { if ($this->Limit != 0 || $this->Offset != 0) { $rs = $connect->CacheSelectLimit($this->nCacheTime, $sql, $this->Limit, $this->Offset); } else { $rs = $connect->CacheExecute($this->nCacheTime, $sql); } } else { if ($this->Limit != 0 || $this->Offset != 0) { $rs = $connect->SelectLimit($sql, $this->Limit, $this->Offset); } else { $rs = $connect->Execute($sql); } } $this->sql = $sql; if (!$rs) { if ($this->Debug) { echo $connect->ErrorMsg(); die(); } } else { $this->AffectedRows = $connect->Affected_Rows(); return $rs; } return array(); } /** * @author Leonardo Alberto Celis * @desc build fields * */ private function buildFields() { $sFunctions = $this->functions; // if the fields has functions if ($sFunctions != '') { for ($i = 0; $i < count($sFunctions); $i++) { /*[0] // field [1] // alias [2] // function*/ $sSQL .= ", " . $sFunctions[$i][2] . "(" . $this->Table . "." . $sFunctions[$i][0] . ") as " . $sFunctions[$i][1] . " "; } //$sSQL .= $sSQL . ", "; $sSQL = substr($sSQL,1); $sSQL .= ", "; } if ($this->Fields != '') { //if (!is_array($this->aFields)) //{ $aFieldsTmp = split(",", $this->Fields); $sFields = ""; //foreach($aFieldsTmp as $sKey => $aValue) foreach($aFieldsTmp as $aValue) { $sFields .= "," . trim($this->Table) . "." . trim($aValue) . " "; } $this->Fields = substr($sFields,1); //} $sSQL .= $this->Fields; } else { $sSQL .= $this->Table . '.*'; } // secondary fields if ($this->sJoinFields != '' && $this->sJoinFields != null) { $sSQL .= $this->sJoinFields; } return $sSQL; } /** * @author Leonardo Alberto Celis * @desc Build the SQL statement based on relations with other tables * * @updated The table element could be an object, so is posibble to join to * another Oh!DB objects * */ public function buildJoins($sql) { $joins = $this->joins; if (count($joins) > 0 && $joins != '') { foreach ($joins as $join) { if (is_object($join['table'])) { $sJoinTable = $join['table']->Table; // if the join object has filters bring them to this object $filters = $join['table']->filters; if ($filters != '' && count($filters) > 0) { // loop for all the filters and add to this object for ($i = 0; $i < count($filters); $i++) { $this->filters[] = $filters[$i]; } } } else { $sJoinTable = $join['table']; } // si viene un join if ($join['direction'] != null && $join['direction'] != '') { $sql .= ' ' . $join['direction'] . ' JOIN ' . $sJoinTable .' '; } else { //$sql .= ' INNER JOIN ' . $join['table'] .' '; $sql .= ' INNER JOIN ' . $sJoinTable .' '; } if (isset($join['primary'])) { // mitabla as tbl // Uso de Alias en la tabla if( stripos($sJoinTable ,' as ') > 0 ) { $sJoinTable = substr( $sJoinTable , stripos($sJoinTable ,' as ') + 3); } $table = $this->Table; if (stripos($join['primary'], ".") !== false ) $table = ""; $sql .= ' ON ' . $table . '.' . $join['primary'] . '=' . $sJoinTable . '.' . $join['foreign'] . ' '; } } } return $sql; } /** * @author Leonardo Alberto Celis * @desc Build the filters * */ public function buildFilters($sql) { $filters = $this->filters; if (($filters != '' && count($filters) > 0) || $this->bLogic) $sql .= " WHERE "; if ($this->bLogic) { $sql .= $this->Table . "." . $this->LogicField . " = 1 "; if ($filters != '' && count($filters) > 0) { $sql .= " AND "; } } $filters = $this->filters; if ($filters != '' && count($filters) > 0) { if ($this->bLogic) { $sql .= " ( "; } $i = 0; foreach ($filters as $filter) { if ($filter['function'] != '' || $filter['function'] != null) { $sql .= " " . $filter['function'] . '(' . $filter['field'] . ") " . $filter['condition'] . " '" . $filter['value'] . "'"; } else { $sql .= " " . $filter['field'] . " " . $filter['condition'] . " '" . $filter['value'] . "'"; } if ($i < count($filters)-1) { if (isset($filter['operator']) && ($filter['operator'] != '' || $filter['operator'] != null)) { $sql .= ' ' . $filter['operator']; } else { $sql .= ' AND'; } } $i++; } if ($this->bLogic) { $sql .= " ) "; } } return $sql; } /** * @author Leonardo Alberto Celis * @desc Build the orders * */ public function buildOrder($sql) { if (is_array($this->Order)) { $sql .= " ORDER BY "; $sField = ""; foreach($this->Order as $sKey ){ $sField .= ",$sKey" ; } $sql .= substr($sField,1); } return $sql; } /** * ======================================================= * Meta * ======================================================= */ /** * @author Mario Garcia * @desc this method is cancel, the validation rules must be in another class * */ function initMetaRules() { // example: //$this->arrRules[] = "required,varOriNombre,El varOriNombre es requerido."; /*foreach($this->aMetaColumns as $sKey => $aMetaColumn) { if($aMetaColumn->primary_key) continue; if($aMetaColumn->not_null ) { $this->aMetaRules[] = "required,{$aMetaColumn->name}, Es requerido."; } switch($aMetaColumn->type) { case 'int': $this->aMetaRules[] = "digits_only,{$aMetaColumn->name},Ingrese un valor numerico."; break; //decimal,text,tinyint,date? } }*/ return null; } /** * @author Mario Garcia * @desc this is awesome!, get the schema for the given table * */ function getMetaColumns() { // pacth for store procedure sync error //if( is_object(self::connectTo()->_queryID) ) mysqli_free_result(self::connectTo()->_queryID); $dataDictionary = NewDataDictionary(self::connectTo()); if(!$this->Table) return array(); $aMetaColumns = $dataDictionary->MetaColumns($this->Table); $aFields = array(); $sFields = ""; if (is_array($aMetaColumns)) { //foreach($aMetaColumns as $sKey => $aValue) foreach($aMetaColumns as $aValue) { $aFields[] = $aValue->name; //$sFields .= ",$this->Table.$aValue->name"; $sFields .= ",$aValue->name"; if($aValue->primary_key){ $this->PrimaryKey = $aValue->name; } } } $this->aFields = $aFields; $this->Fields = substr($sFields,1); $this->aMetaColumns = $aMetaColumns; return $this->aMetaColumns; } /** * @author Mario Garcia * @desc init the meta, get the schema, empowered the object * */ function initMeta() { //Este metodo carga en $this->aMetaColumns toda la info de la metadata //Tiene que ser llamado despues de inicializar $this->Table = "tblProOrigenes"; //y tiene que ser llamado solo en el constructor self::getMetaColumns(); //luego de crear la metadata creo las metas rules self::initMetaRules(); } /** * ======================================================= * Write actions * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc the other core! * * @todo Unified save and RunSQL methods * */ function save($data) { //if (is_array($this->aFields) && $data[$this->LogicField] != '0') if (is_array($this->aFields)) { $aSave = null; foreach($this->aFields as $lnKey) { // if exists in the save array if (isset($data[$lnKey])) { $sType = $this->aMetaColumns[strtoupper($lnKey)]->type; // upper case if (($sType == 'char' || $sType == 'longtext' || $sType == 'mediumtext' || $sType == 'text' || $sType == 'tinytext' || $sType == 'varchar' ) && $this->bUpper) { $this->str2Upper($data[$lnKey]); } // if it's int and the value is 0, set to null if (($sType == 'int' || $sType == 'tinyint' || $sType == 'bigint' || $sType == 'decimal' || $sType == 'double' || $sType == 'float' || $sType == 'mediumint' || $sType == 'numeric' || $sType == 'smallint' ) && $data[$lnKey] == '') { $data[$lnKey] = "null"; } $aSave[$lnKey] = $data[$lnKey]; } } if (!is_null($aSave)) $data = $aSave; } // if the logic delete is active; if ($this->bLogic) { if ($data[$this->LogicField] != '0') { $data[$this->LogicField] = '1'; } } // connection $connect = self::connectTo(); // for checkbox? /*foreach( $data as $key => $value) { if (strtolower($value) == 'on') { $data[$key] = '1'; } }*/ $ok = true; if (isset($data[$this->PrimaryKey]) && $data[$this->PrimaryKey] != "null") { // update $ok = $connect->replace($this->Table, $data, $this->PrimaryKey, true); $this->iLastID = $data[$this->PrimaryKey]; } else { // insert $ok = $connect->AutoExecute($this->Table, $data, 'INSERT'); $this->iLastID = $connect->Insert_ID(); } return $ok; } /** * @author Leonardo Alberto Celis * @desc delete the row * */ //function delete($id, $data = null) function delete($id) { // logic delete if ($this->bLogic) { //$this->deleteLogic($id, $data); self::deleteLogic($id); } else { self::clean(); $sSQL = "DELETE FROM ".$this->Table." WHERE ".$this->PrimaryKey." = ".$id; return self::RunSQL($sSQL); } return array(); } /** * @author Leonardo Alberto Celis * @desc delete the selected rows by filters * */ public function deleteAll() { self::cleanJoins(); $sSQL = "DELETE FROM " . $this->Table; return self::RunSQL($sSQL); } /** * @author Leonardo Alberto Celis * @desc logic delete * */ //function deleteLogic($id, $data) function deleteLogic($id) { $data[$this->PrimaryKey] = $id; $data[$this->LogicField] = '0'; self::save($data); self::cascadeDeleteLogic($this, $this->PrimaryKey, $id); } /** * @author Leonardo Alberto Celis * @desc Cascade logic delete * * @todo Change the Execute to RunSQL */ function cascadeDeleteLogic($pobjTable, $pKey, $pId) { // get the adodb object connection $connect = self::connectTo(); // set the logic field in 0 $data[$this->LogicField] = '0'; if (count($pobjTable->ChildsTables) > 0 && $pobjTable->ChildsTables != '') { foreach( $pobjTable->ChildsTables as $value ) { $objTable = new $value; $objTable->addFilter($pKey, "=", $pId); $rsChilds = $objTable->getAll(); if (!$rsChilds->EOF) { while (!$rsChilds->EOF) { $connect->AutoExecute($objTable->Table, $data, 'UPDATE', $pKey . '=' . $pId); $objTable->cascadeDeleteLogic($objTable, $objTable->PrimaryKey, $rsChilds->fields[$objTable->PrimaryKey], 0); $rsChilds->MoveNext(); } } } } } /** * @author Leonardo Alberto Celis * @desc Retrieved from Recycled * * @todo This has to be in a Recycled object * */ function retrieveFromRecycled($pobjTable, $pId) { $oRecycled = $this->oRecycled; $connect = self::connectTo(); $data[$this->LogicField] = '1'; if (count($pobjTable->ChildsTables) > 0 && $pobjTable->ChildsTables != '') { foreach( $pobjTable->ChildsTables as $value ) { $objTable = new $value; $objTable->addFilter($pobjTable->PrimaryKey, "=", $pId); $rsChilds = $objTable->getAll(); if (!$rsChilds->EOF) { while (!$rsChilds->EOF) { $oRecycled->addFilter('varPapTabla', '=', $objTable->Table, null, 'AND'); $oRecycled->addFilter('varPapCampoClave', '=', $objTable->PrimaryKey, null, 'AND'); $oRecycled->addFilter('intPapRegID', '=', $rsChilds->fields[$objTable->PrimaryKey], null); $rsDeleted = $oRecycled->getAll(); if ($rsDeleted->EOF) { $connect->AutoExecute($objTable->Table, $data, 'UPDATE', $pobjTable->PrimaryKey . '=' . $pId); } $objTable->retrieveFromRecycled($objTable, $rsChilds->fields[$objTable->PrimaryKey]); $rsChilds->MoveNext(); } } } } } /** * ======================================================= * Validations * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc check for duplicated rows * */ public function checkDuplicated ($id = null, $name = null) { $o = $this; // check for duplicated register if ($this->sCodeErrorDuplicated != '' && $this->sDuplicatedField != '') { $o->addFilter($this->sDuplicatedField, '=', $name); // if the id is specified then check for all except the id if ($id != '') $o->addFilter($this->PrimaryKey, '<>', $id); // if the login field is set if ($this->bLogic) { $o->addFilter($this->LogicField, '=', '1'); } $rs = $o->getAll(); if (!$rs->EOF) { return false; } else { return true; } } return false; } /** * @author Leonardo Alberto Celis * @desc Check if the register id exists * */ function validateUnique($id) { self::clean(); self::addFilter($this->PrimaryKey, "=", $id, null, null); $rs = self::getAll(); self::clean(); return !$rs->EOF; } /** * @author Mario Garcia * @desc validate metarules * */ function validateMetaRules( $aValues) { return validateFields($aValues, $this->aMetaRules); } /** * @name Leonardo Alberto Celis * @desc check for relations in another tables * */ public function checkRelations($id) { $ok = true; // check for relationed tables if (count($this->ChildsTables) > 0 && $this->ChildsTables != '') { foreach( $this->ChildsTables as $value ) { $oTable = new $value; $oTable->addFilter($this->PrimaryKey, "=", $id, null, null); $rsChilds = $oTable->getAll(); if (!$rsChilds->EOF) { $ok &= false; } } } // check for related tables if (count($this->RelatedTables) > 0 && $this->RelatedTables != '') { foreach( $this->RelatedTables as $value ) { $oTable = new $value; $oTable->addFilter($this->PrimaryKey, "=", $id, null, null); $rsChilds = $oTable->getAll(); if (!$rsChilds->EOF) { $ok &= false; } } } return $ok; } /** * ======================================================= * Cleaning * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc Clean objects properties * */ function clean() { //$this->JoinFields = ""; $this->Order = ""; $this->sJoinFields = ""; //$this->aFields = ""; $this->Fields = ""; $this->functions = ""; $this->filters = ""; $this->joins = ""; /** * @desc Patch: reload the schema */ //$this->initMeta(); } /** * @author Leonardo Alberto Celis * @desc Clean the filters * */ function cleanFilters() { $this->filters = null; self::initMeta(); } /** * @author Leonaro Alberto Celis * @desc remove the last apply filter */ public function removeLastFilter() { $this->filters = array_slice($this->filters, 0, count($this->filters)-1); self::initMeta(); } /** * @author Leonardo Alberto Celis * @desc Clean the joins * */ function cleanJoins() { $this->joins = null; self::initMeta(); } /** * ======================================================= * Cool stuff * ======================================================= */ /** * @author Leonardo Alberto Celis * @desc Change to Upper only the alphabetical characters * */ private function str2Upper($psString) { $psString = mb_convert_case($psString, MB_CASE_UPPER, "UTF-8"); return $psString; } /** * @author Mario Garcia * @desc Execute a Store Procedure * */ public function ExecuteSP($psSPName, $paSPParameters) { $lsSQLParm = ""; foreach ($paSPParameters as $lsValue) { //$lsSQLParm .= ",?"; $lsSQLParm .= ",{$lsValue}"; } $lsSQLParm = substr($lsSQLParm,1); $lsSQLSP = "CALL {$psSPName} ({$lsSQLParm})"; $connect = self::connectTo(); $lmRS = $connect->Execute($lsSQLSP, $paSPParameters); return $lmRS; } /** * @author Leonardo Alberto Celis * @desc rows navigator * */ public function navigator($piConst, $piID) { switch ($piConst) { case $this->nav_first: //$this->removeLastFilter(); $this->Limit = 1; self::addOrder(null, $this->PrimaryKey, "ASC"); $rs = self::getAll(); if ($rs->EOF) { return self::getRecordsetSchema($rs); } else { //return $rs->getRows(); return $rs; } break; case $this->nav_next: $this->Limit = 1; self::addFilter($this->PrimaryKey, ">", $piID); $rs = self::getAll(); if ($rs->EOF) { $this->removeLastFilter(); return self::navigator($this->nav_first, null); } else { //return $rs->GetArray(1); return $rs; } break; case $this->nav_prev: self::addFilter($this->PrimaryKey, "<", $piID); $rs = self::getAll(); if ($rs->EOF) { $this->removeLastFilter(); return self::navigator($this->nav_last, null); } else { $rs->MoveLast(); //return $rs->GetArray(1); return $rs; } break; case $this->nav_last: //$this->removeLastFilter(); $this->Limit = 1; self::addOrder(null, $this->PrimaryKey, "DESC"); $rs = self::getAll(); if ($rs->EOF) { return self::getRecordsetSchema($rs); } else { return $rs; } break; } return array(); } /** * @author Leonardo Alberto Celis * @desc this is experimental, the xml query! * */ function xmlQuery($pstrTag, $parrParams = array()) { // the domit object, only this object! $success = $this->oDomIt->loadXML($this->xmlSQL, true); if ($success) { //use getElementsByTagName to gather all elements named "cd" $matchingNodes =& $this->oDomIt->getElementsByTagName($pstrTag); //if any matching nodes are found, echo to browser if ($matchingNodes != null) { $temp = $matchingNodes->item(0); $sql = $temp->getText(); if (count($parrParams) > 0) { for ($i = 0; $i < count($parrParams); $i++) { $sql = str_replace('@param' . $i, $parrParams[$i], $sql); } } $connect = self::connectTo(); return $connect->Execute($sql); } else { return false; } } else { return false; } } } ?>