File indexing completed on 2024-12-22 05:33:23

0001 <?php
0002 
0003 /*
0004  *   GFX 4.0
0005  * 
0006  *   support: happy.snizzo@gmail.com
0007  *   website: http://trt-gfx.googlecode.com
0008  *   credits: Claudio Desideri
0009  *   
0010  *   This software is released under the MIT License.
0011  *   http://opensource.org/licenses/mit-license.php
0012  */ 
0013 
0014 /*
0015  * fields()
0016  * insert()
0017  * find()
0018  * count()
0019  * delete()
0020  * update()
0021  */
0022 
0023 class EModel {
0024   //in order to avoid avoidable queries
0025   private $dbg = false;
0026   private $ready = false;
0027   private $tcount = "nd";
0028   private $table = false;
0029   private $fields = array();
0030   private $noquery = false;
0031   
0032   private $conditions = "";
0033   private $is_first_contidion = true;
0034   
0035   public function __construct($tbl=""){
0036     if(!empty($tbl)){
0037       $this->table = $tbl;
0038       if(EDatabase::table_exists($this->table)){
0039         $this->get_table_info();
0040       } else {
0041         ELog::error("$tbl does not exists on database.");
0042       }
0043       
0044       $this->dbg = false;
0045       $this->ready = true;
0046     }
0047   }
0048   
0049   
0050   
0051   /**
0052    * Prints debug informations about a database table.
0053    */
0054   public function print_debug_info(){
0055     echo "tcount: ".$this->tcount."<br>";
0056     echo "table: ".$this->table."<br>";
0057     echo "fields: <br><pre>";
0058     var_dump($this->fields); 
0059     echo "</pre>";
0060   }
0061   
0062   /**
0063    * Set this to true in order to make EData just simulate modifications
0064    * and echo the query. Use only for debug purposes.
0065    */
0066   public function set_simulate($b){
0067     $this->noquery = $b;
0068   }
0069   
0070   /**
0071    * Rewrite debug rule.
0072    */
0073   public function set_debug($b){
0074     $this->dbg = $b;
0075   }
0076   
0077   /**
0078    * check if table is loaded,
0079    * if not, empty model is been used
0080    * and warning is printed
0081    */
0082   public function is_ready_test(){
0083     if(!$this->ready){
0084       ELog::warning("EModel without table has been used. Please fix this.");
0085     }
0086     return $this->ready;
0087   }
0088   
0089   /*
0090    * Load info from a database table.
0091    * Results are also cached.
0092    * TODO: move cache to new ECacheVar.
0093    */
0094   private function get_table_info(){
0095     //TODO: this makes no sense...
0096     //if(!$this->is_ready_test()) { return; }
0097     //if already cached load from cache else load with a describe AND cache
0098     $cache_name = $this->table.".table";
0099     if(ECacheVar::exists($cache_name)){
0100       $cache = new ECacheVar($cache_name);
0101       $data = $cache->get_array_assoc(); 
0102       foreach($cache as $key => $value){
0103         $fields[] = array("field" => $key,"type" => $value);
0104       }
0105       
0106     } else {
0107       $cache = new ECacheVar($cache_name);
0108       
0109       $describe = EDatabase::q("DESCRIBE ".$this->table);
0110       
0111       while($row=$describe->fetch_array()){
0112         $type = "null";
0113         if(stristr($row['Type'], "varchar")){ $type = "varchar"; }
0114         if(stristr($row['Type'], "int")){ $type = "int"; }
0115         if(stristr($row['Type'], "text")){ $type = "text"; }
0116         
0117         $this->fields[] = array("field" => $row['Field'],"type" => $type);
0118         
0119         $cache->set($row['Field'],$type);
0120       }
0121     }
0122   }
0123   
0124   /*
0125    * Returns all fields contained in table structure.
0126    */
0127   public function fields(){
0128     return $this->fields;
0129   }
0130   
0131   /*
0132    * Perform an automatic insert using data passed through GET/POST.
0133    * To use only if user has every access to the database table.
0134    * 
0135    * Note that is $allowed_arrays is empty, every field is considered valid.
0136    * TODO: fix this retrocompatibility crap ^^^
0137    */
0138   public function insert($allowed_fields=array()) {
0139     if(!$this->is_ready_test()) { return; }
0140     //accepting eventual data as valid
0141     if(!empty($allowed_fields)){
0142       foreach($this->fields as $field){
0143         if(EHeaderDataParser::exists_post($field['field']) and in_array($field['field'],$allowed_fields)){
0144           $entries[] = array("field" => $field['field'], "value" => EHeaderDataParser::db_post($field['field']), "type" => $field['type']);
0145         }
0146       }
0147     } else {
0148       foreach($this->fields as $field){
0149         if(EHeaderDataParser::exists_post($field['field']) ){
0150           $entries[] = array("field" => $field['field'], "value" => EHeaderDataParser::db_post($field['field']), "type" => $field['type']);
0151         }
0152       }
0153     }
0154     
0155     if(!empty($entries)){
0156       $sql = "INSERT INTO ".$this->table." ("; //starting query
0157       foreach($entries as $entry){ $sql = $sql.$entry['field'].","; } //insert in queries all the fields we're going to accept
0158       $sql = rtrim($sql,",").") VALUES (";
0159       foreach($entries as $entry){
0160         //type check against type field found with describe
0161         if($field['type']=="varchar" or $field['type']=="text"){
0162           $sql = $sql."'".$entry['value']."',";
0163         } else if($field['type']=="int") {
0164           if(preg_match("/[^0-9]/", $entry['value'])){
0165             ELog::error("EData Object Error: wrong data passed for <i><big>`".$field['field']."`</big></i> with type `INT`! freezing...");
0166           }
0167           $sql = $sql.$entry['value'].",";
0168         }
0169       }
0170       $sql = rtrim($sql,",").")"; // cleaning and ending query
0171       
0172       //outputting or executing
0173       if($this->noquery==false){
0174         EDatabase::q($sql);
0175       } else {
0176         echo $sql;
0177       }
0178     }
0179   }
0180   
0181   /*
0182    * Extrapolates data and map it into an associative array
0183    */
0184   public function find($what=" * ", $where="") {
0185     if(!$this->is_ready_test()) { return; }
0186     
0187     //build the query, if any condition is present, attach right conditions
0188     $q = "SELECT $what FROM ".$this->table;
0189     if(!empty($this->conditions)){ $q .= ' '.$this->conditions.' '; }
0190     $q .= " $where";
0191     
0192     $r = EDatabase::q($q);
0193     while($arr = $r->fetch_assoc()){
0194       $result[] = $arr;
0195     }
0196     
0197     if($this->noquery==false){
0198       if(isset($result)){
0199         return $result;
0200       } else {
0201         return false;
0202       }
0203     } else {
0204       echo $q;
0205     }
0206   }
0207   
0208   public function add_condition($c){
0209     if($this->is_first_contidion){
0210       $this->conditions .= " WHERE $c ";
0211       $this->is_first_contidion = false;
0212     } else {
0213       $this->conditions .= " AND $c ";
0214     }
0215   }
0216   
0217   /*
0218    * Return result from a single query.
0219    * Example: COUNT(....) returns 56. This method returns 56.
0220    */
0221   public function take($what=" * ", $where="") {
0222     if(!$this->is_ready_test()) { return; }
0223     if(!empty($where)){ $where = " WHERE ".$where." "; }
0224     
0225     $result = EDatabase::sq("SELECT $what FROM ".$this->table." $where");
0226     
0227     return $result;
0228     
0229   }
0230   
0231   /*
0232    * Return a single row from an associative array
0233    */
0234   public function row($what=" * ", $where="") {
0235     if(!$this->is_ready_test()) { return; }
0236     if(!empty($where)){ $where = " ".$where." "; }
0237     
0238     $r = EDatabase::q("SELECT $what FROM ".$this->table." $where");
0239     
0240     while($row=$r->fetch_array()){
0241       $result = $row;
0242     }
0243     
0244     return $result;
0245     
0246   }
0247   
0248   /*
0249    * Performs counts on selected table.
0250    * TODO: maybe a little refactor using db->sq()?
0251    */
0252   public function count($field="id", $where=""){
0253     if(!$this->is_ready_test()) { return; }
0254     //optimized... only one query in a page!
0255     if($this->tcount!="nd"){
0256       return $this->tcount;
0257     }
0258     
0259     if(!empty($where)){ $where = " WHERE ".$where." "; }
0260     
0261     $r = EDatabase::q("SELECT COUNT($field) FROM ".$this->table." $where");
0262     while($row=$r->fetch_array()){
0263       $result = $row[0];
0264     }
0265     
0266     $this->tcount = $result;
0267     return $result;
0268   }
0269   
0270   /*
0271    * check if exists a $field in $this->table $where
0272    */
0273   public function is_there($field="", $where=""){
0274     if(!$this->is_ready_test()) { return; }
0275     $result = $this->count($field, $where);
0276     if($result){
0277       return true;
0278     } else {
0279       return false;
0280     }
0281   }
0282   
0283   /*
0284    * Deletion method.
0285    */
0286   public function delete($where="", $howmany=""){
0287     if(!$this->is_ready_test()) { return; }
0288     if(!empty($where)){ $where = " WHERE ".$where." "; }
0289     if(!empty($howmany)){ $howmany = " LIMIT ".$howmany." "; }
0290     
0291     EDatabase::q("DELETE FROM ".$this->table." $where $howmany");
0292   }
0293   
0294   
0295   /*
0296    * Automatic update method. Works basically like insert method.
0297    * Remember to specifies $where when used!
0298    */
0299   public function update($where="", $allowed_fields=array()) {
0300     if(!$this->is_ready_test()) { return; }
0301     //recupero le informazioni di where
0302     if(!empty($where)){ $where = " WHERE ".$where." "; }
0303     
0304     //recupero le informazioni automaticamente
0305     if(!empty($allowed_fields)){
0306       foreach($this->fields as $field){
0307         if($field['field']!="id"){
0308           if(EHeaderDataParser::exists_post($field['field']) and in_array($field['field'],$allowed_fields)){
0309             $entries[] = array("field" => $field['field'], "value" => EHeaderDataParser::db_post($field['field']), "type" => $field['type']);
0310           }
0311         }
0312       }
0313     } else {
0314       foreach($this->fields as $field){
0315         if($field['field']!="id"){
0316           if(EHeaderDataParser::exists_post($field['field']) ){
0317             $entries[] = array("field" => $field['field'], "value" => EHeaderDataParser::db_post($field['field']), "type" => $field['type']);
0318           }
0319         }
0320       }
0321     }
0322     //costruisco la query ed eseguo se ho le informazioni in entries
0323     if(!empty($entries)){
0324       $sql = "UPDATE ".$this->table." SET ";
0325       foreach($entries as $entry){
0326         $sql = $sql.$entry['field']."=";
0327         if($entry['type']=="int"){
0328           if(!is_numeric($entry['value'])){
0329             //data type error
0330             echo "<span style=\"font-family:Arial,sans-serif\">Warning! GFX3 <span style=\"color:red\">EData Object Error</span>: wrong data passed for <i><big>`".$field['field']."`</big></i> with type `INT`! freezing...</span><br>";
0331             die();
0332           }
0333           $sql = $sql.$entry['value'].",";
0334         } else {
0335           $sql = $sql."'".$entry['value']."',";
0336         }
0337       }
0338       $sql = rtrim($sql,",")." $where";
0339       
0340       if($this->noquery==false){
0341         EDatabase::q($sql);
0342       } else {
0343         echo $sql;
0344       }
0345     } else {
0346       //ELog::warning("EData->update called with empty entries");
0347     }
0348   }
0349   
0350 }
0351 
0352 ?>