Xom Criteria

Projet
Nous allons créer un objet patientChambre

Un ou plusieurs patients peuvent être éventuellement dans une chambre.

Une chambre a un numéro, un libelle, une date du dernier nettoyage

La correspondance avec la table patient se fait sur le code de la chambre (patient.col10)

On veut une interface qui permette de rechercher une chambre : par nom de patient qui est dedans, ou par libelle de chambre.

NOTE: c’est un tuto, alors attention à ne rien commiter sur subversion !

création de la table
On veut créer la table suivante

CREATE TABLE `patients_chambres` (
`id` INT NOT NULL AUTO_INCREMENT ,
`code` VARCHAR( 8 ) NOT NULL ,
`libelle` VARCHAR( 32 ) NOT NULL ,
`dernier_nettoyage` DATETIME NOT NULL ,
PRIMARY KEY ( `id` )
) ENGINE = MYISAM ;
Note: la clé primaire doit impérativement être la premiere colonne Sauf cas particulier, ce doit être un int autoincrémenté

Les datetime doivent etre des DATETIME et en aucun cas des TIMESTAMP ( pas gêrés par le framework )

Pour inclure la création de cette table dans les mises à jour de TU deployées sur les sites, il faut recopier cette requete dans le fichier : meta/update.xml

On ajoutera une balise de ce type (à adapter )



… ici une requete pour etre sur qu’on ne crée pas une nouvelle fois la table : SHOW TABLES LIKE … , si la requete renvoie des résultats, la commande ci dessous ne sera pas exécutée
CREATE TABLE…..

De cette façon, lors de la mise à jour d’un terminal sur les sites, la table sera automatiquement créée.

On a une double sécurité : un update n’est exécuté qu’une fois par id + la balise optionelle mais recommandée requeteifnot

le script index.test.php lit le fichier meta/update.xml et crée les tables. Exécutez le.

Génération de l’objet base associé
Il faut editer le fichier meta/baseinstall/xom_model.xml pour lui signaler la présence d’un nouvel objet à gênérer, ainsi que les liaisons à prévoir





On peut maintenant generer les classes associées automatiquement :

cd meta/tools php genXomBaseClasses

Ceci va créer dans le répertoire lib/model/base les classes patientChambreBase (la classe métier) et patientChambreBasePeer (l’objet de manipulation de l’objet patientChambre )

Ces deux classes ne doivent pas être modifiées. Elles sont écrasées des qu’on appelle le générateur de classe. Elles se basent uniquement sur le fichier meta/baseinstall/xom_model.xml

Deux autres fichiers se sont créés dans lib/model/ : patientChambre , et patientChambrePeer . Ces deux classes héritent des objets base.

Une fois créés, ces fichiers ne seront pas modifiés par le générateur de classes, par contre les classes Base le seront. Par conséquent, toute modification des classes que vous avez besoin de coder doit se faire sur les classes dans model et surtout pas dans celles dans base. Note : pensez à utililer sans complexes l’autocompletion, qui vous donne acces à toutes les methodes de la classe héritée

Note 1 : vous pouvez également ajouter l’attribut crudGenerator= »yes » ou crudGenerator= »always » pour lancer la génération automatique de l’interface d’administration de cette table. A savoir que la valeur « yes » ne génèrera les fichiers qu’une seule et unique fois (vous pouvez donc les modifier ensuite pour les adapter à des besoins précis) et que la valeur « always » fera que l’ihm sera générée à chaque fois que le script genXomBaseClasses est appelé.
Note 2 : si l’attribut crudGenerator est présent, les fichiers suivants seront générés :
lib/controllers/gestAdminPatientChambre.php
templates_int/xom.admin.patientChambre.form.tpl.php
templates_int/xom.admin.patientChambre.liste.tpl.php
création du controller et de la template
Un controller traite les données reçues par l’utilisateur, puis renvoie de l’affichage

Un controller se place dans lib/controllers et doit hériter de l’objet xomController. On crée un controller basique : gestChambres.class.php

class gestChambres extends xomController
{

function __construct() {
parent::__construct();
//Rien à traiter pour le moment
}

function getAffichage()
{
return « coucou » ;
}

}
Le constructeur ne doit pas sauf exception gênérer de HTML. Il traite les données reçues, et prépare les données et objets qui vont être utilisés dans le template. (qui lui, gérere du html par définition )

On va affecter ce controller à un menu de GTS.

Dans l’interface de TU aller dans dev->navigation, et créer une entrée de menu dont la classe chargée est « gestChambres »

Notez qu’on peut restreindre à un droit, à une option, ou passer un argument ( qui sera reçu dans le constructeur de gestChambres ) , même si tout cela ne sera pas utilisé dans ce tutorial.

Normalement à ce stade, vous avez créé un menu assigné à un controller, qui dit coucou.

Compliquons un peu les choses : on va passer par une template qui dit coucou.

Créons un fichier template ( dans templates_int par exemple ) : GTS.Tutorial.GestionChambres?.tpl.php

qui contient

Le message envoyé par le controler est

Et remplaçons la methode getAffichage du controller par :

function getAffichage()
{
return XhamTools::readTemplate(‘GTS.Tutorial.GestionChambres’,array(‘controller’=>$this,’message’=> »Coucou de luxe »)) ;
}
On peut voir ainsi la façon dont les variables sont instanciées, puis utilisées dans la template.

(on a passé également $this, ce qui va permettre d’accéder aux propriétés du controller dans la template, comme par exemple l’url de navigation un peu plus bas )

De bonnes recommandations sur la façon d’écrire les templates peuvent se trouver dans la charte de développement ici : https://docs.google.com/a/orupaca.fr/document/d/1xlsRtBvd2eJ2F1ZfbHANhqUfUvuTMTDiOEWZYHGcZSI/edit?hl=fr (XVeme commandement )

Modifions le template de cette façon pour avoir un formulaire de requetage tres laid mais fonctionnel :

Nom de la salle :


getLibelle() ; ?>

Maintenant, on va modifier le controller pour qu’il applique les criteres, et contruise la liste. On va se servir une fois de plus allegrement de l’autocompletion, la meilleure amie des logiciels stables et des féniants .

/*
* Classe créée par Emmanuel Cervetti ecervetti@orupaca.fr
* Controleur des exports de patients de TU
* Toute modification est interdite sans l’accord de l’auteur.
*/

class gestChambres extends xomController
{

public $collectionChambres ;

function __construct() {
parent::__construct();
//Rien à traiter pour le moment
$chambreLambda = patientChambrePeer::getInstance()->getXomObjetLambda() ; //Cet objet permet de contruire des criteres à partir de l’autocompletion, en utilisant les methodes existantes. Attention à toujours utiliser le même si vous construisez un critere à travers plusieurs methodes
$this->collectionChambres = $chambreLambda->getCollection();

//Décommentez la ligne suivante si vous voulez qu’en l’absence de critere fourni (données post vides) , TOUS LES OBJETS soient récupérés. PENSEZ au temps de réponse que ça va impliquer en prod si vous décommentez !!
//$this->collectionChambres->setGetAll();

if($this->getUserInput(‘nom_salle’))
{
$criteria = xomCriteria::_like($chambreLambda->getLibelle(),$this->getUserInput(‘nom_salle’));
$this->collectionChambres->setCriteria($criteria); //On pourait indiferement ici, si c’est le premier critere chargé, utiliser également addCriteriaAnd ou addCriteriaOr
}
if($this->getUserInput(‘nom_patient’))
{
$criteria = xomCriteria::_like($chambreLambda->getPatientResidents()->getNomu() ,$this->getUserInput(‘nom_patient’)); // Facile le JOIN non ?
$this->collectionChambres->addCriteriaAnd($criteria); //On fait un AND avec le critere précédent, s’il existe. sinon
}
eko($this->collectionChambres->getSqlGenere()); //permet de debuguer la requete générée, en cas de problemes.
}

function getAffichage()
{
return XhamTools::readTemplate(‘GTS.Tutorial.GestionChambres’,array(‘controller’=>$this,’message’=> »Coucou de luxe »,’chambres’=>$this->collectionChambres)) ;
}

}
Remplissez un peu la base de données pour avoir des exemples,

INSERT INTO `patients_chambres` (`id`, `code`, `libelle`, `dernier_nettoyage`) VALUES
(1, ‘BOX 1’, ‘Andouillette, boudin, trippes’, ‘1987-11-17 18:20:10’),
(2, ‘BOX 2’, ‘Museau, poitrine, rognons’, ‘1993-11-25 18:20:42’);
Affectez des patients à ces salles : votre module de recherche devrait être totalement fonctionel !

Exemples d’autres criteres et recherches
Spécification de la clause where à utilser sur la requete sql
Si vous souhaitez appeller et chercher un objet avec un petit bout de requete simple , on peut utiliser le code suivant. Uniquement pour les petits bouts de requetes simples !!

$chambres007 = chambrePatientPeer::getInstance()->getFromCw( » code=’007′ « );
compter les objets
$collectionChambres->count() ; //génere une requete SQL de type COUNT sur le critere en cours, renvoie le nombre d’objets trouvés
$collectionChambres->getNbObjects() ; //Effectue la requete, met en cache les résultats , et renvoie le nombre d’objets retournés. La requete n’aura été exécutée qu’une fois, même si on passe la collection dans un foreach() apres ou avant.
Trier les résultats
//Trier les chambres par libelles ascendants, puis par ID descendants

foreach($collection->orderBy($chambreLambda->getLibelle())->orderBy($chambreLambda->Id(),DESC)