Il peut arriver que la structure existante des données de l'application (collections/contenus) soit inappropriée à la gestion d'un type particulier de données, par exemple si vous devez importer de nombreux enregistrements d'une base de données existante qui possède sa propre structure complexe.
Dans un tel cas, la bibliothèque de génération de formulaires CRUD (pour Create, Read, Update, Delete) fournie avec chora permet le plus souvent de développer rapidement les contrôleurs et vues adaptés à vos données externes.
(Notez qu'il vous faudra cependant importer ces données dans la base de données MySQL de l'application, soit à l'aide d'un import SQL, soit d'un import CSV, d'un import ODBC ou via l'API RESTful (par exemple à l'aide de la bibliothèque client d'API RESTful).
La bibliothèque de génération de formulaires CRUD de chora est dérivée du populaire GroceryCRUD de John Skoumbourdis (en version 1.6.1 modifiée) : cette application est disponible sous licence MIT. Malgré les modifications apportées pour son intégration à chora (elle est utilisée pour construire de nombreux formulaires de l'interface de gestion), son fonctionnement demeure 100% compatible avec l'application d'origine.
Vous trouverez la documentation complète de GroceryCRUD à l'adresse suivante : https://www.grocerycrud.com/documentation (veuillez noter que cette documentation est considérablement enrichie par les informations disponibles sur les forums d'utilisateurs de GroceryCRUD : https://www.grocerycrud.com/forums/ ; aussi, nous vous conseillons vivement de les consulter).
Le générateur de formulaires CRUD est une des bibliothèques les plus complètes qui sont fournies avec chora. il convient d'en présenter rapidement les fichiers importants.
Le fichier principal de la bibliothèque est /application/libraries/Grocery_CRUD.php
C'est le seul fichier à charger pour pouvoir utiliser les fonctions de génération de formulaires CRUD :
$this->load->library('grocery_CRUD');
La configuration basique de la bibliothèque se fait dans le fichier /application/config/grocery_crud.php
(En principe, vous ne devez pas modifier celui-ci, car certaines options sont nécessaires au fonctionnement de chora).
Enfin, une grande partie du code de la bibliothèque est constituée par les fichiers de contenu qui se trouvent dans le dossier /assets/grocery_crud
Nous ne présentons ici que les spécificités de la version livrée avec chora.
Une partie importante des formulaires CRUD est leur interface qui fonctionne avec AJAX. Celle-ci est créée à partir des fichiers du thème fourni avec chora : /assets/grocery_crud/themes/AEdatatables/
AEdatatables s'appuie sur les versions spécifiques des bibliothèques Javascript Datatables, jQuery et Bootstrap 4 fournies avec chora pour proposer des formulaires et des tables homogènes avec le reste de l'application. Ses fonctions comprenent notamment le support de la taille d'écran d'utilisateur (design adaptatif), des messages non intrusifs affichés avec CSS/Javascript via la bibliothèque humane.js, des filtres des colonnes, du tri des colonnes (corrigé), de la recherche dans less tableaux et des boutons copier, imprimer et exporter au format CSV.
Pour permettre l'intégration dans chora, quelques modifications ont été apportées au chargement des fichiers Javascript et aux code Javascript de la bibliothèque.
Le fichier modèle fourni avec chora (/application/models/Grocery_crud_model.php
) inclut le support d'une fonction supplémentaire écrite par Nagara Jupuli Mamadi (http://www.nagarajupulimamidi.com/grocery-crud-where_in/).
Cette fonction est semblable à la méthode where_in() de ActiveRecord (qui n'est pas supportée sinon dans GroceryCRUD) et fournit la possiblité d'utiliser des clauses IN WHERE dans les formulaires CRUD :
$crud->in_where(<liste de valeurs clés>)
Une fois la bibliothèque chargée, vous pouvez l'utiliser dans un contrôleur pour générer en quelques lignes les formulaires permettant de manipuler les données d'une table de la base de données de l'application :
//Chargement de la bibliothèque CRUD
$this->load->library('grocery_CRUD');
//Construction des formulaires
$crud = new grocery_CRUD(); //Initialisation
$crud->set_theme('AEdatatables'); //Définition du thème
$crud->set_language($this->session->userdata('language')); //Définition de la langue
$crud->set_table('my_table'); //Table de la base de données
$crud->set_subject('My Data'); //Libellé des données
//Clause WHERE :
//$crud->where("cle=$valeur"); //Filtre optionnel (clause WHERE)
//$crud->in_where($valeur1,$valeur2,$valeur3...); //Filtre optionnel (clause WHERE IN)
//...
//Sortie HTML (à transmettre à la vue)
$output = $crud->render();
Notez que dans le cadre d'une utilisation avec chora, il vous faudra généralement ajouter vos propres contrôles pour gérer les droits de l'utilisateur à l'aide la bibliothèque Auth :
$this->load->library('Auth');
if (!$this->auth->is_allowed(0,'view')) {
$crud->unset_list(); //Supprime la fonction lister
$crud->unset_read(); //Supprime la fonction voir
}
if (!$this->auth->is_allowed(0,'edit')) {
$crud->unset_edit(); //Supprime la fonction éditer
$crud->unset_clone(); //Supprime la fonction cloner
}
if (!$this->auth->is_allowed(0,'delete')) {
$crud->unset_edit(); //Supprime la fonction effacer
}
Deux fonctions particulièrement utiles de la bibliothèque permettent la gestion des relations entre deux tables de la base de données MySQL :
Soit une relation 1-n entre la valeur du champ this_table.data_id et les données de la table data dont la clé primaire est définie :
$crud->set_relation('data_id','data','{label_data} ({publish_data})',array('status' => 1,'label_data ASC'));
affichera une chaîne de caractères constituée par la valeur du champ label_data, suivie de la valeur du champ publish_data entre parenthèses, toutes deux prises dans la table data, à la place du champ data_id de la table manipulée dans les formulaires CRUD (this_table dans notre exemple).
Le quatrième paramètre (optionnel) ajoute une clause where supplémentaire : seuls les contenus actifs sont listés.
Le cinquième paramètre (optionnel) indique que les résultats seront triés par ordre croissant de la valeur du champ label_data
Nous reprenons ici l'exemple fourni dans la documentation de GroceryCRUD pour traduire la relation n-n suivante :
table manipulée dans le formulaire CRUD (this_table) -> table de jointure (relation_table) -> table mise en relation (selection_table)
On utilisera :
$crud->set_relation_n_n(
$field_name,
$relation_table,
$selection_table,
$primary_key_alias_to_this_table,
$primary_key_alias_to_selection_table ,
$title_field_selection_table
[ , $priority_field_relation [, $where_clause]]
);
Avec les paramètres suivants :
Bien que cela ne soit pas recommandé, il arrive fréquemment de rencontrer des listes de valeurs, séparées par une virgule, qui ont été insérées dans un seul champ d'une table : un tel procédé peut permettre de simuler une relation n->n qui aurait été exprimée à l'aide d'une table intermédiaire (voir ci-dessus), mais en faisant l'économie de cette dernière.
Un champ de type multiselect permet de gérer une telle liste de valeurs dans le CRUD.
Dans le cas où les données de la liste sont issues d'une table de la base de données, le tableau stockant les valeurs possibles pour la sélection doit en sus être construit à l'aide d'une requête spécifique : dans un tel cas, il faut prendre soin de réinitialiser le constructeur de requête avant et après la construction de cette requête (pour éviter l'agrégation des clauses), ce que montre l'exemple suivant :
$this->db->reset_query();
$this->db->select('id, nom');
$results = $this->db->get('groupe')->result();
$groupes_multiselect = array();
$this->db->reset_query();
foreach ($results as $result) {
$groupes_multiselect[$result->id] = $result->nom;
}
$crud->field_type('liste_groupes', 'multiselect', $groupes_multiselect);
Vous trouverez ci-après quelques recettes utiles, regroupées pour plus de simplicité.
En règle générale, veuillez vous référer à la documentation disponible sur GroceryCRUD 1.6.x pour développer avec cette bibliothèque.
Il faut d'abord définir le tableau des paramètres personnalisés à transmettre à la vue (en principe $this->view_data
), puis initialiser la bibliothèque CRUD et en récupérer la sortie dans une variable (de type tableau : $output
). Pour terminer, on fusionne les deux tableaux en un seul à l'aide de la fonction array_merge()
, puis on charge la vue avec le résultat de la fusion (dans la variable $crud_output
).
Par exemple, pour ajouter des fichiers Javascript/CSS aditionnels et une variable $page_title à la vue, on utilisera :
//Définition des paramètres de la vue
$css_files=$this->view_data['css_files']=array(
base_url().'assets/css/content.css',
base_url().'assets/css/vendor/aurorae/dashboard.css');
$js_files=$this->view_data['js_files']=array(base_url().'assets/js/content.js');
$this->view_data['page_title']='Ma page...';
//Initialisation de la bibliothèque CRUD et construction des formulaires
$crud = new grocery_CRUD();
$crud->set_theme('AEdatatables');
$crud->set_language($this->session->userdata('language'));
$crud->set_table('my_table');
//Filtre :
//$crud->where("cle=$valeur");
//$crud->in_where("valeur1, valeur2, valeur3, ...");
//...
//Sortie HTML de la bibliothèque CRUD (à transmettre à la vue)
$output = $crud->render();
// Fusion des paramètres personnalisés de la vue et de la sortie HTML de la bibliothèque CRUD
$crud_output = array_merge($this->view_data,(array)$output);
//Chargement de la vue finale avec le résultat de la fusion
$this->load->view('formulation/index.php',$crud_output);
Veuillez noter que l'en-tête et le pied de page devront être chargés normalement dans la vue, qui contiendra a minima le code suivant :
<?php
$view_data['css_files']=$css_files;
$view_data['js_files']=$js_files;
$view_data['page_title']=$page_title;
$this->load->view('Head',$view_data);
echo $output; //Sortie HTML de la bibliothèque CRUD
//...
?>
<!-- Messages non intrusifs avec humane.js -->
<?php if($this->session->flashdata('message')){ ?>
<script>
humane.log("<?=$this->session->flashdata('message');?>");
</script>
<?php } ?>
<!-- Conteneur div des redirections JS à partir des formulaires CRUD -->
<div id="crud_redirect"></div>
<?php $this->load->view('Footer'); ?>
Les formulaires CRUD utilisant AJAX, il est impossible d'effectuer une redirection personnalisée à partir d'une fonction callback, sauf en utilisant Javascript pour écrire dans le formulaire avant un ajout ou une mise à jour de données.
Cependant, dans la plupart des cas vous souhaiterez plutôt rediriger l'utilisateur après l'ajout ou la mise à jour.
Pour le faire, il est possible de modifier le message de succès/d'erreur normalement affiché en y ajoutant une balise <script></script>
contenant le code de redirection :
//Redirect after successful insert/update:
$crud->set_lang_string('update_success_message',
'Redirection vers DuckDuckGo... <script language="text/javascript">window.location.replace("http://www.duckduckgo.com");</script>');
$crud->set_lang_string('insert_success_message',
'Redirection vers DuckDuckGo... <script language="text/javascript">window.location.replace("http://www.duckduckgo.com");</script>');
Cependant, cela ne suffit pas, car la bibliothèque humane.js affichant les messages de succès/d'erreur n'exécute pas de code javascript par mesure de sécurité.
Pour que la redirection Javascript fonctionne, il faut également ajouter dans la vue une balise spéciale : <div id="crud_redirect"></div>
: c'est finalement celle-ci qui accueillera le code javascript redirigeant l'utilisateur.
Idéalement, placez-la en fin de fichier, juste avant le chargement du pied de page (consultez le fichier qui contient les fonctions Javascript d'affichage des messages de succès/d'erreur CRUD pour voir comment cela fonctionne : /webapp/assets/grocery_crud/js/notify.js
).
Dans le cas d'une redirection automatique vers la liste des enregistrements (state='list'), par exemple lorsque le bouton Sauver et revenir à la liste d'un formulaire est cliqué, il peut être suffisant de placer le code suivant en tête de la fonction du contrôleur :
//Redirect in case of success when saving data
if (strstr(current_url(),'success')) {
redirect(<URL de redirection>,true);
}
Important ! La création d'un champ caché est incompatible avec les relations.
Voici comment ajouter un champ caché à un formulaire avec une valeur par défaut :
$crud->field_type('my_field', 'hidden',$this->session->userdata('default_value'));
Note : une valeur par défaut peut être affectée de la même manière à un champ de type enum.
Le CRUD ne supporte les valeurs par défaut que pour les champs cachés (de type hidden) ou enum.
Un moyen rapide d'affecter une valeur par défaut à un champ texte ou dropdown du CRUD est de le faire avec Javascript.
Note : les champs de type dropdown sont générés avec le plugin jquery chosen : lorsqu'une nouvelle option est sélectionnée, un traitement spécifique doit être effectué pour que le changement soit pris en compte en appelant la méthode javascript $('#id_du_champ').trigger('chosen:updated');
Voici ce qu'il faut ajouter au contrôleur qui génère le CRUD pour définir la valeur 1 comme valeur par défaut du champ de type dropdown nommé champ1 :
$view_data['selectDefault']=array("field-champ1"=>'1');
Dans le cas d'un champ texte, le code serait le suivant :
$view_data['textDefault']=array("field-champ1"=>'1');
Dans la vue qui affiche le CRUD, le code PHP suivant générera le code javascript requis pour mettre automatiquement à jour la valeur de l'élément champ1 du formulaire :
<?php
echo <<<EOT
<script>$(document).ready(function() {
EOT;
if(isset($selectDefault)){
foreach ($selectDefault as $key => $value) {
echo <<<EOT
$("#$key").val('$value');
$('#$key').trigger('chosen:updated');
EOT;
}
}
if(isset($textDefault)){
foreach ($textDefault as $key => $value) {
echo <<<EOT
document.getElementById("$key").value = '$value';
EOT;
}
}
echo "});";
echo "</script>";
?>
Pour désactiver les fonctions CRUD de votre choix, utiliser les fonctions suivantes :
$crud->unset_list(); //Supprime la liste des enregistrements
$crud->unset_read(); //Supprime la lecture d'un enregistrement
$crud->unset_clone(); //Supprimer la fonction cloner
$crud->unset_edit(); //Supprime la fonction éditer
$crud->unset_delete(); //Supprimer la fonction effacer
Dans le cas ou la liste est supprimée, il faudra également probablement rediriger les utilisateurs en cas de succès (voir ci-dessus).
Modifier les messages de succès/d'erreur
Les messages de succès ou d'erreur sont définis dans le fichier /assets/grocery_crud/languages/english.php
(remplacez english par la langue souhaitée, par ex. french).
Si vous souhaitez modifier les messages de succès pour un seul formulaire, vous pouvez utiliser les fonctions suivantes dans le contrôleur :
$crud->set_lang_string('update_success_message',
"Mon message en cas de mise à jour réussie");
$crud->set_lang_string('insert_success_message',
"Mon message en cas d'ajout réussi");
Vous pouvez utiliser la fonction getState()
:
$state=$crud->getState();
$this->view_data['state']=$state;
if ($state=='add' || $state=='edit') {
//Code à exécuter uniquement en cas d'ajout/d'édition
}
if ($state=='list' || $state=='read') {
//Code à exécuter uniquement en cas d'affichage/d'affichage de la liste
}
Dans la fonction CRUD du contrôleur :
$crud->set_rules('mon_champ',$this->lang->line('lib_mon_champ'),'callback_capitals_dash_spaces');
Ensuite, définissez la fonction callback de validation correspondante (sans le préfixe spécial callback_ !) :
public function capitals_dash_spaces($str)
{
if ((bool) preg_match('/^[A-Z0-9 _-]+$/', $str)) {
return true;
} else {
$this->form_validation->set_message('capitals_dash_spaces',
sprintf(
$this->lang->line('msg_x_field_can_have_only_capitals_dash_spaces'),
$this->lang->line('lib_content')
)
); //Le champ %s ne peut contenir que des lettres capitales, -, _ et des espaces.
return false;
}
}
Voici comment inclure des listes de valeurs dépendantes ou liées (la sélection d'une valeur dans la liste 1 entraîne le chargement de la liste de valeurs 2 avec des valeurs filtrées issues de la base de données).
Notez que cette opération est une des plus complexes à réaliser avec la bibliothèque CRUD.
TODO
Vous pouvez utiliser la fonction suivante dans le contrôleur :
$crud->unset_back_to_list();
Pour définir une relation avec une vue MySQL ou avec une table dépourvue de clé primaire, il faut indiquer préalablement quelle est la clé à utiliser à la bibliothèque CRUD, sous peine de générer une erreur SQL :
//Voir http://www.nagarajupulimamidi.com/set-relation-table-view-grocery-crud/
$crud->set_primary_key('table_key','table_name');
Vous pouvez soit créer un champ de type enum
dans la base de données, ou bien utiliser la fonction suivante :
$crud->field_type('agreement','dropdown',array('0' => 'No', '1' => 'Yes'),1);
Cela est nécessaire lorsque vous avez ajouté des champs, par exemple pour effectuer des traitements dans des fonctions callback : si des champs qui n'existent pas dans la base de données sont transmis, une erreur SQL sera générée au moment de l'insertion/modification de vos données. Il faut donc les supprimer au préalable, par exemple dans une fonction callback appelée avant l'insertion :
$crud->callback_before_insert(array($this,'unset_some_field'));
function unset_some_field($post_array)
{
unset($post_array['some_field']);
return $post_array;
}
Voici la liste de référence des fonctions supportées pour la génération de formulaires CRUD :
nom de la fonction | Description |
---|---|
add_action | Ajout d'une action personnalisée (bouton) |
add_fields | Champs visibles dans le formulaire d'ajout |
callback_add_field | This callback escapes the default auto field output of the field name at the add form. |
callback_after_delete | The callback runs when the operation delete completed successfully |
callback_after_insert | This is a callback after the auto insert of the CRUD. |
callback_after_update | This is a callback that is used after the automatic update of the CRUD. |
callback_after_upload | A callback that triggered after the upload functionality. |
callback_before_delete | This callback runs before the auto delete of the crud. |
callback_before_insert | This callback runs before the auto insert of the crud. |
callback_before_update | This callback runs before the auto update of the crud. |
callback_before_upload | A callback that triggered before the upload functionality. This callback is suggested for validation checks. |
callback_column | This callback runs on each row. It escapes the auto column value and runs the callback. |
callback_delete | This callback escapes the auto delete of the CRUD , and runs only the callback. |
callback_edit_field | This callback escapes the default auto field output of the field name at the edit form. |
callback_field | This callback escapes the default auto field output of the field name for the add and edit form. |
callback_insert | This callback escapes the auto insert of the CRUD, and runs only the inserted callback. |
callback_read_field | This callback escapes the default auto field output of the field name at the read form. |
callback_update | This callback escapes the auto update of the CRUD , and runs only the callback. |
callback_upload | Callback qui remplace le champ d'envoi de fichier par défaut |
change_field_type | Modifie le type de champ par défaut |
columns | Champs visibles pour l'affichage d'une donnée/l'affichage de la liste des données |
display_as | Modifie le libellé d'un champ |
edit_fields | Champs visibles dans le formulaire d'édition |
fields | Champs visibles dans les formulaires d'ajout/d'édition |
field_type | Alias de la fonction change_field_type. |
getState | Obtention de l'état sous forme de chaîne de caractères (selon la documentation) |
getStateInfo | Obtention de l'information d'état de l'opération qui vient d'être effectuée |
get_primary_key | Obtention de la clé primaire Note : le résultat des fonctions get est disponible après l'appel à render(). |
in_where* | Semblable à la fonction in_where de CodeIgniter pour construire la liste |
like | Semblable à la fonction like de CodeIgniter pour construire la liste |
limit | Semblable à la fonction limit de CodeIgniter pour construire la liste |
order_by | A quick first order_by (same as codeigniter) to our list |
or_like | Semblable à la fonction or_like de CodeIgniter pour construire la liste |
or_where | Semblable à la fonction or_where de CodeIgniter pour construire la liste |
render | Fonction qui génère la sortie HTML de la bibliothèque CRUD : présente à l'utilisateur un formulaire d'ajout, d'édition, une liste de données (tableau) ou l'affichage d'un enregistrement, selon l'état courant |
required_fields | Définit les champs obligatoires pour les formulaires d'ajout/d'édition |
set_crud_url_path | Permet de corriger la construction des URLs lorsque le chemin n'est pas spécifié correctement, notamment lorsque des routes personnalisées sont utilisées |
set_field_upload | Transforme un champ en envoi de fichier |
set_language | Définit la langue de l'interface |
set_lang_string | Définit directement la chaîne de caractères pour une langue |
set_model | Définit le modèle que le CRUD doit utiliser (ce modèle doit toujours étendre grocery_Model) |
set_primary_key | Définit la clé primaire à utiliser pour une table |
set_relation | Définit une relation 1-n dans la base de données |
set_relation_n_n | Définit une relation n-n dans la base de données |
set_rules | Définit des règles de validation (identique à la fonction CodeIgniter set_rules) |
set_subject | Définit un libellé de sujet pour indiquer quelles données sont manipulées |
set_table | Définit la table de la base de données dont les données principales seront extraites |
set_theme | Définit le thème de la bibliothèque CRUD. Le thème par défaut de chora est AEdatatables ; un autre thème plus dépouillé est disponible (flexigrid). |
unique_fields | Définit les champs qui stockent des valeurs uniques dans la base de données |
unset_add | Supprime l'action d'ajout |
unset_add_fields | Supprime les champs du formulaire d'ajout |
unset_back_to_list | Supprime les boutons et messages "Revenir à la liste" |
unset_clone | Supprime l'action de clonage |
unset_columns | Supprime les colonnes de la liste |
unset_delete | Supprime l'action de suppression |
unset_edit | Supprime l'action d'édition |
unset_edit_fields | Supprime les champs du formulaire d'édition |
unset_export | Supprime la fonction d'export |
unset_fields | Supprime les champs des formulaires d'ajout et d'édition |
unset_list | Supprime la liste des données |
unset_operations | Supprime toutes les actions : seule la liste des données demeure visible |
unset_print | Supprime la fonction d'impression |
unset_read | Supprime la fonction d'affichage des données |
unset_texteditor | Supprime l'éditeur de texte enrichi (RTF) pour les champs spécifiés |
where | Semblable à la fonction where de CodeIgniter pour construire la liste |
(*) fonction propre à chora.
Les fonctions qui empêchement le chargement de JQuery, JQueryUI et Bootstrap ont été supprimées car elle n'ont pas de sens dans le cas de chora.
Ce document a été publié le 2019-01-13 22:39:54. (Dernière mise à jour : 2020-10-01 09:50:58.)