Recommendations techniques
Un article de DocAstairs.
Sommaire
|
[modifier] Recommendations techniques
Cette rubrique à pour but de définir et de résumer certains points techniques de la plate-forme qui requierent des attentions particulières. Afin de limiter le nombre de pages de cette rubriques, tous les points techniques seront directement accéssibles de cette page, divisée en plusieurs parties.
[modifier] Le réseau
Le réseau des plates-formes AFIDE est constitué de 2 serveurs physiques (par opposition aux serveurs logiciels) : 1 sur le réseau local et 1 connecté à internet.
[modifier] Les différents types de plates-formes
On peut distinguer 2 types de plates-formes Astairs:
- les plates-formes mono-client (dédiées à la vente)
- les plates-formes PGR clientes (dédiées à la location)
Les 2 serveurs physiques disposent chacun d'une plate-forme mono-client et gèrent un ensemble de plates-formes PGR, dont le nombre évolue en fonction des besoins et des locations. Chaque client dispose ainsi d'une plate-forme, appelée actuellement PGR (Plate-forme Générique Régionale), et donc de sa propre base de données et de ses propres scripts.
Plusieurs critères différencient les plates-formes mono-client des plates-formes PGR :
- l'arborescence des scripts php
- les outils d'administration
Le détail de ces différences pourrait être complété par la suite.
[modifier] Architecture du Réseau
[modifier] Accès http
Adresses Locales | Adresses Internet | |
Production | En ligne | |
Nom | Barracuda | Hannibal |
FRONT-OFFICE MONO-CLIENT | 192.168.1.83 | WWW.INTERFORMATION.NET |
BACK-OFFICE MONO-CLIENT | 192.168.1.84 | 217.113.207.05 |
ADMINISTRATION CLIENTS PGR | 192.168.1.87 | 217.113.207.06 |
BACK-OFFICES PGR | 192.168.1.86 | ?? |
SGBD Postgres | localhost | localhost |
Administration du serveur | 192.168.1.80 | 217.113.207.05 |
Les plates-formes mono-client et PGR sont accessibles par accès http à l'aide d'un navigateur internet; 3 types d'interfaces sont accessibles :
- Front -office(fo):
L'accès aux front-offices se fait par la même adresse sur chacun des serveurs physiques : Production, En Ligne. La page d'accueil demande alors une identification par login/mot de passe, et l'utilisateur est ensuite dirigé vers le front-office de sa plate-forme. Ainsi, un login est unique sur la totalité des plates-formes du serveur physique concerné (mono-client et PGR). Le login est recherché sur les plates-formes PGR, puis sur la plate-forme mono-client.
- Back-office(bo):
Il faut distinguer ici les back-offices mono-client des back-offices PGR : sur un serveur physique donné, coexistent :
- une plate-forme mono-client (bo et fo)
- plusieurs plates-formes PGR
Chacun des serveurs physiques dispose d'une adresse IP pour chacun de ces deux types de back-office. Une adresse IP de connexion aux back-offices PGR dirige automatiquement l'utilisateur vers son back-office PGR en fonction de son login. Une adresse IP de connexion au back-office mono-client dirige automatiquement l'utilisateur vers le back-office mono-client.
- Administration clients
Permet de créer et d'administrer les plates-formes PGR d'un serveur.
[modifier] Les accès SSH
L'accès aux serveurs physiques par connexion SSH permet d'accéder à l'arborescence et donc aux scripts PHP. Un accès SSH est possible sur les 2 serveurs physiques :
- le serveur de Production est accessible par l'adresse 192.168.1.80.
- le serveur En Ligne est accessible à partir du serveur Production uniquement. Pour s'y connecter, il faut donc établir une connexion SSH vers le serveur Production en tant qu'utilisateur root:
ssh root@192.168.1.80
puis se connecter au serveur En ligne en tant qu'utilisateur webafide;
ssh webafide@admin.afide.fr
NB: seul l'accès au serveur physique de Production devrait être utilisé. En effet, l'automatisation des synchronisations rend inutile l'accès aux autres serveurs physiques en connexion SSH. Cette possibilité n'est maintenue qu'en cas de besoin exceptionnel (correction de bugs...).
[modifier] Les processus de synchronisation et de production
La multiplication du nombre de plates-formes a donné lieu à l'élaboration de scripts pour automatiser les mises à jour de leurs scripts php ainsi qu'à l'élaboration d'un nouveau processus de production.
Le processus de production se déroule comme suit :
- les développements se font sur la plate-forme mono-client PRODUCTION
- une fois achevés, ceux-ci sont reportés manuellement sur la plate-forme PGR POSTPRODUCTION, qui est la plate-forme de référence pour les synchronisations. Cette plate-forme de référence permet ainsi de synchroniser à tout moment les autres plates-formes qu’elles soient mono-client ou PGR.
Une synchronisation se déroule donc ainsi :
- Synchronisation de la plate-forme de developpement PRODUCTION avec la plate-forme de référente POSTPRODUCTION (serveur physique PRODUCTION).
- Synchronisation de la plate-forme PGR CORTEX du serveur physique En Ligne à partir de la plate-forme de référence POSTPRODUCTION.
- synchronisation des autres plate-formes du serveur physique En ligne(plate-forme monoclient, PGRs ,...) à partir de la plate-forme de référence CORTEX.
Ces synchronisations sont automatisées et modulaires. Il est possible de choisir quelles sont les plates-formes à synchroniser. Cela se fait à partir de la page d'admnistration du serveur PRODUCTION(barracuda).
Voici le détail des 3 étapes de synchronisation et de l’architecture mise en place:
Pour plus d'informations sur les synchros, voire: Les_synchros
[modifier] BDD
[modifier] Suppression des données
Le paragraphe suivant est à lire TRES ATTENTIVEMENT, car une mauvaise manipulation de DELETE peut etre source de corruption des données!
Lorsqu'il y a un héritage entre plusieurs tables, il faut toujours supprimer les enregistrement de la table père, ce qui entrainera la suppression des enregistrements fils par les ON DELETE CASCADE.
A contrario, si un enregistrement ayant un role de fils dans un héritage est supprimé, il y a RUPTURE DE L'HERITAGE. Celà aura donc pour resultat de laisser le pere en table sans le ou les fils correspondant, ce qui sera donc source de bugs à la récupération de l'ensemble des données.
[modifier] Insertion / Récupération des chaines de caractères
Pour insérer et récupérer les chaines de caractères, ils convient de respecter certaines rêgles afin de traiter de façon correcte les caractères spéciaux et le charset courant de la plate-forme.
NB: Le charset est défini par la constante PHP CHARSET. Les charsets actuellement disponibles sur la plate-forme sont : ISO-8859-15 et UTF-8.
[modifier] Insertion
Pour inserer des données en base, effectuer systématiquement un appel à la fonction addslashes(String) sur les chaines de caractères (types varchar ou text). Celà aura pour effet d'enregistrer les quotes et doubles quotes aux bons formats.
[modifier] Récupération
Afin d'afficher correctement les chaines de caractères (types varchar ou text), il faut effectuer un appel à la fonction htmlentities(String,ENT_QUOTES,CHARSET). Celà aura pour effet de formater la chaine avec des caractères affichables (pas d'interpretation HTML) tout en maintenant un encodage de caractère ( CHARSET ) et interpretation des quotes correctes .
Si une interprétation HTML est nécéssaire, il suffit d'afficher la chaine directement, sans appel a la fonction htmlentities.
[modifier] Interprétation des champs contenant des variables ($MSG_xxx)
exemple :
--- Libellé de l'étape ---
$var = '$etape_type_libelle_original='.$row[10].','; eval($var);
exemple 2:
--- Libellé de la Langue --- $libelle_langue=pg_fetch_result(get_langue($objet->getLangue()),0,1); eval("\$libelle_langue=\"$libelle_langue\";");
[modifier] Requetes SQL
[modifier] Syntaxe des requetes
Afin d'obtenir les meilleurs performances possibles, certains mots SQL sont à aviter pour les requetes. Ces mots sont:
- IN
- UNION
- CASE
Voici quelques transformations usuelles qu'il convient d'avoir à l'esprit afin d'optimiser vos requêtes:
Ici: transformations SQL usuelles
ATTENTION: vérifiez bien que la transformation opère une réduction du temps de traitement car cela n'est pas toujours le cas et peut dépendre de votre indexation, du type de données, des paramètres de votre SGBDR et des ressources de votre machine... Il n'y a pas de miracle, seul des tests peuvent vous convaincre de l'efficacité d'écrire votre requête de telle ou telle manière.
REMARQUE : toutes les transformations ne répondent pas de la même manière à la charge. Autrement dit, en fonction du volume des données telle ou telle transformation peut s'avérer gagner du temps puis en faire perdre lorsque le volume des données s'accroit. Afin d'etre sur de gagner du temps d'execution, tansformez vos requêtes et choisissez après des tests, en ré évaluant le coût à la charge.
La source de ces transformations peuvent se trouver ici
[modifier] PL/PGSQL
Des conventions de nommage ont été définie pour chacune des fonctions PHP. Ces conventions s'appliquent bien evidement aux fonctions PL/PGSQL. Cependant, comme le PL/PGSQL permet la surchage de fonctions, certaines singularités sont a souligner pour ce type de fonction:
[modifier] PHP
[modifier] Les fichiers
[modifier] Les noms de fichiers
[modifier] Les extentions
[modifier] Les repetoires
[modifier] Les fonctions
[modifier] Conventions de nommage
Le début des fonctions doit toujours commencer par l'un de ces 5 qualificatifs :
- get (retourne) : indique que la fonction retourne des données,
- set (ou 'maj')(enregistre) : indique que la fonction sert à enregistrer des données. 'set' doit être choisi pour les fonctions effectuant un 'INSERT' et 'maj' pour les fonctions effectuant des 'UPDATE'. Cependant, il est très courant que les 'INSERT' et les 'UPDATE' soient liés. On effectue souvent un test pour savoir si un enregistrement existe, et selon, on effectue un 'INSERT' ou un 'UPDATE'. Dans ce cal, il a donc été convenu de tout regrouper dans la fonction 'set', qui sera donc chargée de tester l'enregistrement et d'effectuer le traitement adapté, et de ne pas utiliser le qualificatif 'maj'.
- del (supprime) : indique que la fonction supprime des enregistrements.
- check (vérifie) : indique que la fonction sert a effectuer une vérification et qu'elle retourne un booléen (true ou false, 1 ou 0, etc..)
- is (est) :permet d'effectuer une vérification simple, dont le ou les criteres sont spéficiés dans le nom de la fonction (ex: is_parcours_supprimable). Elle retourne un booléen (true ou false, 1 ou 0, t ou f etc. ...)
Ainsi, à ce stade, on sait ce que fait la fonction de façon générale (get_, set_ ,del_, check_, is_). Ensuite, le nom de la fonction doit être composé du nom du répertoire de « lib » dans lequelle elle est présente, puis par le type de données qu'elle retourne et ses éventuels qualificatifs. Les arguments à passer à la fonction seront ensuite ajoutés au nom (on ne rajoutera pas le paramètre correspondant au nom du répertoire ). Ainsi les fonctions seront toutes de la forme:
qualificatif_repertoire_donnée(s)_qualificatifdonnées(s)_argument(s)(arguments)
Une attention particulière sera portée au singulier/pluriel des mots. Certaines fonctions sont donc à renommer, et parfois, leur remplacement dans la totalité des scripts n'est pas évident. Créer les fonctions directement avec leur nom correct est donc primordial pour ne pas utiliser des noms de fonctions dont l'écriture serait à venir, et ainsi créer un effet « boule de neige » sur le mauvais nommage des fonctions.
Le renommage des fonctions peut se faire en duplicant la fonction avec son nom correct, et ajouter le tag « @deprecated » dans le commentaire PHPDoc. Ainsi, cela permettra d'introduire pas à pas les bons noms de fonction sans avoir à parcourir la totalité des scripts, et de les recenser en vue de leur suppression future.
[modifier] exemples
Obtenir les stagiaires qui ont des évaluations finies pour une formation donnée:
get_formation_stagiaires_evaluations_finies($formation)
Obtenir les séries notées d'un stagiaire pour une formation:
get_stagiaire_series_notees_formation($stagiaire, $formation)
[modifier] Les objets
[modifier] Observations
La plate-forme est actuellement développée avec un code fonctionnel (par opposition à la POO) et est structurée par page, La Programmation Orientée Objet (POO) propose de nombreux avantages, notamment aux niveaux de la réutilisabilité du code et de la simplicité de codage pour les développeurs.
La version actuelle du serveur PHP, la version 4.1.3, propose des fonctionnalités limitées sur les Objets. Des fonctionnalités Objets plus complètes et plus performantes sont disponibles à partir de la version 5 de PHP.
[modifier] Solutions/propositions
Le moteur de recherche étant à refaire et étant relativement indépendant du reste de la plate-forme, sa refonte a été perçue comme une occasion idéale pour la création et l'utilisation d'Objets, et ce malgré les limitations de la version actuelle de PHP.
En effet, il permet de bien percevoir ce que la plate-forme pourrait gagner si elle évoluait vers la POO, tout en ne modifiant pas le fonctionnement actuel de la plate-forme et en permettant l'utilisation des Objets ailleurs dans la plate-forme.
Ainsi, le moteur de recherche propose des exemples d'utilisation d'Objets et a donné lieu à la création des objets principaux de la plate-forme, disponibles en back-office dans la librairie. Le FRONT OFFICE à lui aussi été refait en utilisant ces objets.
Le repertoire « lib » à vocation de regrouper toutes les fonctionnalités métier. Le objets présents dans cette arborescence devraient donc le pas contenir d'éléments d'affichage. Si des objets d'affichage venaient a être implémentés, il serait judicieux de les placer dans le repertoire lib_graphique, selon un principe similaire a celui du repertoire lib.
Comme la POO prendra tout son sens avec le passage du serveur PHP à la version 5, il est primordial, afin de faciliter l'adaptation des scripts de développer les classes en prenant en compte les nouvelles fonctionnalités quelle propose. La partie concernant les objets a fortement évolué entre la version de PHP actuellement utilisée par la plate-forme et la version 5. De nombreux sites détaillent ces différences, et en prendre connaissance permettrait de simplifier de façon conséquente les développements futurs.
[modifier] Passage d'objet d'une page à l'autre
Il est parfois nécessaire de passer un objet d'une page à l'autre, et une solution a été trouvée à cet effet. Il est possible de les passer par formulaire dans un champ <input type= « hidden »>. Il nécessite un traitement particulier, et des fonctions sont disponibles dans le fichier dbpostgres_fonction.php: exportObjet($objet): Permet de transformer un objet sous la forme d'une chaîne pouvant être passé comme valeur à une balise<input type= « hidden »>, et retourne cette chaîne. importObjet($objet_a_importer): Permet, à partir d'une chaîne d'un objet exporté de récupérer l'objet. L'objet est retourné par la fonction.
[modifier] Sructure recommandée pour les fichiers php
[modifier] Syntaxe des commentaires
(Ou comment bien commenter son code php pour générer une belle documentation php)
D'une façon globale, les commentaires en tête de fichier au juste au dessus des classes, fonctions, variables globales sont à rédiger de la façon suivante :
/** * Description * @standardTag */
- Exemple de documentation d'un fichier :
<?php /** * Description du fichier * * Commentaires divers sur l'utilisation ou spécificité de ce fichier * @author L'auteur * @version x.y * @package nom_du_package */ /** * inclusion du fichier d'exemple */ include("./exemple.php"); /** * Description de la variable globale * @global integer $GLOBALS['_exemple'] * @name $_exemple */ $GLOBALS['_exemple']; /** * Exemple de bloque documentaire d'une fonction * @param string $param1 description du premier paramètre * @param string $param2 description du deuxième paramètre * @return integer description du ce qui est est retourné par la fonction */ function firstFunc($param1, $param2 = 'optional'){ static $staticvar = 7; global $_myvar; return $staticvar; } /** * Description de la class * * Commentaire sur son utilisation * @package sample * @subpackage classes */ class myclass { /** * Exemple de variable multi-type * * Description de la variable * @var integer|string */ var $firstvar = 6; /** * Description de la variable * @var array */ var $secondvar = array ( 'stuff' => array ( 6, 17, 'armadillo' ), testing => anotherconstant ); /** * Constructor faisant appel à {@link $firstvar} */ function myclass() { $this->firstvar = 7; } /** * Return a thingie based on $paramie * @param boolean $paramie * @return integer|babyclass */ function parentfunc($paramie) { if ($paramie) { return 6; }else{ return new babyclass; } } } ?>
[modifier] Formulaires
[modifier] Soumission des formulaires
Afin de permettre une lecture des scripts claire, et d'avoir une certaine "indépendance" des scripts, il est souhaitable que lorsque qu'un script contient un formulaire, le traitement de sa validation se fasse dans le même script.
Il n'est donc pas recommandé de faire un script commun pour la soumission de formulaires venant de scripts différents.
Il est recommandé d'avoir la structure suivante:
- Un script = 1 ou plusieurs formulaires
- Un script avec 1 ou plusieurs formulaires = 1 ou plusieurs traitements apres validation dans le meme script
- Les traitements de validation de formulaires doivent se faire au tout début du script
[modifier] Messages de débugage
[modifier] Observations
Lors des développements et des débugages, il est souvent nécessaires d'afficher temporairement certaines variables. Ces messages sont généralement mis en commentaire ou supprimés lorsqu'ils ne sont plus utiles. Sur des scripts complexes ou souvent débugués, il est parfois laborieux d'enlever les commentaires ou de les ré écrire.
De plus il peut apparaitre interressant d'avoir différents niveau de débugage, à l'image de la plupart des applications actuelles.
[modifier] Solution
Afin de mettre en place plusieurs niveau d'affichage de débuggage, nous avons mis en place différentes constantes inspirées de PostgreSQL:
- MSG_DEBUG :
Fournis des informations aux développeurs pour l'aide au débuggage.
- MSG_INFO:
Fournis des informations implicitement requises par les dévelloppeurs pour la compréhension des scripts.
- MSG_NOTICE
Fournis des informations sur des traitements effectués de façon transparente.
- MSG_WARNING
Fournis des message d'avertissement aux utilisateurs leur indiquant des risques d'erreur.
- MSG_ERROR
Affiche des erreurs indiquant l'impossibilité d'effectuer des actions faite par les utilisateurs.
- MSG_LOG
Reporte des informations utilisées par les administrateurs, pour reporter l'activité de scripts par exemple.
- MSG_FATAL
Affiche une erreur irrécupérable, indiquant l'échec d'actions faite par les utilisateurs.
- MSG_PANIC
Affiche une erreur du à une corrucption grave de la plate-forme.
Afin de simplifier cela, 3 fonctions de debugages ont été mises en place dans le fichier dbpostgres_fonctions.php:
- httpPostVariables(): permet d'afficher les valeurs passées par formulaire à une page.
- messageDebug($message): affiche le message passé en paramètre.
- messageDebugR($message, $tableau): affiche le message passé en paramètre suivi de l'affichage du tableau en second paramètre.
[modifier] Messages de confirmation
[modifier] Observations
Lors d'une action utilisateur, essentiellement en back-office mais parfois en front-office, il est commun d'afficher un message confirmant que l'action a été effectuée ou d'indiquer un message d'erreur annonçant que l'action a échouée.
Ces messages sont rarement corrects et les méthodes pour les afficher sont souvent hétérogènes. Outre ces 2 messages, il peut apparaitre interressant d'avoir la possibilité d'afficher d'autres types de messages, tels que des messages d'avertissement par exemple.
Il faut donc une méthode unique, evolutive, et simple d'utilisation pour ces messages.
[modifier] Solution
Une telle solution à été implémentée en Version 2, grace au fait que chacunes des pages de cette version de la plate forme correspond à un objet de type AstairsPage.
Cet objet à la propriété d'afficher un message, constitué d'un libéllé et d'un type, qui est stocké en session. Il est ainsi accéssible de n'importe quel script php et est systématiquement lu à chaque affichage de page.
Une méthode simple est unique permet d'affecter ce message, et il n'y a donc pas de méthode pour le lire, ceci étant automatique.
Ainsi, pour afficher un message sur une page la méthode est la suivante:
AstairsTemplate::setPageMessage($msg,$msg_code);
où $msg est la chaine du message, et $msg_code le type du message.
Les types disponibles sont définis par des constantes:
- MSG_ERROR (valeur par défaut) Indique un message d'erreur (en rouge)
- MSG_CONFIRM Indique un message de confirmation (en vert)
- MSG_WARNING Indique un message d'avertissment (en rose)
NB: les couleurs sont ici indiquées à titre indicatif, car dépendantes des feuilles de style.
[modifier] Les objets graphiques (gui et templates)
[modifier] Heritages de gui
[modifier] Contenus des constructeurs et méthodes pour l'héritage
Certains éléments graphiques se ressemblent énormément, par exemple, un QCM et sa correction. On peut voire la correction d'un QCM comme l'affichage d'un QCM plus sa correction. Ce qui ce traduit en développement par un héritage. Ainsi, pour cet exemple, on a : QcmCorrection hérite de QCM. $this->setComponent('actions', $component,true,$this->getBlockName(),$this->getBlockVar()); Un héritage classique suffit, sauf pour les boucles. En effet, une boucle impose une construction particulière. Pour que cet héritage puisse se faire, if faut donc que la classe mère (ici QCM) soit construite d'une certaine façon pour pouvoir être héritée par la suite (par la classe QCMCorrection)
[modifier] Classe mère
Voici un exmeple d'objet graphique permettant un tel héritage (les éléments de code à respecter sont commenté et expliqués, les autres sont facultatifs):
class guiScenarioDynamique extends PageComponent{ var $obj_scenario; //on stocke l'objet de données en tant qu'attibut pour qu'il puisse etre utilisé par la méthode setBlockLine() function guiScenarioDynamique($block_target,$obj_scenario,$module_root=null,$templates=null,$theme=0){ parent::PageComponent($module_root,$templates); $this->obj_scenario=$obj_scenario; //affectation de l'attribut $this->setBlockResult($obj_scenario->getBlocs()); //affectation du resultat de requette permettant de boucler $this->set_block($block_target,'block_blocs','block_blocs_tmp'); //déclaration de la boucle $this->setBlockLineVars('block_blocs','block_blocs_tmp');//déclaration de l'héritage pour la boucle $this->setBlockLines($module_root,$templates); //affichage des éléments de la boucle (chacunes des lignes) } function setBlockLine($indice_ligne,$module_root,$templates){ //le constructeur d'une ligne (appelée automatiquement par setBlockLines) //Les arguments sont obligatoires et ne peuvent $etre ni modifié, ni complétés global $chemin_fo; $row=pg_fetch_row($this->getBlockResult(),$indice_ligne); //pour récupérer les données d'une ligne $theme_scenario=$this->obj_scenario->getThemes(0); //création du gui pour la ligne $component=new guiScenarioDynamiqueBloc('scenario_bloc',new FichierScenarioDynamiqueBloc($row[0],$row[1],$row[2],plpgsql_array_to_text_array($row[3]),plpgsql_array_to_text_array($row[4]),$row[5]),"$chemin_fo/data/contenus/".$theme_scenario[0]."/".TYPE_CATEGORIE_FICHIER_SCENARIO_DYNAMIQUE_BLOC."/",array('scenario_bloc' => $row[0].'.tpl')); //affectation du gui pour la ligne $this->setComponent('scenario_bloc', $component,true,'block_blocs','block_blocs_tmp'); return $row; //très important, on retourne la ligne pour l'utiliser dans la classe fille } }
[modifier] Classe fille
Voici un exemple de classe utilisant cet héritage(les éléments de code à respecter sont commenté et expliqués, les autres sont facultatifs):
class guiBoScenarioDynamique extends guiScenarioDynamique{ //déclaration de la classe et de l'héritage function guiBoScenarioDynamique($block_target,$obj_scenario,$module_root=null,$templates=null,$theme=0){ global $chemin_fo; parent::guiScenarioDynamique($block_target,$obj_scenario,$module_root,$templates,$theme); //appel de la classe mère } //la méthode qui permet de "compléter" l'affichage d'un ligne function setBlockLine($indice_ligne, $module_root,$templates){ global $root; //appel de la méthode de la classe mère et récupération des données pour la ligne $row=parent::setBlockLine($indice_ligne, $module_root,$templates); //constuction du gui supplémentaire (ne remplace pas , mais complete la ligne précédente) $component=new guiBoScenarioDynamiqueBlocActions('scenario_bloc_actions',$this->getFichierScenarioDynamique(), new FichierScenarioDynamiqueBloc($row[5],$row[0],$row[2],$row[1],plpgsql_array_to_text_array($row[3]),plpgsql_array_to_text_array($row[4])), $module_root,array('scenario_bloc_actions' => 'gui_bo_scenario_dynamique_bloc_actions.tpl')); $this->setComponent('scenario_bloc_actions', $component,true,$this->getBlockName(),$this->getBlockVar()); return $row; //on retourne la ligne de données au cas ou l'on ferait un héritage de cette classe } }
[modifier] Exceptions et particularités
- Comment utiliser autre chose qu'un resultat de requete pour boucler?
Pour la ligne :
$this->setBlockResult($obj_scenario->getBlocs()); //affectation du resultat de requette permettant de boucler
on peut passer un tableau par exemple (ou n'importe quoi d'autre). La méthode $this->getBlockResult() retournera alors le tableau.
Il faut cependant surcharger la méthode getNumBlockLines(), qui est appelée en interne (elle ne doit jamais etre utilisée directement), afin que la boucle puisse se faire correctement. Cette méthode doit retourner le nombre de lignes.
Dans le cas d'un tableau, on aurait à ajouter, dans la classe mère, la méthode suivante:
function getNumBlockLines(){ return count($this->getBlockResult()); }
- que peut etre l'affichage d'une ligne?
Il n'y a pas de limitation, on peut mettre dans chage ligne n'importe quoi que l'on met habituellement dans une boucle:
* une variable, avec $this->set_block_var("LINE_COLOR",$line); * un PageComponent, avec $this->setComponent('actions', $component,true,$this->getBlockName(),$this->getBlockVar());
[modifier] HTML
[modifier] Versions et navigateurs
[modifier] Observations
La plate-forme est écrite en PHP 4.3.1 et génère donc du code HTML. Le code HTML est ensuite interprété par les navigateurs, et sa qualité ainsi que son contenu intervient pour une grande part sur l'apparence de la plate-forme et sur l'apparition de bugs.
L'organisme chargé de la normalisation du HTML, le W3C (www.w3c.org) établi les versions du html, du css, et ce sans aucune référence aux navigateurs. Le développement de la plate-forme se fait sous Linux, c'est à dire en utilisant plusieurs versions de Netscape et de Mozilla, et maintenant Firefox. Le navigateur préconisé aux clients pour l'utilisation de la plate-forme est Internet Explorer. Les tests sont donc effectués sous Windows avec Internet Explorer. Le code html généré par la plate-forme est à améliorer : balises non fermées, absences des balises obligatoires (body, html),... Le code HTML est le seul visible par les utilisateurs de la plate-forme. Quand elles existent, les balises doctype (indiquant au navigateur la version du code html qu'il doit interpréter) indiquent la version HTML 4.0 Transitional.
[modifier] Propositions
Bien que l'écrasante majorité des navigateurs utilisés sur internet soit Internet Explorer, il peut être intéressant que la plate-forme puisse fonctionner « officiellement » sur d'autres navigateurs. En effet, recommander uniquement Internet Explorer pourrait apparaître comme un choix contestable étant donné le choix des plate-formes de développement : la plate-forme est développée et fonctionne sous Linux, et le navigateur recommandé n'existe pas sous se système d'exploitation. Internet Explorer étant connu pour interpréter des codes html de qualité quelconque. Le choix de cette recommandation peu être perçu comme un choix « trop facile », Le développement ne se faisant pas sous Internet Explorer, mais sous des navigateurs Linux, il y a une perte de compétence, Les navigateurs devant en principe se référer aux normes du W3C (ce qui n'est pas toujours le cas), il semble logique de faire de même afin d'être compatible avec la plus part d'entre eux. D'autant plus qu'il est plus simple de certifier une norme que de garantir un fonctionnement avec la totalité des navigateurs et de leurs versions,
Si la démarche d'Afide venait à accentuer sa position au sein du logiciel libre, il serait certainement très positif de supprimer toutes références à des logiciels propriétaires ou imposant un monopole, et de privilégier des références à des normes existantes.
Il peut donc être intéressant de formaliser et de revoir ou justifier, les choix fait concernant le code HTML, et donc les choix de navigateurs.
Il est aussi possible de cacher le source des pages html, ce qui pourrait être envisageable pour des questions de sécurité, ou encore pour empêcher les utilisateurs de la plate-forme de voire la qualité du code html généré.
[modifier] Les frames
Que se soit en Back-Office ou en Front Office, un système de frames a été mis en place :
- Une frame nommée page, qui est la frame principale où doivent être tous les affichages de la plate-forme (top.page ou top.frames[0] en javascript),
- Une frame cachée nommée deconnect, qui permet de suivre en temps réel les personnes connectées à la plate-forme: si cette frame disparaît (fermeture, plantage, remplacement,...), un script de déconnexion est lancé. Cette frame ne doit donc jamais être utilisée pour autre chose, et doit être présente tant que l'utilisateur est connecté.
- Une autre frame cachée, nommée rien, a été ajouté en front office. Elle peut être utilisée, dans certains cas, pour exécuter des scripts sans affichage.
Le système de frames permet aussi de cacher l'URL aux utilisateurs de la plate-forme.
[modifier] Le charset
Les bases de données utilisent le charset UNICODE (UTF-8), et le charset utilisé dans les pages HTML est défini par la constante CHARSET.
Le charset intervient pour l'essentiel au niveau des fichiers de langues, dans laquelle la constante CHARSET est définie. En effet, les messages des langues contenus dans ces fichiers doivent etres encodé avec le charset correspondant à la valeur de la constante.
Il est possible de convertir et de modifier la constante CHARSET de ces fichiers de façon automatisée par l'intermédiaire du BACK OFFICE en cliquant sur le lien: Gestion des Ressources Administratives/Utilitaires/Gestion du CHARSET.
La quasi-totalité des encodages de caractères est disponible dans cette interface.
[modifier] Les templates
Pour un debugage plus facile, il faut bien indenter le code html. Avec les templates, on ne peut pas toujours prévoir le niveau d'imbrication et donc le nombre d'indentation. Cependant, si ces quelques règles sont respectées, le code devrait être assez lisible.
- Passer des lignes entre les balises par paire afin qu'elle soient l'une en dessous de l'autre (pour détecter les balises en trop ou manquantes)
<div> <div> <div> <span>toto</span> </div> </div> <div> <span>toto</span> </div> </div>
- Les boucles dans les templates s'appellent toujours de la même manière, à savoir :
<!-- BEGIN block --> {BLOCK_LINE} <!-- END block -->
- Passer une ligne à la fin de chaque template (excepté pour les templates qui font l'objet d'un contenu de boucle)
- Toutes les variables des templates sont à mettre en majuscule et entre accolades
{MA_VARIABLE}
- Lors du passage de contenu par une variable, il faut respecter l'indentation dans le template fils, mais pas dans le père
<div> <div> <div> {TEMPLATE_FILS} </div> </div> </div>
<span>Hello World !</span>
[modifier] CSS
Afin d'homogéniser l'aspect de la plate-forme, un système de feuilles de style a été mis en place, mais pour le moment uniquement en BACKOFFICE.
[modifier] Présentation
Le BackOffice est définit par les 4 feuilles de styles suivantes :
Fichier | Description |
ressourcesHumaines.css | Formatage des pages des ressources Humaines. |
ressourcesPedagogiques.css | Formatage des pages des ressources Pédagogiques. |
ressourcesAdministratives.css | Formatage des pages des ressources Administratives. |
global.css | Formatage du menu principal et de certaines pages qui nécessitent de connaître le formatage des différentes ressources telles que la page d'aperçu d'une feuille de style ou encore le moteur de recherche. |
Les feuilles de style ressourcesHumaines.css , ressourcesPedagogiques.css et ressourcesAdministratives.css possèdent exactement le même nombre d’entités, avec les mêmes noms : seules les valeurs des attributs diffèrent. La feuille global.css possèdent certaines entités qui lui sont propres, ainsi que les entités de chacune des feuilles de style ressourcesXxxxx.css .
[modifier] Description
Voici les différentes entités présentes dans les 3 feuilles de style « ressources » :
Entité | Description |
couleur1 | Couleur d’arrière plan n°1 |
couleur2 | Couleur d’arrière plan n°2 |
couleur3 | Couleur d’arrière plan n°3 |
action | Mise en forme d’un lien correspondant à une action. |
retour | Mise en forme d’un lien correspondant à un retour |
titre_rubrique | Mise en forme du titre de la page |
tableau_normal | Tableau. |
tableau_normal2 | Idem mais avec une largeur plus importante, cette entité est utilisée dans les scripts ayant l’arborescence javascript sur la gauche. |
tableau_espace | Tableau dont les cellules sont légèrement espacées. |
tableau_espace2 | Idem mais avec une largeur plus importante, cette entité est utilisée dans les scripts ayant l’arborescence javascript sur la gauche. |
tableau_message | Tableau utilisé pour l’affichage d’un message. |
th | Mise en forme de l’entête des colonnes d’un tableau. |
ressourcesHumaines1 | Couleur d’arrière plan n°1 du menu principal pour les ressources Humaines. (Correspond à l’entité « couleur1 » de la feuille ressourcesHumaines.css) |
ressourcesHumaines2 | Couleur d’arrière plan n°2 du menu principal pour les ressources Humaines. (Correspond à l’entité « couleur2 » de la feuille ressourcesHumaines.css) |
ressourcesHumaines3 | Couleur d’arrière plan n°3 du menu principal pour les ressources Humaines. (Correspond à l’entité « couleur3 » de la feuille ressourcesHumaines.css) |
ressourcesPedagogiques1 | Couleur d’arrière plan n°1 du menu principal pour les ressources Pédagogiques. (Correspond à l’entité « couleur1 » de la feuille ressourcesPedagogiques.css) |
ressourcesPedagogiques2 | Couleur d’arrière plan n°2 du menu principal pour les ressources Pédagogiques. (Correspond à l’entité « couleur2 » de la feuille ressourcesPedagogiques.css) |
ressourcesPedagogiques3 | Couleur d’arrière plan n°3 du menu principal pour les ressources Pédagogiques. (Correspond à l’entité « couleur3 » de la feuille ressourcesPedagogiques.css) |
ressourcesAdministratives1 | Couleur d’arrière plan n°1 du menu principal pour les ressources Administratives. (Correspond à l’entité « couleur1 » de la feuille ressourcesAdministratives.css) |
ressourcesAdministratives2 | Couleur d’arrière plan n°2 du menu principal pour les ressources Administratives. (Correspond à l’entité « couleur2 » de la feuille ressourcesAdministratives.css) |
ressourcesAdministratives3 | Couleur d’arrière plan n°3 du menu principal pour les ressources Administratives. (Correspond à l’entité « couleur3 » de la feuille ressourcesAdministratives.css) |
th_ressourcesHumaines | Correspond à l’entité « th » de la feuille ressourcesHumaines.css |
th_ressourcesPedagogiques | Correspond à l’entité « th » de la feuille ressourcesPedagogiques.css |
th_ressourcesAdministratives | Correspond à l’entité « th » de la feuille ressourcesAdministratives.css |
lien_menu_principal | Mise en forme d’un lien du menu principal |
Tableau_menu_principal | Tableau utilisé pour le menu principal du Back Office |
titre1_menu_principal | Mise en forme des titres pincipaux du menu principal |
titre2_menu_principal | Mise en forme des titres secondaires du menu principal |
[modifier] Utilisation
[modifier] Appel d'une feuille de style dans un script
Utiliser la variable $styleCSS pour appeler la feuille de style souhaitée.
Exemples :
- Pour une rubrique concernant les ressources Humaines, renseigner la valeur $styleCSS avant l'inclusion du fichier entete.php3 ainsi :
$styleCSS = " ../style/".MY_STYLE."/ressourcesHumaines.css" ;
- Pour une rubrique qui nécessite de connaître toutes les entités :
$styleCSS = " ../style/".MY_STYLE. "/global.css" ;
Remarque : La constante MY_STYLE réfère au modèle de style utilisé (le modèle par défaut étant l’ensemble des 4 feuilles de style se trouvant dans le repertoire style/original .
[modifier] Appel d’une entité de la feuille de style dans le code HTML
Utiliser l’attribut class en appellant l’entité voulue.
Exemples :
- Pour créer un lien retour, préciser l’entité retour dans l’attribut class du lien.
<a href="exemple_de_lien.php" class="retour"> Retour </a>
- Pour colorer une ligne d’un tableau avec la deuxième couleur d’une ressource :
<tr class="couleur2"> // si c’est la feuille d’une ressource qui est utilisée <tr class="ressourcesAdministratives2"> // si c’est global.css qui est utilisé
[modifier] Modifications
Les trois feuilles de style dont le nom de fichier commencent par ressources doivent IMPERATIVEMENT posséder les mêmes entités, avec les mêmes noms et le même nombre d'attributs pour chacune des entité afin de conserver l’homogénité des styles.
- Ajout d’une nouvelle entité de style :
- Au niveau des CSS :
Si l'on souhaite par exemple ajouter une quatrième couleur pour les ressources Humaines, il faut créer la nouvelle entité dans la feuille de style ressourcesHumaines.css mais EGALEMENT dans la feuille de style ressourcesPedagogiques.css ainsi que dans ressourcesAdministratives.css. Il faudra aussi répercuter ces modifications dans la feuille de style global.css en créant trois nouvelles entités correspondant à celles créées dans chacune des feuilles ressources .
- Au niveau des scripts :
Afin de permettre ensuite au générateur de feuilles de style de prendre en compte cet ajout, il faut modifier le formulaire de création en ajoutant les champs correspondant à la modification voulue dans le fichier style/creerStyle.php et dans le fichier qui génére ces feuilles de style (fichier style/creerCSS.php ).
- Au niveau de l’aperçu :
Ne pas oublier également de modifier le fichier style/apercuStyle.php de façon à avoir un aperçu complet d’un modèle de style.