The ORM: the abstract model layer

Introduction

The framework ORM is inspired on everything i could see: one file by table grouped in the model directory
A file example:
It is base on this points:
- performance
- transparency
- ergonomy


  
<?php
class model_article extends abstract_model{
  
   
protected $sClassRow='row_article';
  
   
protected $sTable='article';
   protected $sConfig='xml';
  
   
protected $tId=array('id');

   public static function getInstance(){
       return self::_getInstance(__CLASS__);
   }

   public function findById($id){
       return $this->findOne('SELECT * FROM '.$this->sTable.' WHERE id=?',$id );
   }
   public function findAll(){
       return $this->findMany('SELECT * FROM '.$this->sTable.' ORDER BY id ASC');
   }
  
}

class 
row_article extends abstract_row{
  
   
protected $sClassModel='model_article';
  
   
public function findAuteur(){
       return model_auteur::getInstance()->findById($this->auteur_id);
   }
  
   
//provide the way to check data coherence
   private function getCheck(){
       $oPluginValid=new plugin_valid($this->getTab());
       /* renseigner vos check ici
       $oPluginValid->isEqual('Field','valueB','Field should be equal to valueB');
       $oPluginValid->isNotEqual('Field','valueB','Field should not be equal to valueB');
       $oPluginValid->isUpperThan('Field','valueB','Field should upper than valueB');
       $oPluginValid->isUpperOrEqualThan('Field','valueB','Field should upper or equal than valueB');
       $oPluginValid->isLowerThan('Field','valueB','Field should lower than valueB');
       $oPluginValid->isLowerOrEqualThan('Field','valueB','Field should lower or equal than valueB');
       $oPluginValid->isEmpty('Field','Field should empty');
       $oPluginValid->isNotEmpty('Field','Field should not be empty');
       $oPluginValid->isEmailValid('Field','Field is not a valid mail');
       $oPluginValid->matchExpression('Field','/[0-9]/','Field doesn t match expression');
       $oPluginValid->notMatchExpression('Field','/[a-zA-Z]/','Field shoudn\'t match expression');
       */

       return $oPluginValid;
   }

   public function isValid(){
       return $this->getCheck()->isValid();
   }
   public function getListError(){
       return $this->getCheck()->getListError();
   }
   public function save(){
       if(!$this->isValid()){ //verifie la coherence avant d'enregistrer
           return false;
       }
       parent::save();
       return true;
   }
  
}
?>
   

Every file owns a few lines

protected $sClassRow

The name of the class row of model, request return object of this class

protected $sTable

Real name of the table in database

protected $sConfig

Identifiant of the use connection (configured in conf/connexion.ini.php)

protected $tId

Array containing primary key(s)

The processing

Introduction

For example, we have an article table and an auteur table linked by article.auteur_id = auteur.id
After the generation of the abstract model layer
We have two files in model directory: model_article.php and model_auteur.php
Each file has two class, one beginning with "row_" (active record) and an other beginning by "model_" (factory).
When you do a "select * from tableArticle" :
You will use the class "model_article", and it will return an array of "row_article" object.


  
$tArticle
=model_article::getInstance()->findAll();
    


When i write that every method class return an array of row_article object, it means that every methods you will add on class row_article will be available on return rows objects.
For example, you want to get the author from an article to display his name

Add in class model_article.php

  
public function findAuthor(){
   return model_auteur::getInstance()->findOne($this->auteur_id);
   //we return the row author returned by FK auteur_id
}
    


As easily, you can display the author name

  
$tArticle
=model_article::getInstance()->findAll();
foreach(
$tArticle as $oArticle){
   echo $oArticle->findAuthor()->name;
}
    



Here you can read list of implemented method with the ORM

public function findOne($requete,$tParam)

return one object when executing the request $requete with parameters $tParam
example :

  
findOne
('SELECT * FROM article WHERE id=?',4);
    


you can write

  
findOne
('SELECT * FROM article WHERE id=?',array(4) );
    


or (only with the pdo driver)

  
findOne
('SELECT * FROM article WHERE id=:id',array('id'=>4) );
    



public function findOneSimple($requete,$tParam)

return one "simple" object when executing the request $requete with parameters $tParam
example :

  
findOneSimple
('SELECT * FROM article WHERE id=?',4);
    


or you can write

  
findOneSimple
('SELECT * FROM article WHERE id=?',array(4) );
    


or (only with the pdo driver)

  
findOneSimple
('SELECT * FROM article WHERE id=:id',array('id'=>4) );
    



note: use this method to show quickly

public function findMany($requete,$tParam)

return an array of object when executing the request $requete with parameters $tParam
example :

  
findMany
('SELECT * FROM article WHERE cat_id=?',2);
    


or you can write

  
findMany
('SELECT * FROM article WHERE cat_id=?',array(2) );
    


or (only with the pdo driver)

  
findMany
('SELECT * FROM article WHERE cat_id=:cat_id',array('cat_id'=>2) );
    



public function findManySimple($requete,$tParam)

return an array of object when executing the request $requete with parameters $tParam
example :

  
findManySimple
('SELECT * FROM article WHERE cat_id=?',2);
    


or you can write

  
findManySimple
('SELECT * FROM article WHERE cat_id=?',array(2) );
    


or (only with the pdo driver)

  
findManySimple
('SELECT * FROM article WHERE cat_id=:cat_id',array('cat_id'=>2) );
    



note: use this method to show quickly

public function execute($requete,$tParam)

execute the query $requete with parameters $tParam
example :

  
execute
('DELETE FROM article WHERE id=?',2);
    


or you can write

  
execute
('DELETE FROM article WHERE id=?',array(2) );
    


or (only with the pdo driver)

  
execute
('DELETE FROM article WHERE id=:id',array('id'=>2) );
    



Write your own query

If you have dynamic variables, for example the query to select articles from an author
Selection of an article by author

  
public function findByAuteur($auteur_id){
   return $this->findOne('SELECT * FROM auteur where auteur_id=?',(int)$auteur_id);
}
    



In cas of many parameters:

  
public function findByAuteur($auteur_id){
   $state=1;//etat actif

   return $this->findOne('SELECT * FROM auteur where auteur_id=? AND state=?',(int)$auteur_id,(int)$state);
   //or
   return $this->findOne('SELECT * FROM auteur where auteur_id=? AND state=?',array( (int)$auteur_id,(int)$state ));
   //or (only with the pdo driver)
   return $this->findOne('SELECT * FROM auteur where auteur_id=:auteur AND state=:state',array( 'auteur'=>$auteur_id,'state'=>$state ));
}
    



Update a row in database

You want to update title of the article with id 2
In the code of your module:

  
//we get article object to update
$oArticleToModify=model_Article::getInstance()->findById(2);
//we update one of its fields
$oArticleToModify->titre='My new title';
//we save
$oArticleToModify->save();
    



Add a row in database

You want add an article
In the code of your module:

  
//we create new article
$oNewArticle= new row_Article;
//we fill the fields
$oNewArticle->titre='My new title';
//we save
$oNewArticle->save();
    



Delete a row in database

You want to delete the article with id 2
In your module code:

  
//we get the article objet to delete
$oArticleToDelete=model_Article::getInstance()->findById(2);
//we delete it
$oArticleToDelete->delete();