Présentation

Cette page vous présente comment, avec Copix, faire un module de type CRUD (Create Read Update Delete).

Cette documentation est absolument exhaustive : aucune opération ou ligne de code supplémentaire n'est nécessaire pour arriver à bout du module.

Si vous avez téléchargé une version complète de Copix, ce module se situe dans le répertoire project/modules/public/stable/tutorials/crud/*.*

C'est parti !

Table utilisée

Voici la table que nous allons utiliser. Nous considérons que vous utiliserez MySQL pour ce tutoriel.

CREATE TABLE `tutorial_crud` (
`id_crud` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`caption_crud` VARCHAR( 20 ) NOT NULL ,
`description_crud` TEXT NOT NULL
);

Première étape, Module.xml

Comme toujours, vous devez créer un fichier module.xml pour déclarer votre module dans Copix.

<moduledefinition>
 <general>
  <default name="crud" longdescription="Tutorial CRUD (Create Read Update Delete) avec Copix." />
 </general>
</moduledefinition>

Une fois ce fichier crée, installez votre module grâce au module admin.

Deuxième étape, page de liste des éléments

Créez un ActionGroup par défaut pour votre module, actiongroup/default.actiongroup.php. L'action par défaut aura pour objectif d'afficher la liste des éléments de la table.

class ActionGroupDefault extends CopixActionGroup {
 public function processDefault (){
  $ppo = new CopixPpo ();

  $ppo->TITLE_PAGE = 'Liste des éléments';
  $ppo->arData = _ioDAO ('tutorial_crud')->findAll ();//Le DAO est généré automatiquement

  return _arPpo ($ppo, 'crud.list.tpl');
}

Cette action utilise le système de DAO de Copix et profite de la possibilité qu'offre Copix de générer automatiquement les DAO à partir du nom des tables.

Cette action demande un affichage via le code retour PPO dans le template crud.list.tpl.

Créez donc le fichier templates/crud.list.tpl

<table class="CopixTable">
 <thead>
  <tr>
   <th>Libellé</th>
   <th>Actions</th>   
  </tr>
 </thead>
 <tbody>
 {foreach from=$ppo->arData item=element}
  <tr {cycle values=',class="alternate"'}>
   <td>{$element->caption_crud}</td>
   <td>
     <a href="{copixurl dest="delete" id_crud=$element->id_crud}"><img src="{copixresource path="img/tools/delete.png"}" /></a>
     <a href="{copixurl dest="edit" id_crud=$element->id_crud}"><img src="{copixresource path="img/tools/update.png"}" /></a>
   <td>
  </tr>
 {/foreach}
 </tbody>
</table>

<a href="{copixurl dest="edit" new=1}"><img src="{copixresource path="img/tools/new.png"}" />Nouveau</a>
  • Ce template profite du tag Smarty alternate afin d'alterner la couleur des lignes pour plus de lisibilité.
  • On utilise également le système d'url afin d'assurer à notre application une portabilité complète et pouvoir profiter plus tard de la possibilité de réécriture d'URL.
  • On utilise le système de ressources afin de pouvoir profiter des thèmes graphiques? Copix.

Troisième étape, page de modification

Dans votre ActionGroup, ajoutez une action de modification. Toutes les lignes importantes du code suivant sont documentées.

public function processEdit (){
  //Si un identifiant d'élément à modifier est donné et que ce dernier existe, on le place
  //dans la session pour qu'il soit défini comme élément à modifier
  if ($crud_id = CopixRequest::getInt ('id_crud')){
   if ($toEdit = _ioDAO ('tutorial_crud')->get ($crud_id)){
    CopixSession::set ('crud|edit', $toEdit);
   }
  }
  //On regarde s'il existe un élément en cours de modification, si ce n'est pas le cas on 
  //passe en mode création. Création forcée si demandé dans l'url.
  if ((($toEdit = CopixSession::get ('crud|edit')) === null) || (_request ('new') == 1)){
   CopixSession::set ('crud|edit', $toEdit = _record ('tutorial_crud'));
  }

  //Préparation de la page
  $ppo = new CopixPpo ();
  $ppo->TITLE_PAGE = $toEdit->id_crud ? "Modification de l'élément" : "Création d'un élément";
  $ppo->toEdit = $toEdit;
  
  //si on demande à afficher les messages d'erreurs
  $ppo->arErrors = _request ('errors') ? _ioDAO ('tutorial_crud')->check ($toEdit) : array ();
  return _arPpo ($ppo, 'crud.form.tpl');
}
  • Cette page regarde donc si l'utilisateur a demandé à éditer un élément (en spécifiant son identifiant dans la requête).
  • Si c'est le cas, on utilise le système de DAO pour le récupérer et le mettre en session.
  • Si l'on a demandé à afficher les erreurs sur la page, on utilise la méthode check pour récupérer un tableau d'erreurs concernant l'enregistrement en cours de modification.
  • On demande ensuite à afficher les éléments dans le template crud.form.tpl.
{if count ($ppo->arErrors)}
<div class="errorMessage">
<h1>Erreurs</h1>
{ulli values=$ppo->arErrors}
</div>
{/if}

<form action="{copixurl dest="valid"}" method="POST">
<table class="CopixVerticalTable">
 <tr>
  <th>Libellé</th>
  <td><input type="text" name="caption_crud" value="{$ppo->toEdit->caption_crud|escape}" /></td>
 </tr>

 <tr>
  <th>Description</th>
  <td><textarea name="description_crud">{$ppo->toEdit->description_crud|escape}
</textarea></td>
 </tr>

</table>

<input type="submit" value="Valider" />
<a href="{copixurl dest="|" cancel=1}"><input type="button" value="Annuler" /></a>
</form>
  • Ce template utilise le tag ulli pour générer une liste d'erreurs
  • Les données de formulaire sont toujours transmises par la méthode POST
  • On utilise le modificateur escape pour échapper les caractères spéciaux HTML que l'utilisateur pourrait saisir.

Quatrième étape, enregistrer les changements

Dans votre ActionGroup, il est temps de développer la méthode de validation, ici commentée :

public function processValid (){
  //On vérifie que l'on est bien en train de modifier un élément, sinon on retourne à la liste.
  if (($toEdit = CopixSession::get ('crud|edit')) === null){
   return _arRedirect (_url ('|'));
  }

  //validation des modifications depuis le formulaire
  $toEdit->caption_crud = _request ('caption_crud');
  $toEdit->description_crud = _request ('description_crud');
  CopixSession::set ('crud|edit', $toEdit);

  //Si tout va bien, on sauvegarde
  if (_ioDAO ('tutorial_crud')->check ($toEdit) === true){
   if ($toEdit->id_crud){
    _ioDAO ('tutorial_crud')->update ($toEdit);
   }else{
    _ioDAO ('tutorial_crud')->insert ($toEdit);
   }
   
   //on vide la session
   CopixSession::set ('crud|edit', null);
   return _arRedirect (_url ('|'));
  }else{
   //un problème ? on retourne sur la page de modification en indiquant qu'il existe un problème
   return _arRedirect (_url ('edit', array ('errors'=>1)));
  }
}
  • Cette méthode récupère depuis la session l'élément en cours de modification.
  • En utilisant les données transmises dans la requête, on met à jour l'enregistrement.
  • Si la méthode check indique que tout est correct, on utilise les méthodes ou insert (pour ajouter l'enregistrement) ou update (s'il s'agit d'une mise à jour).
  • S'il y a un problème, l'utilisateur est redirigé vers la page de modification avec les messages d'erreurs, sinon on redirige l'utilisateur dans la page de liste.

Cinquième étape, permettre la suppression

Pour permettre la suppression, on rajoute l'action suivante dans l'ActionGroup :

public function processDelete (){
  //On s'assure qu'un id_crud a bien été donné    
  CopixRequest::assert ('id_crud');

  //On vérifie si l'enregistrement existe, si tel n'est pas le cas, 
  //on ne s'embête pas et on retourne en liste.
  if (! ($record = _ioDAO ('tutorial_crud')->get (CopixRequest::getInt ('id_crud')))){
   return _arRedirect (_url ('|'));//'|' signifie action par défaut dans l'actiongroup par défaut du module courant, on aurait pu ici écrire 'crud|default|default' ou 'crud||'
  }

  if (! _request ('confirm', false, true)){
   return CopixActionGroup::process ('generictools|Messages::getConfirm',
   array ('message'=>'Etes vous sûr de vouloir supprimer cet élément '.$record->caption_crud.' ?',
   'confirm'=>_url ('delete', array ('id_crud'=>$record->id_crud, 'confirm'=>1)),
   'cancel'=>_url ('|')));
  }else{
   _ioDAO ('tutorial_crud')->delete ($record->id_crud);
  }
  return _arRedirect (_url ('|'));
}

Dans cette action, on s'assure que l'utilisateur est bien passé par une page de confirmation réalisée avec le module GenericTools avant d'effectivement supprimer la donnée avec la méthode delete.

C'est terminé

Dans ce tutoriel, vous pouvez apprécier le nombre de choses que Copix vous a proposé pour aller plus vite dans vos développements, à savoir :

  • Les DAO automatiques pour lire, supprimer, modifier, insérer et contrôler vos données.
  • Un module pour générer automatiquement les page de confirmation.
  • Un système de Session pour y placer des objets facilement (sans se soucier de leur inclusion préalable).
  • Des tags pour réaliser les opérations communes en une ligne dans vos templates.
  • Un système de génération d'URL pour faire évoluer la forme de vos URL sans impact sur le code existant
  • Un système de thèmes graphiques? qui vous permettra de changer l'apparence de votre site sans modifier le code du module.