GenList2 - Framework YSM (PHP)

Caractéristiques

Le Framework YSM est écrit en PHP5 et est testé avec un serveur Web Apache2.

Les interfaces administratives utilisent XHTML, CSS et Javascript.

Modèles

Les modèles sont séparés en trois types: Base de données, Répertoire de Fichiers et Liste statique.

Traduction

Les chaînes de caractères de l'interface générée sont en français et anglais. On peut retrouver les traductions dans le répertoire app/po/{codelangue}.php. Par défaut l'interface utilise la langue de la configuration. Les codes de langues sont par défaut "fr" et "en".

Pré-Requis

Exigences systèmes

  • PHP 5 - j'utilise des PHP version 5.2.9 et 5.5.9
  • MySQL. Même si j'utilise PDO, les requêtes sont écrites pour MySQL.
  • Apache2 - je n'ai jamais essayé sur un autre type de serveur.

Connaissance

Vous devez avoir des connaissances de base dans un environnement LAMP. Le générateur de code GenList2 génère du code PHP 5 (avec classes), du XHTML, du CSS et du Javascript. Même si le générateur crée un script MySQL, vous devez créer et configurer la base de données avant d'utiliser le code généré.
Un fichier de configuration Apache2 est aussi fourni pour créer un hôte virtuel. Vous pouvez l'utiliser si vous savez comment gérer les hôtes virtuelles sur votre serveur HTTP Apache2.

Aperçu

Voici un aperçu rapide des caractéristiques que vous apprécierez en utilisant GenList2-YSM :

  • Programmer pour des projets vendus à des clients
  • Compatible avec PHP 5. Interface en XHTML/CSS/Javascript.
  • Fonctions CRUD (create, read, update, delete) intégrées pour les interactions avec la base de données. Peut être modifier pour chaque modèle.
  • Formulaire pour éditer et modifier une liste d'éléments ou un seul.
  • Validation de base des données du côté serveur
  • Vue codée en PHP et XHTML. Pas de ré-interprétation d'une syntaxe étrangère à PHP
  • Assistants (helpers) qui s'ajoutent ou s'enlève selon vos besoins
  • Connexion à l'interface de gestion protégé par un système d'identification simple (Array) ou tables MySQL. Peut aussi être adapté à LDAP avec quelques modifications.
  • Localisation française et anglaise supportée par le générateur en ligne. D'autres langues pourraient être ajoutées.

Principe de base

Le générateur utilise des fonctions avec une syntaxe qui ressemble aux fonctions de PHP, par exemple fetch_item(), get_title(). Seul les tables MySQL avec une clé primaire numérique sont supportées. GenList2 n'utilise pas comme CakePHP des identifiants qui changent selon le contexte (singulier, pluriel, majuscule, minuscule). Les identifiants sont tels que vous les définissez au départ.

Structure

Les Modèles (/app/mod{nom}/{List,Item,File}.php) sont des objets pour gérer les listes et les données. On peut avoir des listes statiques qui ne changent pas (Array), des listes MySQL dynamiques, des répertoires de téléchargement de fichier. Une liste MySQL est séparée en deux classes PHP: nom_Item (un item individuel) et nom_List (une liste d'items). Si vous gérer des fichiers, la classe nom_File sera créée.

Les Contrôleurs (/app/mod{nom}/index.php) gèrent les requêtes en utilisant les modèles et en envoyant les résultats dans les vues. On utilise généralement les contrôleurs pour gérer les modèles de listes MySQL mais on peut aussi utiliser un contrôleur pour gérer une liste de fichiers dans un répertoire. Il y a deux contrôleurs de base fourni avec GenList2: auth (pour l'authentification) et default (accueil ou aide).

Les Vues sont des fichiers PHP contenant le code XHTML. Elles utilisent les variables des contrôleurs. Elles sont stockés dans le répertoire du module selon la zone et l'action. Par exemple, si j'ai une vue pour enregistrer une page dans la zone "admin", le fichier sera: /app/modpage/admin_save.php

Les Assistants (/app/helpers) sont des classes indépendantes qui offrent des fonctionnalités supplémentaires pour les vues, les contrôleurs ou pour les modèles. Les types de contrôleurs de base (MySQL, fichier) sont définies dans un Assistant.

Les fichiers du répertoire de configuration (/app/config) permettent de configurer l'application, la connexion SQL et l'authentification.

Le répertoire (/app/core) possède des fichiers qui contient la logique de base (__autoload, gestionnaire du contrôleur, chargement de l'admin).

Le répertoire de traduction (/app/po) fournit les fonctions de traductions et chaque fichier de langues.

Le répertoire des données (/app/data) permet d'intégrer des fonctions globales qui sont propres à votre projet.

Une requête typique de l'interface d'administration

Voici en gros les composants appelés lors de l'affichage du formulaire d'édition simple d'un item "livre" avec uid=1. L'URL serait "http://genlist.local/admin/index.php?module=livre&action=save&p[]=1"

Le paramètre module correspond au nom du modèle. Le paramètre action correspond à la méthode dans le contrôleur. Dans la partie /admin/, ces méthodes commencent par le préfixe admin_. Les paramètres envoyés à la méthode sont dans le tableau p. On pourrait utiliser d'autres paramètres, mais il ne seront pas traités automatiquement par l'appel des contrôleurs.

  1. La page d'administration /admin/index.php est appelée et charge la gestion interne de l'administration "/app/core/admin.php". Le reste du code de /admin/index.php ne fait qu'afficher le résultat dans une page XHTML. La vue appelle le gestionnaire de contrôleur.
  2. Le coeur du programme "/app/core/admin.php" se charge d'appeler le bon contrôleur avec les paramètres de l'URL. Ainsi, module=livre, action=save et p[]=1 appellera la méthode livre_index->admin_save(1). Le gestionnaire de contrôleur appelle le contrôleur.
  3. La méthode admin_save est soit définie dans le contrôleur du livre (/app/modlivre/index.php) ou soit dans l'assistant MySQL de base (/app/helpers/Mysql.php). Le contrôleur livre a généralement le plus de pouvoir même si la majorité des méthodes de bases sont dans l'assistant MySQL.
  4. Le contrôleur MySQL de base créera le modèle "livre" (/app/modlivre/Item.php) et enregistra les données si nécessaires. Le contrôleur crée et modifie le modèle.
  5. Ensuite, le contrôleur MySQL utilisera la vue (/app/modlivre/admin_save.php) pour l'affichage. Cette vue contient le code XHTML du formulaire. Le contrôleur génère la vue finale.

Structure de fichiers

Voici une liste complète de la structure des fichiers

  • admin : répertoire d'administration, avec authentification
    • js : fichiers javascripts
    • css : fichiers css
  • app : répertoire de l'application
    • config : configuration de l'application, de la base de données, de l'authentification et d'apache2
    • core : coeur du système
    • data : fonction propre à l'application
    • helpers : assistants pour les contrôleurs, les modèles ou les vues.
    • mod{nom} : répertoire du modèle "nom" avec le contrôleur, modèle et vue.
    • po : fichiers de traductions et langages
    • sql : table sql et indexes (peut être effacé après la création)
  • OPTIONNEL: wpproxy : si vous avec choisit un template à la wordpress pour la partie public
  • OPTIONNEL: drupalproxy : si vous avec choisit un template à la drupal pour la partie public

Conventions

  • Le nom des classes des modèles se terminent par _Item, _List, _File avec le nom du modèle. Les noms des fonctions sont généralement en minuscule séparés par des caractères de soulignement "_", comme fetch_item, update_item, get_id ou set_id.
  • Le nom des classes des contrôleurs se terminent par _index et se retrouve dans le fichier index.php de chaque module.
  • Pour les méthodes des contrôleurs, il n'est pas possible d'avoir une action externe qui commence par un caractère de soulignement "_" car ces noms de méthode sont réservés pour des usages internes.
  • Le nom des classes des assistants se terminent par _Helper.
  • Le nom des fichiers n'utilisent pas de préfixes _Helper.

Développer

Voici comment développer un gestionnaire de données?

Pré-requis

  • Un serveur HTTP. Apache avec mod_rewrite est préférable si vous voulez utiliser les contrôleurs pour le site web, mais en aucune façon obligatoire.
  • PHP 5
  • MySQL 4 ou 5 (si on veut utiliser les modèles de la base de données).
  • sendmail/postfix si on veut envoyer des courriels

Préparation à l'installation

Vous devez avoir un navigateur compatible avec Firefox (Iceweasel, Mozilla). J'ai déjà essayé avec webkit mais je ne l'utilise que très rarement, donc il peut y avoir des bugs.

Pour utiliser le code généré vous devez avoir un serveur web et une base de données MySQL. Vous devez avoir la commande tar si vous utilisez l'exportation tar.

Installation

Pour installer le code généré, vous pouvez soit copier/coller chaque fichier manuellement et recréer la hiérarchie de fichiers où utiliser l'exportation tar.

Pour exporter le projet dans le fichier genlist.tar, cliquer sur le menu Projet > Importer/exporter et sur le bouton "Exporter les fichiers en .tar". Lorsque la fenêtre "Ouverture de genlist.tar" apparaît, sélectionner l'option Enregistrer le fichier et cliquer sur le bouton OK. Une fois le fichier télécharger, décompresser le fichier genlist.tar dans un répertoire tar xvf genlist.tar. Un répertoire "genlist" sera créer avec tous les fichiers. Généralement les fichiers dans genlist/ devrait être copié à la racine de votre site Web.

Une fois les fichiers installées, il faut créer la base de données et créer un utilisateur qui correspond à votre configuration. La configuration de la base de données est dans le fichier app/config/database.php. Le fichier app/sql/table.sql contient les instructions nécessaires pour créer la base de données et l'utilisateur dans les premières lignes en commentaire du fichier.

Les tables de la base de données peuvent être créées en exécutant le fichier app/sql/table.sql avec l'utilisateur configuré. Pour MySQL, on peut utiliser la commande suivante: mysql -u genlist --password=genlist genlist < app/sql/table.sql .

Ensuite, on peut utiliser ou non le fichier de configuration apache qui se retrouve dans app/config/apache2.conf et le copier dans /etc/apache2/sites-enabled/nomdusite.conf. Il suffit de recharger la configuration d'apache avec /etc/init.d/apache2 reload.

Si vous utiliser les modules de téléchargement de fichiers, il est nécessaire de permettre au serveur d'écrire dans le répertoire files/. La commande pour donner les droits d'écriture est: chgrp -R www-data files/ && chmod -R g+w files/ .

À ce stade, la partie administration devrait être prête sur votre serveur.

Utiliser les contrôleurs et la récriture pour le site web

Il est possible d'utiliser les contrôleurs et la réécriture d'URL pour le site web en tant que tel. GenList2 ne génère pas encore le code pour cette gestion mais il devrait être assez proche de app/core/admin.php.

Dans la configuration Apache2 de l'hôte virtuel, on pourrait écrire ceci dans le bloc <Directory></Directory>:

<Directory /var/www/vhost/nomdusite/>
# ...
  RewriteEngine On
  RewriteCond %{REQUEST_FILENAME} !-d 
  RewriteCond %{REQUEST_FILENAME} !-f 
  RewriteRule ^(.*)$ index.php?url=$1 [L,QSA]
# ...
</Directory>

Le paramètre url va contenir le chemin controleur/methode/parametre1/parametre2 et peut être extrait à l'aide d'un explode('/', $_GET['url']) . Ensuite il suffit d'appeler le bon contrôleur et la bonne méthode dans le fichier index.php du site web.

Configuration

La configuration est la partie la plus importante de GenList2.

C'est ici qu'on définit la connexion à la base de données, la langue utilisée, les modèles de données, les contrôleurs.

La configuration de base se retrouve dans les fichiers du répertoires app/config/.

Configuration générale

Dans le menu Configuration, on retrouve divers renseignements sur l'ensemble du projet.

URL du site web
L'URL du site. C'est la constante WEBSITE_URL et la configuration de l'hôte virtuel
URL alias du site web (dev)
L'URL de développement du site. Utlisé dans la configuration de l'hôte virtuel (ServerAlias)
Racine du site web
Le site web peut être dans un sous-répertoire "/genlist/" ou à la racine "/" du serveur.
Titre du site web
La constante WEBSITE_TITLE
Courriel du site web
La constante WEBSITE_EMAIL utilisé pour les courriels et la configuration de l'hôte virtuel.
Préfix (cookie)
La constante P (préfix) est utilisé pour définir des variables globales propre au système et pour les témoins (cookies). Par exemple, la langue est définit dans la variable $GLOBALS[P.'language'].
Langue (défaut)
Code à deux lettres. Présentement seul 'fr' et 'en' sont définis dans le répertoire app/po/. Si vous voulez ajouter une langue, on doit modifier la variable $GLOBALS[P.'availableLangs'] du fichier app/config/system.php et ajouter un fichier app/po/<code>.php.
Avec éditeur HTML
Ajoute le code nécessaire pour utiliser un éditeur TinyMCE dans la partie administration. Il faut installer manuellement TinyMCE dans le répertoire tinymce à la racine du site web. Voir la balise script du fichier admin/index.php pour plus de détails.
Plugin "tableau" dans tiny_mce
Si l'éditeur TinyMCE est utilisé, on peut ajouter le plugin "tableau" avec cette option.
Avec OpenLayers
Permet d'ajouter une carte de sélection de coordonnées GPS

Authentification

GenList2 génère une partie administration gérer par des utilisateurs systèmes. Ces utilisateurs sont définies dans le fichier app/config/auth.php dans le tableau $users. Il est donc nécessaire d'avoir au moins un utilisateur. Si on veut plusieurs utilisateurs, on peut ajouter manuellement des lignes dans le tableau $users.

Usager
Nom de l'administrateur par défaut (sans espace ou caractère spéciaux)
Mot de passe
Mot de passe de l'administrateur par défaut
Avec MySQL ?
Permet d'utiliser une table MySQL pour l'authentification des autres utilisateurs. On doit choisir le nom du modèle, le champ nom d'usager et champ mot de passe. Noter que le modèle pour l'authentification aura une nouvelle fonction login($username,$password). Habituellement, je crée un modèle qui se nomme "user" avec trois champs: uid (clé primaire), username (varchar(255)) et password (varchar(32)).

Configuration de la base de données

Dans le menu Configuration > SQL, on peut définir les renseignements utiles à la connexion à la base de données MySQL.

Ces renseignements sont enregistrés dans le fichier app/config/database.php.

Ils sont aussi utilisés dans l'exemple de création de base de données et de création de l'usager dans le fichier app/sql/table.sql.

Autre configuration

Les autres configurations seront expliquées dans la création des modèles et des contrôleurs.

Les modules Relations et Contraintes sont des fonctionnalités expérimentales qui ne sont pas prêtes à être utilisées ou expliquées.

Modèles

La configuration des modèles est la partie la plus importante de GenList2. Ce sont les modèles qui définissent les tables de la base de données et les formulaires d'administration.

Comprendre les modèles

GenList2 gère deux types de modèle. Les modèles MySQL et les modèles "labellist" ou liste d'étiquettes. Le modèle MySQL est dynamique et peut être modifier à l'aide de formulaire XHTML par l'administrateur. Pour chaque modèle MySQL, une table MySQL est crée et deux classes PHP. Les modèles MySQL sont liés à des contrôleurs. Le modèle "liste d'étiquettes" est statique, n'est pas lié à un contrôleur et doit être modifié manuellement dans la classe PHP. Il est représenté par une seule classe PHP.

Les modèles "labellist" sont généralement utilisés pour des données non modifiable par l'administrateur comme des catégories, une liste de mois, une liste de langues. Par exemple, je définis parfois une modèle "statut" avec les étiquettes "Brouillon", "Publié" et "Archivé".

GenList2 permet maintenant de classifier les modèles MySQL à l'aide de catégorie. Ces catégories sont utilisés pour générer un menu dans la partie administration. Il n'y a pas encore de représentation PHP de ses catégories.

Les modèles MySQL

Les modèles de type "MySQL" sont créés à partir du Menu Modèles > Ajouter un modèle. On doit entrer le nom du modèle, le type "mysql", préciser ou non la catégorie et cliquer sur le bouton Ajouter.

Voici les différentes options de configuration:

Catégorie
Catégorie du modèle (selon la liste des catégories). Vide si aucune catégorie.
Nom de la table
Nom de la table MySQL. Devrait être le même que le modèle.
Modèle hérité
Abstract. Seul ce modèle est testé présentement.
Champ étiquette
Nom du champ qui sera utilisé dans les listes déroulantes générés avec le modèle. Si le champ est vide, la clé primaire sera utilisée.
Modèle parent
Si on indique un nom de modèle, celui-ci affichera un formulaire d'édition pour ajouter plusieurs items du modèle en cours. Par exemple, si j'ai une liste d'entreprise et que chaque entreprise possède plusieurs produits, je devrais indiquer dans le modèle "produit" que le modèle parent est "entreprise". De plus, je devrais ajouter une clé étrangère (champ FK) dans le modèle "produit" qui fait référence à la clé primaire d'entreprise. Dans le formulaire d'édition d'une entreprise, je pourrai ajouter des produits directement à partir de la page d'édition.
Modèle limite
Le modèle limite permet de limiter le nombre d'enregistrements lié à un modèle parent. Si dans mon exemple d'entreprise avec des produits je voudrais indiquer qu'il y a toujours trois types de produit (base, intermédiaire, expert), je pourrais créer un modèle "labellist" qui se nomme "typeproduit" avec trois étiquettes. Ensuite, je dirais que le modèle limite de mon produit est "typeproduit". Dans le formulaire d'édition d'une entreprise, je pourrais ajouter trois produits: un de base, un intermédiaire et un expert. J'utilise principalement le modèle limite avec les langues. Je crée un modèle "languages" avec français/anglais, je créer un modèle parent "model1" et un sous-modèle "model1lang". Dans le modèle "model1lang", le modèle parent est "model1" et le modèle limite est "languages". Ainsi, je peux avoir un modèle qui comporte des champs communs et qui est traduit en deux langues dans la même interface d'administration.
ID avec autre nom
Devrait être vide.

Les champs MySQL

Les modèles MySQL sont formés de champ MySQL. Le premier champ, qui est obligatoire est la clé primaire. Le défaut est id bigint(11) primary key (PK), auto-increment (AI). On peut changer le nom de la clé, mais il est primordial qu'il y est au moins une, de type numérique.

Pour ajouter un champ, il faut cliquer sur le bouton "Ajouter un champ". Le nouveau champ est de type varchar(32) par défaut.

Voici la description des options de configuration des champs:

Nom
Nom du champ, il existe des noms réservés qui ne peuvent pas être utilisé par MySQL.
Type
Type de la base de données.
Type Form
Actuellement, les chaînes de caractères peuvent être redéfinies en deux types pour un meilleur affichage dans les formulaire d'édition. Ainsi, un type TEXT pourra utilisé le type "html" pour utiliser un éditeur tinymce et un VARCHAR pourra utilisé un type "file" pour télécharger des fichiers (images, photos, logo, fichier attaché, ...). Note qu'il faut aussi ajouter, pour le type "file", un type de fichier avec le nom du champ. Voir la section "Les types de fichier".
Longueur
La longueur du champ principalement pour les entiers (1 à 11) et les champs varchar (1 à 255).
Valeur par défaut
Si la case est cochée, cette valeur sera utilisé lors de la création d'un nouvel item.
Insert
Constante ou code utilisé dans les requêtes INSERT. La case "internal" doit être cochée. On peut utiliser la syntaxe mysql:CODEMYSQL pour utilisé une fonction MYSQL (exemple mysql:NOW() pour un champ datetime) ou la syntaxe php:CODEPHP (exemple $GLOBALS['auth']->getUsername()) pour utilisé du code PHP.
Update
Constante ou code utilisé dans les requêtes UPDATE. La case "internal" doit être cochée. Le même format que Insert s'applique.
PK
Clé primaire
FK
Clé secondaire, on doit cocher et indiquer le nom du modèle (pas de la table), le caractère point et le nom du champ. Par exemple: entreprise.uid. Utiliser pour afficher des listes déroulantes ou les restrictions de modèles (Modèle parent). Si on utilise un modèle de type "labellist", on doit écrire "nommodele.uid" .
AI
Auto-increment. Utilisé pour les clés primaires.
NULL
Indique si on permet les valeurs nulles dans le champ. Rarement utilisé.
Internal
Permet de ne pas afficher le champ lors de l'insertion ou de la mise à jour de la table. Ce champ est interne. Très utile conjointement avec la valeur par défaut, la valeur Insert et la valeur Update.

Les types de fichier

Lorsqu'un champ texte est un champ formulaire de type "file", on peut définir le type de fichier qui peut être téléchargé. Ce type est associé à un modèle. Pour ce faire, on cliquer sur le bouton "Ajouter un type de fichier" dans l'affichage d'un modèle. Ensuite, il suffit de paramètrer chaque colonnes.

Nom du champ
Il s'agit du nom du champ dans la liste des champs du modèle.
Type
Image, PDF ou all. Image est limité à png, gif et jpg.
Répertoire/
Nom du sous-répertoire où sont stockés les fichiers. J'utilise généralement un répertoire de la forme {modele}/{nomchamp}/. Par exemple si je spécifie "users/avatar/" alors les fichiers seront stockés dans le répertoire files/users/avatar/.
Extension
Liste d'extension utilisées, si vide, utilise les extensions par défaut du type. On doit les spécifier avec les guillemets simples et le point, séparé par des virgules. Exemple: ('.pdf','.odt','.doc')
Redimensionner image?
Permet de redimensionner un fichier de type "image". Les proportions sont conservées. Si l'image est de format portrait et la largeur/hauteur est de format paysage, les dimensions seront inversées.
Largeur
Largeur maximum
Hauteur
Hauteur maximum

Dans le code généré, ces renseignements sont stockés dans la classe {modele}Item_ dans le tableau associatif $this->_filesinfo, déclaré dans le constructeur de la classe. Pour le type image, il est possible de générer des miniatures automatiquement en ajoutant pour un type de fichier l'attribut 'thumbnails'. Cet attribut est une liste qui contient des propriétés pour chaque variantes des photos. Les dimensions des thumbnails peuvent être plus grandes que l'image normale.

    $this->_filesinfo['photo'] = array(
      'path'=>'users/photo/',
      'ext'=>array('.jpg','.gif','.png'),
      'type'=>'image',
      'maximagesize'=>array('width'=>640,'height'=>480),
      'thumbnails'=>array(
        'mini'=>array('path'=>'users/photo_mini/', 'width'=>64, 'height'=>48),
        'big'=>array('path'=>'users/photo_big/', 'width'=>1000, 'height'=>1000),
      )
    );

La classe {modele}_Item possède des méthodes pour obtenir les propriétés des photos. En autre:

get_file_path($fieldname, $thumbnailKey = null)
Retourne le chemin complet du fichier (sur le disque dur). On peut avoir le chemin d'une miniature en utilisant le deuxième argument.
get_file_location($fieldname, $thumbnailKey = null)
Retourne l'URL relative au serveur Web. On peut avoir le chemin d'une miniature en utilisant le deuxième argument.

Le modèle MySQL Abstract

Le modèle MySQL Abstract est un modèle de base pour les autres modèles MySQL. Ainsi, on peut définir des champs qui seront communs à toutes les autres classes (par exemple: uid, status, modauthor, moddate). Ce modèle définit les comportements de base des modèles MySQL. C'est dans ce modèle qu'on exécute les requêtes SQL finales. L'ajout de champ ce fait de la même façon que le formulaire d'édition des modèles MySQL.

Les modèles "labellist"

Les modèles de type "labellist" sont créés à partir du Menu Modèles > Ajouter un modèle. On doit entrer le nom du modèle, le type "labellist" et cliquer sur le bouton Ajouter.

En cliquant sur le nom du modèle dans la liste des menus on peut indiquer le type de clé (entier ou chaînes de caractères). La case à cocher "Traductions des étiquettes" indique si on veut traduire ou non la valeur des étiquettes. La traduction de cette liste n'est pas encore supportée par le module "Traductions" et doit être ajouté manuellement dans le fichier po/{langue}.php, dans le tableau $GLOBALS[P.'translation_{langue}']. Dans le cas qu'on utilise la traduction, la valeur devrait être en anglais.

Ce modèle est enregistré dans le fichier app/models/{nom}List.php et crée la classe {nom}_List. Les deux méthodes sont: toArray() pour retourner la liste complète traduite et get_label($key) qui retourne la traduction pour la clé ($key) demandée.

NOTE: intégrer avec le module de traduction

Les catégories de modèles (menu)

Les catégories sont utilisées pour générer un menu dans la partie administration.

Par exemple, si j'ai trois tables livre, film et cd et je voudrais avoir un menu "Collection", je devrais faire ceci:

  1. Dans le menu Modèles, section Catégorie de modèle (menu), cliquer sur le bouton Ajouter. Entrer comme nom "Collection" et comme identifiant "collection". Pour confirmer, cliquer sur Mettre à jour.
  2. Pour chaque table livre, film et cd, créer un modèle de type mysql et sélectionner la catégorie "Collection" et cliquer sur Ajouter.
  3. Pour chaque table livre, film et cd, créer un contrôleur de type Mysql avec le même nom que le modèle et cliquer sur Ajouter.
  4. Dans le fichier admin/index.php, vous devriez voir la ligne suivante: $controllersleft = array(array('menu'=>'collection', 'controllers'=>array('livre','film','cd')));. Cette ligne indique qu'il va y avoir un menu "Collection" avec trois sous-menus.
  5. Dans le menu Traductions, une étiquette "modelcat_collection_label" sera créer avec la traduction anglaise/française à modifier selon vos préférences. De plus, des étiquettes pour les trois contrôleurs seront créés.

Les catégories ne sont pas obligatoires. Si un modèle avec contrôleur n'appartient à aucune catégorie, il sera directement affiché dans le menu de la partie administration.

Créer les tables de la base de données

Une fois les modèles définis, le fichier app/sql/table.sql possède les instructions MySQL pour la création des tables. Le fichier possède aussi la création des index sur les clés étrangères.

On peut toute fois utiliser les classes des modèles List pour créer les tables. Le code ressemblerait à pour le modèle "foo":

require_once 'app/core/init.php';
$modelList = new foo_List($GLOBALS['db']);
$modelList->create_table();

Cependant, la classe ne gère pas la création d'index.

Récupérer vos données

Voici la procédure pour récupérer le champ "title" d'un item du modèle "foo". Clé primaire #3. Si on veut l'afficher dans une page HTML, il est préférable d'utiliser la fonction html() ou htmlspecialchars().

// démarrer le système
require_once 'app/core/init.php';

// nouvel item "foo"
$modelItem = new foo_Item($GLOBALS['db']);

// récupération de l'item 3
if ( $modelItem->fetch_item(3)) {

  // affichage du champ "title"
  echo $modelItem->get_title();
}

Voici la procédure pour récupérer 10 enregistrements "foo" avec un filtre sur une colonne "status". Note que la fonction toArray() retourne une liste d'array() et non pas une liste d'objet Item.

// démarrer le système
require_once 'app/core/init.php';

// nouvel item "foo"
$modelList = new foo_List($GLOBALS['db']);

// order doit être manuellement ajouté à la liste des ordres possibles dans la fonction toArray().
$pager = array('limit'=>10, 'order'=>'title');

// Si le champ status est une clé étrangère, le filtre sera automatiquement créé. 
// Sinon on doit ajouter chaque filtre supplémentaire dans la fonction toArray();
$filter = array('status'=>2);

// appel de la fonction. $pager est modifié, le compte total (sans la limite) est dans $pager['count'].
$list = $pager->toArray($pager, $filter);

foreach($list as $item) {
  echo $item['title'];
}

Sauvegarder vos données

On peut facilement enregistrer des données avec la fonction insert_item() et update_item($id).

// démarrer le système
require_once 'app/core/init.php';

// nouvel item "foo"
$modelItem = new foo_Item($GLOBALS['db']);

// ajout d'un item
$modelItem->set_title('bla bla bla');
$newId = $modelItem->insert_item();

// récupération et modification de l'enregistrement 3
if ( $modelItem->fetch_item(3)) {
  $modelItem->set_title('new title for item #3');
  $modelItem->update_item(3); // le numéro de l'item est obligatoire.
}

Particularités du système

La fonction insert_item() fonctionne avec l'item en cours et retourne le nouveau uid. La clé primaire est modifiée mais il n'y aura pas de récupération de l'enregistrement. En d'autres mots, si vous générer des champs dans la requête d'insertion SQL ou qu'il y a des valeurs par défaut SQL qui sont utilisées, vous devez faire un fetch_item($newuid) par la suite pour travailler avec l'objet.

La fonction update_item($id) n'utilise pas la clé primaire de l'item en cours. Vous pouvez donc récupérer l'item 2 et le copier dans l'item 3 si vous faite un fetch_item(2) et ensuite un update_item(3).

Supprimer des données

Il suffit d'utiliser la fonction delete_item($id). Avant la suppression, l'enregistrement sera stocké dans l'objet. Après la suppression on pourrait réutiliser ces renseignements pour l'insérer de nouveau avec un insert_item().

// démarrer le système
require_once 'app/core/init.php';

// nouvel item "foo"
$modelItem = new foo_Item($GLOBALS['db']);

// suppression de l'enregistrement 4
$modelItem->delete_item(4);

Associations : relier les modèles entre eux

Cette partie est en développement...

Contrôleurs

Le menu contrôleur permet d'ajouter des contrôleurs au projet. Un contrôleur est l'intermédiaire entre la vue et les modèles.

Il existe trois types de contrôleurs en ce moment

  1. Les contrôleurs de base. Auth (authentification) et Default (par défaut)
  2. Les contrôleurs MySQL. Chaque modèle MySQL doit avoir un contrôleur MySQL pour être gêré.
  3. Les contrôleurs Fichier. Permet de gérer un répertoire de fichiers ou d'images.

Attibuts internes

Les contrôleurs possèdent plusieurs attributs internes pour gérer les liens dans la partie administration, les filtres, les modèles et les vues.

$name
Nom du contrôleur.
$adminActions
Liste d'actions dans le menu de la partie administration (<div id="actions">). Une action possède les attributs "admin" (true/false), label (étiquette), module, action et params (array). Accessible dans les vues.
$pages
?
$rights
Tableau de droits. Chaque droit est vérifier avec la méthode $GLOBALS['auth']->hasRights(RIGHTS_ADMIN, $right, 0).
$filters
Filtres envoyés aux listes d'administration. Accessible dans les vues.
$sets
Liste de variable disponibles dans les vues. $keywords, $body, $q, $view et $layout sont toujours définies (ou vide). Plusieurs méthode sont disponible pour utiliser $sets. $this->_set($param, $value) modifie une variable. $this->_append($param, $value) ajoute une chaîne à une variable et $this->_appendArray($param, $value) ajoute un élément à une tableau. Si la variable $view n'est pas vide, le fichier app/views/$views.php sera utilisé, sinon la variable $body sera affichée.

Méthodes d'administration

Le nom des méthodes d'administration commence par le préfixe admin_. La méthode d'administration par défaut est admin_index().

Contrôleurs MySQL

Les contrôleurs MySQL gère à la fois le formulaire en tableau (multisave) et le formulaire individuel (edit). On peut définir un répertoire pour la liste d'image dans TinyMCE avec le champ "Répertoire d'image pour l'éditeur".

Fonctionne interne:

Les contrôleurs MySQL ajoute automatiquement les actions Gérer et Ajouter, et créer les modèles dans les variables $this->lists["nomModele"] et $this->items["nomModele"].

L'attribut $tableFormDefault permet de gérer l'affichage par défaut du formulaire par défaut. 'limit' pour le nombre d'enregistrement, 'order' pour l'ordre d'affichage et 'new' pour le nombre de nouvel enregistrement.

La vue multisave possède les variables: $form_action, $pager_url, $name, $modifids, $item, $list, $view, $editItems, $pager. Il est possible d'exécuter du code avant ou après l'affichage du formulaire en redéfinissant les méthodes: _pre_table_form() et _post_table_form().

La vue edit possède les variables: $form_action, $name, $id, $item, $editors, $editorImageFolder, $view. Il est possible d'exécuter du code avant ou après l'affichage du formulaire en redéfinissant les méthodes: _pre_edit_form() et _post_edit_form().

Les méthodes admin_shortlist, admin_shortedit, admini_shortsave gère les modèles secondaire dans les iframes.

Traductions

Lors de la création des formulaires et des contrôleurs, plusieurs chaîne de caractères seront créer et pourront être traduite. La gestion des traductions permet de gérer les langues française et anglaise. Il faut cliquer sur Appliquer pour enregistrer les changement.

Vues

Voici d'autres variables définies par les contrôleurs:

$form
Classe utilitaire pour les formulaire (<select>).

Fonctions de traduction

Les principales fonctions déclarés dans app/po/index.php.

  • __($str) traduit une phrase ou un mot anglais
  • _label($label) traduit une étiquette.
  • _html($str) traduit une phrase ou un mot et encode en HTML
  • _labelhtml($label) traduire une étiquette et encode en HTML
  • _url($params...) retourne un lien.
  • _urlhtml($params...) retourne un lien et encode en HTML.
  • _format_date(time()); _date(time()) retourne la date du jour. Exemple: '10 janvier 2012'
  • _format_filesize($filesize); _filesize($filesize) retourne une représentation textuel d'un nombre d'octets. 1024 devient "1 Kio" (Mio, Kio, o)
  • _month($number) retourne le nom du mois. 1 devient "Janvier"/"January".
  • _number($number) retourne un chiffre en lettres. 9 devient "neuf" ou "nine".
  • _format_phone($no, $label = '', $post = ''); _phone($no, $label = '', $post = '') retourne un numéro de téléphone formaté. '1234567890' devient 123-456-7890.
  • _format_postalcode($postalcode); _postalcode($postalcode) retourne un code postal formaté. 'J9L1A1' devient 'J9L 1A1'.
  • _format_price($price, $currency = ''); _price($price, $currency = '') retourne le prix. _price('100') devient '1,00', _price('100','$') devient '1,00 $'.
  • get_http_accept_language(array('fr','en'), 'fr') retourne une langue supportée selon le navigateur de l'usager.

Tâches courantes avec GenList

TODO: À définir ce qui est courant ou pas.

Composants intégrés

Voici quelques classes aidantes

Captcha
ajout d'une petite question mathématique.
Email
Envoie de courriel.
RSS
Écriture de fil RSS.
Image
Redimensionnement d'images.
Form
Écrit des champ de formulaire HTML (select).

Exemple d'applications

TODO: Lister fichiers genlist_nomprojet.xml

Annexes

Ajouter un formulaire à un contrôleur

1. Ouvrir le fichier du contrôleur dans app/controllers/{nomcontrolleur}.php

2. Ajouter une fonction admin_ et spécifier la vue à charger et l'url du formulaire (form_action)
public admin_{nomaction}() {
  // handle form
  if (array_key_exists('save', $_POST)) {
    // do something...
  }
  
  $this->_set('form_action', _geturl('admin',$this->name,'import'));
  $this->_set('view', 'admin_{nomcontrolleur}_{nomaction}');
}

3. Créer la vue app/views/admin_{nomcontrolleur}_{nomaction}.php

4. Ajouter le code pour le formulaire:
<form enctype="multipart/form-data" accept-charset="utf-8" method="post" class="editform" action="<?php echo html($form_action) ?>">
  <div>
    <p id="cmd">
      <input type="submit" name="save" value="<?php echo __html('Save') ?>" />
    </p>
  </div>
</form>

5. Ajouter le lien dans l'interface d'administration

 a) Dans le fichier admin/index.php, ajouter au tableau $controllersleft = array(), un item:
    array('module'=>'{nomcontrolleur}', 'action'=>'{nomaction}')

    Dans le fichier app/po/fr.php, ajouter la traduction française du menu dans la variable $GLOBALS[P.'translation_label_fr']
    'admin_{nomcontrolleur}_short_{nomaction}' => 'Importer',

 b) Une autre façon de faire serait de rajouter une action propre à un contrôleur, dans app/controllers/{nomcontrolleur}.php
    Ajouter la ligne suivante après la ligne parent::__construct() du constructeur:
    $this->adminActions[] = array('label'=>'{etiquette}', 'admin'=>true, 'action'=>'{nomaction}', 'module'=>$this->name, 'params'=>'');

Modèle NN

L'utilitaire MysqlNN permet de créer une relation multiple dite N à N. La situation se présente si vous avez des pages de contenu (pages) et des catégories (categorie). Pour chaque pages vous pouvez avoir 0 à N catégories. Et chaque catégorie peut être associé à 0 ou N pages.

Exemple de tables:

page
- uid
- title

category
- uid
- title

pagecategory
- uid
- nopage
- nocategory

Lors de la création des trois modèles il faut modifier "page" et "pagecategory". Dans le modèle page, il faut ajouter l'option nn = pagecategory (4e colonne des propriétés du modèle). Cela permet de créer le code d'édition des catégories dans index.php et admin_save.php.

Ensuite, dans le modèle pagecategory, il faut choisir le sous-type N à N (NN) pour créer le fichier NN.php.

Commentaires

L'ordre des chapitres est inspiré des chapitres de CakePHP.

Il existe aussi une sortie "expérimentale" en Django (en python) mais elle n'est pas activement développée car je ne connais pas assez Django.