CREATE TABLE `news` (
`id_news` int(11) NOT NULL auto_increment,
`sujet` varchar(255) NOT NULL,
`texte` text NOT NULL,
`news_date` date NOT NULL,
PRIMARY KEY (`id_news`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Ressource jDao : news~news\\
Fichier DAO : news\\
Table : news
Créez dans le répertoire jelix/news/modules/news/forms/, le fichier //news.form.xml//.
===== Notes sur l'application à réaliser =====
Précisons l'ouvrage qu'il nous reste à faire pour compléter notre programme :
* Une réponse HTML personnalisée (//myHtmlResponse.class.php//)
* Le template principal (//main.tpl//)
* Le CSS (//screen.css//)
* La classe nommée //baseCrudController// (le CRUD) qui dérive de jController
* Un exemple d'utilisation nommé defaultCtrl qui hérite de la classe du CRUD
* Trois templates du CRUD correspondant à certaines actions
Et nous aurons une fois terminé une application de base pouvant évoluer vers un projet informatique.
===== La réponse HTML =====
Le but de créer une réponse HTML personnalisée est de généraliser dans l'application :
*utiliser le même thème dans toutes les pages de notre petite application
*garantir l'initialisation par défaut de certaines variables
*et de l'utilisation d'un template principal par défaut indépendant du CRUD
Enregistrez le code suivant dans le fichier //jelix/news/responses/myHtmlResponse.class.php//
body->assignIfNone('MAIN','Aucun contenu
');
$this->body->assignIfNone('CRUDtpl','');
$this->addCSSLink($GLOBALS['gJConfig']->urlengine['basePath'].'screen.css');
}
}
?>
Consulter le manuel pour obtenir plus de détail sur la classe [[http://docs.jelix.org/fr/manuel-1.0/creer_response|jReponseHTML]].
Pour indiquer à Jelix que vous avez créé une réponse personnalisée, vous devez ouvrir le fichier //jelix/news/var/config/index/config.ini.php// et ajouter **dans la section [responses]** la ligne suivante:
html = myhtmlResponse
===== La CSS =====
Le fichier screen.css doit être enregistré dans jelix/news/www/ ou dans un de ses sous-répertoires. Ce fichier est le CSS contenu dans l'application **testapp** de Jelix.
body { font-family: Verdana, Arial, Sans; font-size:0.8em;}
a img { border:0;}
pre {
padding-left:1em;
border-left:4px solid #efe03b;
color:black;
}
#header {
margin:20px 0 0 190px; width:730px;
padding:15px;
background-color:#1e92af;
-moz-border-radius:10px 10px 0 0;
/*height:35px;*/
color:white;
font-weight:bold;
font-size:1.5em;
}
#main {clear:both;
margin:0 0 0 190px;
padding:30px 15px 15px 15px;
max-width:730px;
color : #002830;
border-left:1px solid #d8e1e4;
border-right:1px solid #d8e1e4;
max-width:728px;
}
#main a { color:#0594c8; text-decoration:underline; }
#main a:visited { color : #002830;}
#main a:hover { color: white; background-color: #0594c8; text-decoration:none;}
#main a.wikilink2 { color:#ed5a02;}
#main h1 { color: #3c90af; border-bottom:4px solid #ed5a02; margin:0; }
#main h2 { color: #3c90af; border-bottom:2px solid #002830; margin:1em 0 0.5em 0; }
#main h3 { color: #002830; border-bottom:1px solid #002830; margin:1em 0 0.5em 0; }
#main h4 { color: #002830; }
#main input.button{
background-color:#4397b6;
border-left: 1px solid #99cbde;
border-right: 1px solid #225365;
border-top: 1px solid #99cbde ;
border-bottom: 1px solid #225365;
-moz-border-radius:3px;
color:white;
cursor: pointer;
}
.fail { color: red; }
.pass { color: green; }
pre { background-color: lightgray; }
.resultfail {
padding: 8px; margin-top: 1em; background-color: red; color: white;
}
.resultsuccess {
padding: 8px; margin-top: 1em; background-color: green; color: white;
}
div.exception { margin-top:4px; margin-bottom:4px;
background-color: #ff9186;
border: 1px solid red;
}
div.exception strong {color: red;}
div.exception p { font-size:0.9em; }
.diff { background: white; border: 1px solid black; }
.diff .block { background: #ccc; padding-left: 1em; }
.diff .context { background: white; border: none; }
.diff .block tt { font-weight: normal; font-family: monospace; color: black;
margin-left: 0; border: none;
}
.diff del, .diff ins { font-weight: bold; text-decoration: none; }
.diff .original, .diff .deleted,
.diff .final, .diff .added { background: white; }
.diff .original, .diff .deleted { background: #fcc; border: none; }
.diff .final, .diff .added { background: #cfc; border: none; }
.diff del { background: #f99; }
.diff ins { background: #9f9; }
#sidemenu {
position:absolute;
top:0;
left:0;
width:185px;
padding-left:10px;
}
#sidemenu a {color:#0594c8; text-decoration:none;}
#sidemenu a:hover { text-decoration: underline; }
#sidemenu h1 { text-align:center; }
#sidemenu h1 a {text-decoration:none;}
#sidemenu h1 a:hover { text-decoration:none; }
#sidemenu ul { margin:0 0 0 1em;
padding:0 0 0 1em;
color: #3c90af;
}
#sidemenu ul li { margin:0; padding:0 0 0 0em; }
#sidemenu .userinfo { margin:2em 0; }
#sidemenu p { text-align:center;}
#footer {
clear:both;
margin:0 0 0 190px;
padding:15px;
max-width:728px;
color : #002830;
text-align:center;
min-height:2em;
background-color:#d8e1e4;
border-left:1px solid #d8e1e4;
border-right:1px solid #d8e1e4;
border-bottom:1px solid #d8e1e4;
-moz-border-radius:0px 0px 15px 15px;
}
===== La classe du CRUD =====
Le classe baseCRUD contient tout le code directement lié à la manipulation des données d'une table.
* Browse : Affiche tous les enregistrements d'une table
* Create : Prépare la création d'un nouvel enregistrement
* Update : Prépare la mise à jour d'un enregistrement
* save : Sauvegarde un enregistrement
* View : Affiche un enregistrement
* Delete : Efface un enregistrement d'une table
Au début de la classe on retrouve le nom des sélecteurs et des templates utilisés par le CRUD mais initialisés par la classe fille.
Viens par après les messages qu'on peut considérer comme par défaut, puisque la classe fille peut les modifier.
Le CRUD crée un template qui contiendra les messages et les données. Puis ce template sera inséré dans le template principal par le biais de la variable de template CRUDtpl.
Vous devez enregistrer ce code dans le répertoire //jelix/news/modules/news/controllers/// et le fichier se nomme //baseCrudController.php//.
'La liste des fiches ',);
protected $CRUD_txt_create = array( 'title' => 'Ajout d\'une fiche ',);
protected $CRUD_txt_update = array( 'title' => 'Edition d\'une fiche ',
'errID' => 'L\'enregistrement que vous recherchez n\'existe pas. ',);
protected $CRUD_txt_save = array( 'errTitle' => 'Erreur de session! ou session fermé',
'errMessage' => 'Les données session recherchées n\'existent pas',);
protected $CRUD_txt_view = array( 'title' => 'La fiche ',);
// Le réponse de l'action est-elle du type HTML ou est-ce une redirection?
private $__typeReponseHTML = false;
public function __construct($request){
parent::__construct($request);
}
/**
* Récupère plusieurs enregistrements de la db
*/
protected function crud_browse(){
// Prépare la réponse
$rep = $this->getResponse('html');
// Crée un template CRUD qui contiendra les données
$tpl = new jTpl();
$tpl->assign('title', $this->CRUD_txt_browse['title']);
// On récupère les données de la db
$fact = jDao::get($this->CRUD_sel_jDao);
$tpl->assign('liste', $fact->findAll());
// La validation d'une liste vide se fait dans la vue.
// Insertion du template CRUD dans le template de l'action
$rep->body->assign('CRUDtpl', $tpl->fetch($this->CRUD_tpl_browse));
return $rep;
}
/**
* Ajoute un nouvel enregistrement dans la db
*/
protected function crud_create(){
// Si le jForms n'existe pas on le crée
$form = jForms::get($this->CRUD_sel_jForm);
if($form == null){
$form = jForms::create($this->CRUD_sel_jForm);
}
// Prépare la réponse
$rep = $this->getResponse('html');
// Crée un template CRUD qui contiendra les données
$tpl = new jTpl();
$tpl->assign('title', $this->CRUD_txt_create['title']);
// Insère les données du formulaire dans le template CRUD
$tpl->assign('form', $form->getContainer());
// Insertion du template CRUD dans le template de l'action
$rep->body->assign('CRUDtpl', $tpl->fetch($this->CRUD_tpl_edit));
return $rep;
}
/**
* Préparation de la saisie de données du formulaire html
* Paramètres :
* id : la clé du formulaire qui est aussi la clé primaire de notre enregistrement
*/
protected function crud_update(){
// Préparation de la réponse
$rep = $this->getResponse('html');
// Si le jForms n'existe pas on le crée
$form = jForms::get($this->CRUD_sel_jForm, $this->param('id'));
if($form == null){
$form = jForms::create($this->CRUD_sel_jForm, $this->param('id'));
}
// On récupère les données de la db
try {
$form->initFromDao($this->CRUD_sel_jDao);
}catch(Exception $e){
//quand initFromDao ne trouve pas l'enregistrement, il y a une exception
$rep->title = $this->CRUD_txt_update['title'];
$rep->body->assign('CRUDtpl', $this->CRUD_txt_update['errID']);
return $rep;
}
// Un nouveau template qui contiendra les données
$tpl = new jTpl();
$tpl->assign('title', $this->CRUD_txt_update['title']);
// Insère les données du formulaire dans le template CRUD
$tpl->assign('form', $form->getContainer());
// Insertion du template dans le template de l'action
$rep->body->assign('CRUDtpl', $tpl->fetch($this->CRUD_tpl_edit));
return $rep;
}
/**
* Enregistre le formulaire (jForm)
* paramètres :
* id : la clé du formulaire qui est aussi la clé primaire de notre enregistrement
* La validation de données sera complétée dans la version beta 3...
*/
protected function crud_save(){
// On récupère les données de la session courante
$form = jForms::fill($this->CRUD_sel_jForm, $this->param('id'));
if(!$form){
// pas de formulaire !
// Préparation de la réponse de type html
$rep = $this->getResponse("html");
$__typeReponseHTML = true;
// Un nouveau template qui contiendra les données
$tpl = new jTpl();
$tpl->assign('title', $this->CRUD_txt_save['errTitle']);
$tpl->assign('message', $this->CRUD_txt_save['errMessage']);
// Insertion du template dans le template de l'action
$rep->body->assign('CRUDtpl', $tpl->fetch($this->CRUD_tpl_index));
return $rep;
}
//normalement, on devrait utiliser $form->check() pour vérifier le contenu du formulaire
//mais cette méthode n'est pas complètement implanté. Donc on vérifie à la main
if($form->getData('sujet') != '' && $form->getData('texte') != ''){
$form->saveToDao($this->CRUD_sel_jDao);
}else{
// la vérification a échouée,
// Retourne les données vers le client pour correction
$rep = $this->getResponse("redirect");
$rep->params['id'] = $this->param('id');
if($this->param('id')){
$rep->action = $this->CRUD_sel_direct_update;
}else{
$rep->action = $this->CRUD_sel_direct_create;
}
return $rep;
}
// La sauvegarde des données à réussi,
// on va maintenant effacer le formulaire en session
jForms::destroy($this->CRUD_sel_jForm, $this->param('id'));
// on retourne à la liste
$rep = $this->getResponse("redirect");
$rep->action = $this->CRUD_sel_direct_browse;
return $rep;
}
/**
* Affiche un enregistrement de la db
* paramètres :
* id : la clé de notre enregistrement
*/
protected function crud_view(){
// Préparation de la réponse
$rep = $this->getResponse('html');
// On récupère les données de la db
$fact = jDao::get($this->CRUD_sel_jDao);
$rec = $fact->get($this->param('id'));
// La validation d'une liste vide se fera dans la vue.
// Un nouveau template qui contiendra les données
$tpl = new jTpl();
$tpl->assign('title', $this->CRUD_txt_view['title']);
$tpl->assign('rec', $rec);
// Insertion du template dans le template de l'action
$rep->body->assign('CRUDtpl', $tpl->fetch($this->CRUD_tpl_view));
return $rep;
}
/**
* Efface l'enregistrement
* paramètres :
* id : la clé de notre enregistrement
*/
protected function crud_destroy(){
// Récupère un objet jDao
$dao = jDao::get($this->CRUD_sel_jDao);
// Détruit l'enregistrement correspondant à l'id
$dao->delete($this->param('id'));
// on retourne à la liste
$rep = $this->getResponse("redirect");
$rep->action = $this->CRUD_sel_direct_browse;
return $rep;
}
/**
* Dans une action retourne vrai si la réponse utilisé est du type HTML
*/
protected function checkReponseHTML(){
return $this->__typeReponseHTML;
}
}
?>
===== Le controleur =====
Nous voici rendu au controleur qui utilise notre CRUD, la classe fille, la classe qui hérite du CRUD. C'est aussi cette classe qu'on appelle les fonctions qui manipulent les enregistrements de la table.
Au début du controleur on retrouve un message qui sera affiché par l'action index.
Remarquez le constructeur qui a exactement la même signature que sa classe parente qui elle aussi à la même signature que sa classe parente. Également le constructeur initialise les sélecteurs et les templates du CRUD. De plus le choix du template principal et du css a été fait dans la réponse personnalisée. Voir une section précédente.
Vous devez copier le code suivant dans le fichier //jelix/news/modules/news/controllers/default.classic.php//
getModulePath('news').'controllers/baseCrudController.php';
class defaultCtrl extends baseCrudController{
private $my_msg_index = 'Jelix vous présente un exemple de CRUD inscrit dans une classe de base.
Veillez noter que les exemples de ce tutoriel ne fonctionnent qu’avec la version en cours de développement de jelix 1.0 beta 3.
Le code comprend :
- La classe baseCrud
- Un exemple d\'utilisation d\'un CRUD
- Personnalisation complète du CRUD :: ressources Jelix du CRUD et des messages
- Une réponse html personnalisé
- Utilisation d\'un css
- Un template principal et quatres templates du CRUD correspondant à chacune des actions
- Un code bien documenté
- Un code facilement adaptable
Limites présentement
- Ne gère qu\'une seule table via le jDao
- Les templates du CRUD sont créés manuellement
';
public function __construct($request){
parent::__construct($request);
$this->common();
}
/**
* Initialisation du CRUD
*/
private function common(){
$this->CRUD_sel_jDao = 'news~news';
$this->CRUD_sel_jForm = 'news';
$this->CRUD_sel_direct_browse = 'news~default_browse';
$this->CRUD_sel_direct_update = 'news~default_update';
$this->CRUD_sel_direct_create = 'news~default_create';
$this->CRUD_tpl_browse = 'news~crudbrowse';
$this->CRUD_tpl_edit = 'news~crudedit';
$this->CRUD_tpl_view = 'news~crudview';
}
/**
* Action par défaut...
*/
public function index(){
$rep = $this->getResponse('html');
$rep->body->assign('MAIN', $this->my_msg_index);
return $rep;
}
/**
* Exemple d'utilisation du CRUD
* Récupère plusieurs enregistrements de la db
*/
public function browse(){
// CRUD
$rep = $this->crud_browse();
// Votre formulaire
$rep->body->assign('MAIN', 'Template d\'utilisation du CRUD action browse....');
return $rep;
}
/**
* Exemple d'utilisation du CRUD
* Préparation de la saisie de nouvelles données du formulaire html
*/
public function create(){
// CRUD
$rep = $this->crud_create();
// Votre formulaire
$rep->body->assign('MAIN', 'Template d\'utilisation du CRUD action create....');
return $rep;
}
/**
* Exemple d'utilisation du CRUD
* Préparation de la modification de données du formulaire html
*/
public function update(){
// CRUD
$rep = $this->crud_update();
// Votre formulaire
$rep->body->assign('MAIN', 'Template d\'utilisation du CRUD action update....');
return $rep;
}
/**
* Exemple d'utilisation du CRUD
* Ajoute ou modifie un enregistrement dans la db
*/
public function save(){
// CRUD
$rep = $this->crud_save();
// Votre formulaire
// Les réponses "html et redirect" n'ont pas les mêmes propriétés
if($this->checkReponseHTML()){
$rep->body->assign('MAIN', 'Template d\'utilisation du CRUD action save....');
}
return $rep;
}
/**
* Exemple d'utilisation du CRUD
* Affiche un enregistrement de la db
*/
public function view(){
// CRUD
$rep = $this->crud_view();
// Votre formulaire
$rep->body->assign('MAIN', 'Template d\'utilisation du CRUD action view....');
return $rep;
}
/**
* Exemple d'utilisation du CRUD
* Efface l'enregistrement dans la db
*/
public function destroy(){
// CRUD
$rep = $this->crud_destroy();
return $rep;
}
}
?>
===== Le template main.tpl =====
Il s'agit du template principal qui affiche les templates du CRUD par le biais de la variable de template $CRUDtpl.
Vous devez copier le code ci-dessous dans le fichier template nommé //main.tpl// du répertoire ///jelix/news/modules/news/templates///.
Tutoriel CRUD de base
{$MAIN}
{$CRUDtpl}
===== Le template crudview.tpl =====
Il s'agit du template du CRUD qui affiche un enregistrement.
Vous devez copier le code ci-dessous dans le fichier template nommé //crudview.tpl// du répertoire ///jelix/news/modules/news/templates///.
{$title}
{if $rec}
- id_news :
- {$rec->id_news}
- Sujet :
- {$rec->sujet|escxml}
- Texte :
- {$rec->texte|escxml}
- Date :
- {$rec->news_date}
{else}
Cette fiche n'existe pas!
{/if}
===== Le template crudedit.tpl =====
Il s'agit du template du CRUD qui permet l'édition d'un enregistrement.
Vous devez copier le code ci-dessous dans le fichier template nommé //crudedit.tpl// du répertoire ///jelix/news/modules/news/templates///.
{$title}
===== Le template crudbrowse.tpl =====
Il s'agit du template du CRUD qui affiche plusieurs enregistrements.
Vous devez copier le code ci-dessous dans le fichier template nommé //crudbrowse.tpl// du répertoire ///jelix/news/modules/news/templates///.
{$title}
{if $liste->rowCount()}
{foreach $liste as $rec}
{$rec->id_news}
{$rec->sujet|escxml}
{$rec->texte|escxml}
{$rec->news_date}
voir
éditer
détruire
{/foreach}
{else}
Il y a aucune fiches d'enregistrés
{/if}
----
* [[fr:tutoriels:|Retour au sommaire des tutoriels]]