Commit 954487b9 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Docs reprises du dokuwiki et converties en md (script de conversion inclu).

parent 322b9b50
Pipeline #3508 failed with stages
in 2 minutes and 35 seconds
......@@ -19,4 +19,20 @@ C'est aussi le module de base (fondations) de toutes nos applications web qui :
## Documentation
- [Installation](./doc/Installation.md)
- [Configuration](./doc/Configuration.md)
- [Services](./doc/Services.md)
- [Modèles](./doc/Modeles.md)
- [Plugins de contrôleur (controller plugins)](./doc/Plugins.md)
- [Aides de vue (view helpers)](./doc/ViewHelpers.md)
- [Contrôleurs](./doc/Controleurs.md)
- [Formulaires](./doc/Formulaires.md)
- [Filtres](./doc/Filtres.md)
- [Validateurs](./doc/Validateurs.md)
- [MVC](./doc/MVC.md)
- [Message](./doc/Message.md)
- [Divers](./doc/Divers.md)
- [Historique](./doc/Historique.md)
- [Eléments de page riches (mélangeant HTML et JS)](./doc/ElementsPageRiches.md)
- [Javascript](./doc/Javascript.md)
- [Widgets](./doc/widgets.md)
====== Configuration ======
Il s'agit ici d'adapter certaines options de configuration du module.
===== Configuration globale =====
* Copier/coller/renommer le fichier ''config/unicaen-app.global.php.dist'' du module vers ''config/autoload/unicaen-app.global.php'' de votre projet.
* Adapter les options de config à votre contexte (sans modifier les noms des clés)...
==== Fiche d'identité de l'appli ====
Il s'agit de renseigner nom de l'appli, description, numéro et date de version, adresses et/ou numéros de téléphones de contact, URL des pages externes "mentions légales" et "informatique et libertés", exemple :
<file php>
$settings = array(
'app_infos' => array(
'nom' => "GesNum",
'desc' => "Gestion des services numériques",
'version' => "1.0.0",
'date' => "05/09/2013",
'contact' => array('mail' => "dsi.applications@unicaen.fr", /*'tel' => "01 02 03 04 05"*/),
'mentionsLegales' => "http://www.unicaen.fr/outils-portail-institutionnel/mentions-legales/",
'informatiqueEtLibertes' => "http://www.unicaen.fr/outils-portail-institutionnel/informatique-et-libertes/",
),
);
</file>
===== Configuration locale =====
* Copier/coller/renommer le fichier ''config/unicaen-app.local.php.dist'' du module vers ''config/autoload/unicaen-app.local.php'' de votre projet.
* Adapter les options de config à votre contexte (sans modifier les noms des clés)...
==== Annuaire LDAP ====
Clé '''ldap''' : il faut configurer la connexion à l'annuaire LDAP via un compte omnipotent pour la récupération des coordonnées, affectations administratives, rôles, etc. de l'utilisateur connecté (notamment), exemple :
<file php unicaen-app.local.php>
'ldap' => array(
'connection' => array(
'default' => array(
'params' => array(
'host' => 'localhost',
'port' => 389,
'username' => "uid=xxxxxxxxxxx,ou=system,dc=unicaen,dc=fr",
'password' => "yyyyyyyyyyyy",
'baseDn' => "ou=people,dc=unicaen,dc=fr",
'bindRequiresDn' => true,
'accountFilterFormat' => "(&(objectClass=posixAccount)(supannAliasLogin=%s))",
)
)
)
),
</file>
==== Envoi de mail ====
Clé '''mail''' : options concernant l'envoi de mail par l'application, exemple :
<file php unicaen-app.local.php>
'mail' => array(
// transport des mails
'transport_options' => array(
'host' => 'localhost',
'port' => 25,
),
// adresses à substituer à celles des destinataires originaux ('CURRENT_USER' équivaut à l'utilisateur connecté)
'redirect_to' => array('bertrand.gauthier@unicaen.fr', /*'CURRENT_USER'*/),
// désactivation totale de l'envoi de mail par l'application
'do_not_send' => false,
),
</file>
==== Mode maintenance ====
Possibilité de passer l'appli en mode maintenance (indisponibilité totale) dans la config, sauf pour certaines adresses IP.
Clé '''maintenance''' : options concernant le mode maintenance de l'application, exemple :
<file php unicaen-app.local.php>
/**
* Mode maintenance (application indisponible)
*/
'maintenance' => array(
// activation (true: activé, false: désactivé)
'enable' => true,
// liste blanche des adresses IP clientes non concernées
'white_list' => [
['127.0.0.1'], // localhost
['10.60.11.88'], // Bertrand
],
),
</file>
<note important>En mode "CLI" (ligne de commande), c'est censé faire un exit(0) mais c'est pas sûr que ça fonctionne. Merci à celui qui en a la possibilité de tester ! </note>
Configuration
=============
Il s\'agit ici d\'adapter certaines options de configuration du module.
Configuration globale
---------------------
- Copier/coller/renommer le fichier
`config/unicaen-app.global.php.dist` du module vers
`config/autoload/unicaen-app.global.php` de votre projet.
- Adapter les options de config à votre contexte (sans modifier les
noms des clés)\...
### Fiche d\'identité de l\'appli
Il s\'agit de renseigner nom de l\'appli, description, numéro et date de
version, adresses et/ou numéros de téléphones de contact, URL des pages
externes \"mentions légales\" et \"informatique et libertés\", exemple :
``` {.php}
$settings = array(
'app_infos' => array(
'nom' => "GesNum",
'desc' => "Gestion des services numériques",
'version' => "1.0.0",
'date' => "05/09/2013",
'contact' => array('mail' => "dsi.applications@unicaen.fr", /*'tel' => "01 02 03 04 05"*/),
'mentionsLegales' => "http://www.unicaen.fr/outils-portail-institutionnel/mentions-legales/",
'informatiqueEtLibertes' => "http://www.unicaen.fr/outils-portail-institutionnel/informatique-et-libertes/",
),
);
```
Configuration locale
--------------------
- Copier/coller/renommer le fichier
`config/unicaen-app.local.php.dist` du module vers
`config/autoload/unicaen-app.local.php` de votre projet.
- Adapter les options de config à votre contexte (sans modifier les
noms des clés)\...
### Annuaire LDAP
Clé `'ldap`\' : il faut configurer la connexion à l\'annuaire LDAP via
un compte omnipotent pour la récupération des coordonnées, affectations
administratives, rôles, etc. de l\'utilisateur connecté (notamment),
exemple :
``` {.php}
'ldap' => array(
'connection' => array(
'default' => array(
'params' => array(
'host' => 'localhost',
'port' => 389,
'username' => "uid=xxxxxxxxxxx,ou=system,dc=unicaen,dc=fr",
'password' => "yyyyyyyyyyyy",
'baseDn' => "ou=people,dc=unicaen,dc=fr",
'bindRequiresDn' => true,
'accountFilterFormat' => "(&(objectClass=posixAccount)(supannAliasLogin=%s))",
)
)
)
),
```
### Envoi de mail
Clé `'mail`\' : options concernant l\'envoi de mail par l\'application,
exemple :
``` {.php}
'mail' => array(
// transport des mails
'transport_options' => array(
'host' => 'localhost',
'port' => 25,
),
// adresses à substituer à celles des destinataires originaux ('CURRENT_USER' équivaut à l'utilisateur connecté)
'redirect_to' => array('bertrand.gauthier@unicaen.fr', /*'CURRENT_USER'*/),
// désactivation totale de l'envoi de mail par l'application
'do_not_send' => false,
),
```
### Mode maintenance
Possibilité de passer l\'appli en mode maintenance (indisponibilité
totale) dans la config, sauf pour certaines adresses IP.
Clé `'maintenance`\' : options concernant le mode maintenance de
l\'application, exemple :
``` {.php}
/**
* Mode maintenance (application indisponible)
*/
'maintenance' => array(
// activation (true: activé, false: désactivé)
'enable' => true,
// liste blanche des adresses IP clientes non concernées
'white_list' => [
['127.0.0.1'], // localhost
['10.60.11.88'], // Bertrand
],
),
```
\<note important\>En mode \"CLI\" (ligne de commande), c\'est censé
faire un exit(0) mais c\'est pas sûr que ça fonctionne. Merci à celui
qui en a la possibilité de tester ! \</note\>
====== ApplicationController ======
C'est la classe du contrôleur fournissant les actions que l'on retrouve dans toutes nos application :
* Affichage de la page "À propos"
* Affichage de la page "Contact"
* Affichage de la page "Plan de navigation"
* Affichage de la page "Mentions légales" (ou redirection)
* Affichage de la page "Informatique et libertés" (ou redirection)
ApplicationController
=====================
C\'est la classe du contrôleur fournissant les actions que l\'on
retrouve dans toutes nos application :
- Affichage de la page \"À propos\"
- Affichage de la page \"Contact\"
- Affichage de la page \"Plan de navigation\"
- Affichage de la page \"Mentions légales\" (ou redirection)
- Affichage de la page \"Informatique et libertés\" (ou redirection)
====== Divers ======
===== Export CSV =====
UnicaenApp intègre un ensemble de classes et de méthodes qui permettent de générer facilement des contenus téléchargeables au format CSV.
Exemple d'utilisation :
<file php DemoController.php>
public function csvAction()
{
/* Création d'un nouveau modèle de données au format CSV. L'en-tête peut être renseignée dès l'instanciation. */
$result = new \UnicaenApp\View\Model\CsvModel( ['header' => ['Nom','Prenom'] ]);
/* Les données peuvent être transmises par des variables (data, header, separator, filename, delimiter)... */
$result->setVariable('data', [
['Lécluse','Laurent'],
['Morin','Paul'],
['Durand','Patrick']
]);
/* .. ou bien par des accesseurs. Ici on attribue un nom de fichier pour l'export. */
$result->setFilename('test_export_csv.csv');
/* On peut aussi ajouter au besoin des lignes avec la méthode addLine ou des tableaux avec addLines... */
$result->addLine( [
'Anquetil', 'Pierre'
] );
return $result;
}
</file>
===== Export XML =====
Il est possible de générer des fichiers XML à la volée et en utilisant le modèle MVC.
Cela se passe de la manière suivante :
Dans votre action de contrôleur :
<file php controler.php>
$data = ['balise1' => 'contenu1', 'balise2' => 'contenu2'];
$viewModel = new \UnicaenApp\View\Model\XmlModel();
$viewModel->setVariable('data', $data); // on transfère les données à la vue
$viewModel->setFileName('mon-fichier-export.xml'); // facultatif
return $viewModel;
</file>
Dans votre vue :
<file php view.phtml>
<?php
/**
* @var $data array
*/
echo "<body>\n";
foreach( $data as $balise => $valeur ){
echo "\t".$this->tag($balise)->text($valeur)."\n";
}
echo '</body>';
</file>
<WRAP center round tip 60%>
Dans cette vue, l'[[develop:unicaen2:moduleunicaenunicaenapp:viewhelpers:tag|Aide de vue Tag]] est utilisée ici pour générer des tags. Ceci évite de gérer explicitement les caractères foireux (<, >, &).
</WRAP>
Résultat :
<file xml mon-fichier-export.xml>
<?xml version="1.0" encoding="utf-8"?>
<body>
<balise1>contenu1</balise1>
<balise2>contenu2</balise2>
</body>
</file>
===== Export PDF =====
La classe ''\UnicaenApp\Exporter\Pdf'' facilite la fabrication d'un document PDF et voici ses arguments principaux :
* Nourrissage à partir de marquage HTML, spécifié directement sous forme de chaînes de caractères ou bien par l'intermédiaire d'un script de vue.
* Format A4, A3, etc., portrait ou paysage.
* En-tête contenant le logo de l'UCBN (spécifié en dur, désolé!), un titre éventuel et un sous-titre éventuel. Possibilité de différencier en-tête des pages paires et en-tête des pages impaires.
* Pied de page contenant l'heure de génération du document, le numéro de page, le nombre total de pages et un titre éventuel. Possibilité de différencier pied des pages paires et pied des pages impaires.
* Un texte en filigrane éventuel (watermark).
* Spécification possible des opérations autorisées sur le document généré et le mot de passe éventuel permettant d'ouvrir le document.
<note important>C'est la bibliothèque mPDF (http://www.mpdf1.com/mpdf/) qui motorise la génération PDF donc vous devez ajouter un truc comme ça dans les "require" de votre ''composer.json'' :
<file php composer.json>"mpdf/mpdf": "v5.7.1"</file></note>
Exemple d'utilisation :
<file php DemoController.php>
public function pdfAction()
{
$renderer = $this->getServiceLocator()->get('view_renderer'); /* @var $renderer \Zend\View\Renderer\PhpRenderer */
$exporter = new \UnicaenApp\Exporter\Pdf($renderer, 'A4', true);
$exporter->addBodyHtml('<h1>Module UnicaenApp</h1>');
$exporter->addBodyHtml('<h2>Export PDF</h2>', false);
$exporter->addBodyScript('application/demo/paragraphe.phtml', false);
$exporter->addBodyScript('application/demo/nouvelle-page.phtml', true);
$exporter->export('export.pdf');
}
</file>
===== Util =====
La classe ''\UnicaenApp\Util'' regroupe quelques méthodes statiques utiles.
==== generateStringTimestamp() ====
Génère une chaine de caractères corespondant à la date spécifiée (ou l'instant présent) au format "aaaammjj_hhmmss", pouvant être utilisée dans un nom de fichier par exemple.
Utilisation :
<code php>
$ts = \UnicaenApp\Util::generateStringTimestamp();
var_dump($ts);
// affiche '20121130_104056'
</code>
==== topChrono() ====
Permet de chronométrer le temps écoulé à plusieurs endroits de votre code.
Affiche le temps écoulé depuis le dernier top du chronomètre.
Utilisation :
<code php>
\UnicaenApp\Util::topChrono(); // affiche 'chrono: 0'
for ($i = 0; $i < 10000000; $i++) { }
\UnicaenApp\Util::topChrono("Ici"); // affiche 'Ici: 1.2799' (par exemple)
for ($i = 0; $i < 10000000; $i++) { }
\UnicaenApp\Util::topChrono("Là"); // affiche 'Là: 1.2841' (par exemple)
</code>
==== zip() ====
Compresse un fichier ou répertoire, en utilisant la classe "\ZipArchive" (l'extension PHP "php5_zip" est donc requise sur le serveur).
Utilisation :
<code php>
\UnicaenApp\Util::zip($sourceDir, $zipfilePath);
</code>
==== removeFile() ====
Supprime un fichier ou un répertoire.
Utilisation :
<code php>
\UnicaenApp\Util::removeFile($fileOrDirectoryPath);
</code>
==== formattedFloat() ====
Formatte un nombre flottant pour l'affichage.
Utilisation :
<code php>
$value = 1200.61;
echo \UnicaenApp\Util::formattedFloat($value, \NumberFormatter::DECIMAL, 1);
// résultat: "1 200,6"
echo \UnicaenApp\Util::formattedFloat($value, \NumberFormatter::CURRENCY);
// résultat: "1 200,61 €"
$value = 1247.0;
echo \UnicaenApp\Util::formattedFloat($value, \NumberFormatter::DECIMAL, -1);
// résultat: "1 247"
</code>
Divers
======
Export CSV
----------
UnicaenApp intègre un ensemble de classes et de méthodes qui permettent
de générer facilement des contenus téléchargeables au format CSV.
Exemple d\'utilisation :
``` {.php}
public function csvAction()
{
/* Création d'un nouveau modèle de données au format CSV. L'en-tête peut être renseignée dès l'instanciation. */
$result = new \UnicaenApp\View\Model\CsvModel( ['header' => ['Nom','Prenom'] ]);
/* Les données peuvent être transmises par des variables (data, header, separator, filename, delimiter)... */
$result->setVariable('data', [
['Lécluse','Laurent'],
['Morin','Paul'],
['Durand','Patrick']
]);
/* .. ou bien par des accesseurs. Ici on attribue un nom de fichier pour l'export. */
$result->setFilename('test_export_csv.csv');
/* On peut aussi ajouter au besoin des lignes avec la méthode addLine ou des tableaux avec addLines... */
$result->addLine( [
'Anquetil', 'Pierre'
] );
return $result;
}
```
Export XML
----------
Il est possible de générer des fichiers XML à la volée et en utilisant
le modèle MVC.
Cela se passe de la manière suivante :
Dans votre action de contrôleur :
``` {.php}
$data = ['balise1' => 'contenu1', 'balise2' => 'contenu2'];
$viewModel = new \UnicaenApp\View\Model\XmlModel();
$viewModel->setVariable('data', $data); // on transfère les données à la vue
$viewModel->setFileName('mon-fichier-export.xml'); // facultatif
return $viewModel;
```
Dans votre vue :
``` {.php}
<?php
/**
* @var $data array
*/
echo "<body>\n";
foreach( $data as $balise => $valeur ){
echo "\t".$this->tag($balise)->text($valeur)."\n";
}
echo '</body>';
```
\<WRAP center round tip 60%\> Dans cette vue, l\'[Aide de vue
Tag](/develop/unicaen2/moduleunicaenunicaenapp/viewhelpers/tag) est
utilisée ici pour générer des tags. Ceci évite de gérer explicitement
les caractères foireux (\<, \>, &). \</WRAP\>
Résultat :
``` {.xml}
<?xml version="1.0" encoding="utf-8"?>
<body>
<balise1>contenu1</balise1>
<balise2>contenu2</balise2>
</body>
```
Export PDF
----------
La classe `\UnicaenApp\Exporter\Pdf` facilite la fabrication d\'un
document PDF et voici ses arguments principaux :
- Nourrissage à partir de marquage HTML, spécifié directement sous
forme de chaînes de caractères ou bien par l\'intermédiaire d\'un
script de vue.
- Format A4, A3, etc., portrait ou paysage.
- En-tête contenant le logo de l\'UCBN (spécifié en dur, désolé!), un
titre éventuel et un sous-titre éventuel. Possibilité de
différencier en-tête des pages paires et en-tête des pages impaires.
- Pied de page contenant l\'heure de génération du document, le numéro
de page, le nombre total de pages et un titre éventuel. Possibilité
de différencier pied des pages paires et pied des pages impaires.
- Un texte en filigrane éventuel (watermark).
- Spécification possible des opérations autorisées sur le document
généré et le mot de passe éventuel permettant d\'ouvrir le document.
\<note important\>C\'est la bibliothèque mPDF
(<http://www.mpdf1.com/mpdf/>) qui motorise la génération PDF donc vous
devez ajouter un truc comme ça dans les \"require\" de votre
`composer.json` :
``` {.php}
"mpdf/mpdf": "v5.7.1"
```
\</note\>
Exemple d\'utilisation :
``` {.php}
public function pdfAction()
{
$renderer = $this->getServiceLocator()->get('view_renderer'); /* @var $renderer \Zend\View\Renderer\PhpRenderer */
$exporter = new \UnicaenApp\Exporter\Pdf($renderer, 'A4', true);
$exporter->addBodyHtml('<h1>Module UnicaenApp</h1>');
$exporter->addBodyHtml('<h2>Export PDF</h2>', false);
$exporter->addBodyScript('application/demo/paragraphe.phtml', false);
$exporter->addBodyScript('application/demo/nouvelle-page.phtml', true);
$exporter->export('export.pdf');
}
```
Util
----
La classe `\UnicaenApp\Util` regroupe quelques méthodes statiques
utiles.
### generateStringTimestamp()
Génère une chaine de caractères corespondant à la date spécifiée (ou
l\'instant présent) au format \"aaaammjj\_hhmmss\", pouvant être
utilisée dans un nom de fichier par exemple. Utilisation :
``` {.php}
$ts = \UnicaenApp\Util::generateStringTimestamp();
var_dump($ts);
// affiche '20121130_104056'
```
### topChrono()
Permet de chronométrer le temps écoulé à plusieurs endroits de votre
code. Affiche le temps écoulé depuis le dernier top du chronomètre.
Utilisation :
``` {.php}
\UnicaenApp\Util::topChrono(); // affiche 'chrono: 0'
for ($i = 0; $i < 10000000; $i++) { }
\UnicaenApp\Util::topChrono("Ici"); // affiche 'Ici: 1.2799' (par exemple)
for ($i = 0; $i < 10000000; $i++) { }
\UnicaenApp\Util::topChrono("Là"); // affiche 'Là: 1.2841' (par exemple)
```
### zip()
Compresse un fichier ou répertoire, en utilisant la classe
\"\\ZipArchive\" (l\'extension PHP \"php5\_zip\" est donc requise sur le
serveur). Utilisation :
``` {.php}
\UnicaenApp\Util::zip($sourceDir, $zipfilePath);
```
### removeFile()
Supprime un fichier ou un répertoire. Utilisation :
``` {.php}
\UnicaenApp\Util::removeFile($fileOrDirectoryPath);
```
### formattedFloat()
Formatte un nombre flottant pour l\'affichage. Utilisation :
``` {.php}
$value = 1200.61;
echo \UnicaenApp\Util::formattedFloat($value, \NumberFormatter::DECIMAL, 1);
// résultat: "1 200,6"
echo \UnicaenApp\Util::formattedFloat($value, \NumberFormatter::CURRENCY);
// résultat: "1 200,61 €"
$value = 1247.0;
echo \UnicaenApp\Util::formattedFloat($value, \NumberFormatter::DECIMAL, -1);
// résultat: "1 247"
```
====== Création d'éléments d'interface "riches" mélangeant HTML et Javascript ======
Il est parfois nécessaire d'adjoindre à des éléments d'interface en HTML des traitements en Javascript.
Il est préférable de concentrer le code Javascript au sein de widgets Jquery ([[https://jqueryui.com/widget/]]) enregistrées dans des fichiers au format <php>.js</php> dédiés.
* Ainsi la logique objet est préservée jusqu'au niveau de l'interface, avec tous les avantages en terme de lisibilité du sode, réutilisabilité, etc.
* Ensuite ce code n'est chargé qu'une fois par le navigateur, même si ce dernier est amené à être exploité à plusieurs endroits de la page.
* De plus, ce fichier JS peut être mis en cache par le navigateur, d'où une économie de bande passante et une rapidité accrue.
* Ensuite, le code javascript d'une application peut être "minifié", c'est-à-dire que les caractères superflus sont éliminés pour que le fichier soit encore plus rapide à charger et à analyser par le navigateur.
* Enfin, pour un développeur, il est plus simple de déboguer du code Javascript dans un fichier .js que directement au sein d'une page Web à l'aide des outils de développement livrés avec la plupart des navigateurs modernes (Firfox, Chrome, etc).
Par ailleurs, ces éléments d'interface doivent être codés de telle manière qu'ils doivent fonctionner parfaitement même si plusieurs instances sont affichés dans une même page. Autrement dit, le codage de l'élément doit être fait de telle manière que la structure de la page web sous-jacente ne doit avoir aucun effet indésirable.
En voici sans plus tarder un exemple de Widget :
* Dans ce fichier HTML, que du HTML, pas de bouts de Javascript!!
* La classe fenetre-confirmation permet de savoir que cet élément est bien une fenêtre de confirmation et donc que ceci doit être un Widget fenetreConfirmation.
* L'ID est indiqué pour pouvoir la sélectionner ensuite mais il n'est pas obligatoire de l'ajouter.
<file html>
<div class="fenetre-confirmation" id="fen1">
<p