Académique Documents
Professionnel Documents
Culture Documents
Version 2.x
01 April 2016
Pour Commencer
1
Tutoriel dun Blog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Blog Tutoriel - Ajouter la logique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Installation
Conditions requises . . . . . . . . . .
Licence . . . . . . . . . . . . . . . .
Tlcharger CakePHP . . . . . . . . .
Permissions . . . . . . . . . . . . . .
Configuration . . . . . . . . . . . . .
Dveloppement . . . . . . . . . . . .
Production . . . . . . . . . . . . . . .
Installation avance et URL Rewriting
A vous de jouer ! . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
31
31
31
32
32
32
33
34
34
43
Controllers (Contrleurs)
Le Controller App . . . . . . . .
Les paramtres de requte . . . .
Les Actions du Controller . . . .
Request Life-cycle callbacks . .
Les Mthodes du Controller . . .
Les attributs du Controller . . .
En savoir plus sur les controllers
Views (Vues)
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
51
51
52
52
54
54
62
64
87
i
Templates de Vues . . . . . . .
Utiliser les Blocs de Vues . . . .
Layouts . . . . . . . . . . . . .
Elements . . . . . . . . . . . . .
Crer vos propres classes de vue
API de View . . . . . . . . . . .
En savoir plus sur les vues . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
87
89
92
94
97
97
100
Models (Modles)
205
Comprendre les Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
Pour en savoir plus sur les Models . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
Librairies du Coeur
Usage Gnral . . . . . . . .
Behaviors (Comportements)
Components (Composants) .
Helpers (Assistants) . . . . .
Utilitaires . . . . . . . . . .
.
.
.
.
.
345
345
504
533
587
682
Plugins
Comment Installer des Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comment Utiliser des Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comment Crer des Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
799
799
801
803
10 Dveloppement
Configuration . . . .
Routing . . . . . . .
Sessions . . . . . . .
Exceptions . . . . . .
Gestion des Erreurs .
Debugger . . . . . .
Testing . . . . . . . .
REST . . . . . . . .
Filtres du Dispatcher
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
809
809
811
813
814
814
815
816
823
824
827
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
849
849
863
881
887
895
897
900
925
929
11 Dploiement
935
Vrifier votre scurit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
ii
937
937
940
942
.
.
.
.
.
945
945
947
949
949
951
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
953
953
954
955
956
956
15 Tutoriels et exemples
Tutoriel dun Blog . . . . . . . . . . . . . . . . . . . . .
Blog Tutoriel - Ajouter la logique . . . . . . . . . . . . .
Authentification Simple et Autorisation de lApplication
Application Simple contrle par Acl . . . . . . . . . . .
Application Simple contrle par Acl - partie 2 . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
957
957
966
978
986
993
16 Contribuer
Documentation . . . . . . . . . . . . . .
Tickets . . . . . . . . . . . . . . . . . . .
Code . . . . . . . . . . . . . . . . . . . .
Normes de codes . . . . . . . . . . . . .
Guide de Compatibilit Rtroactive . . . .
Le processus de dveloppement CakePHP
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
997
997
1006
1006
1009
1020
1023
17 Annexes
2.8 Guide de Migration . . . . . . . .
2.7 Guide de Migration . . . . . . . .
2.6 Guide de Migration . . . . . . . .
2.5 Guide de Migration . . . . . . . .
2.4 Guide de Migration . . . . . . . .
2.3 Guide de Migration . . . . . . . .
2.2 Guide de Migration . . . . . . . .
2.1 Guide de Migration . . . . . . . .
2.0 Guide de Migration . . . . . . . .
Migration de la version 1.2 vers la 1.3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1025
. 1025
. 1027
. 1029
. 1032
. 1037
. 1043
. 1050
. 1056
. 1067
. 1099
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
iii
1119
Index
1121
iv
CHAPITRE 1
Pour Commencer
Le framework CakePHP fournit une base robuste pour votre application. Il peut grer tous les aspects, de
la requte initiale de lutilisateur et son cheminement jusquau rendu final de la page web. Et puisque le
framework suit les principes du MVC, il vous permet de facilement personnaliser et offre la plupart des
aspects de votre application.
Le framework fournit aussi une structure organisationnelle basique, des noms de fichier jusquaux noms
des tables de la base de donnes, en gardant toute votre application cohrente et logique. Ce concept est
simple mais puissant. Suivez les conventions et vous saurez toujours exactement o les choses se trouvent
et comment elles sont organises.
La meilleure faon de dcouvrir et dapprendre CakePHP est de sassoir et de construire quelque chose.
Pour commencer, nous construirons une application simple de blog.
3. Des connaissances de base en PHP. Plus vous aurez dexprience en programmation orient objet,
mieux ce sera ; mais nayez crainte, mme si vous tes adepte de la programmation procdurale.
4. Enfin, vous aurez besoin de connaissances de base propos du motif de conception MVC. Un bref
aperu de ce motif dans le chapitre Comprendre le systme M-V-C (Model-View-Controller). Ne vous
inquitez pas : il ny a quune demi-page de lecture.
Maintenant, lanons-nous !
Obtenir CakePHP
Tout dabord, rcuprons une copie rcente de CakePHP.
Pour obtenir la dernire version, allez sur le site GitHub du projet
https ://github.com/cakephp/cakephp/tags et tlchargez la dernire version de la 2.0.
Vous
pouvez
aussi
cloner
le
dpt
git://github.com/cakephp/cakephp.git
en
utilisant
git 1 .
CakePHP
git clone
Peu importe comment vous lavez tlcharg, placez le code lintrieur du DocumentRoot de votre
serveur. Une fois termin, votre rpertoire dinstallation devrait ressembler quelque chose comme cela :
/chemin_du_document_root
/app
/lib
/plugins
/vendors
.htaccess
index.php
README
A prsent, il est peut-tre temps de voir un peu comment fonctionne la structure de fichiers de CakePHP :
lisez le chapitre Structure du dossier de CakePHP.
Permissions du rpertoire Tmp
Ensuite vous devrez mettre le rpertoire app/tmp en criture pour le serveur web. La meilleur faon de
le faire est de trouver sous quel utilisateur votre serveur web tourne. Vous pouver mettre <?php echo
exec(whoami); ?> lintrieur de tout fichier PHP que votre serveur web execute. Vous devriez
voir afficher un nom dutilisateur. Changez le possesseur du rpertoire app/tmp pour cet utilisateur. La
commande finale que vous pouvez lancer (dans *nix) pourrait ressembler ceci :
$ chown -R www-data app/tmp
Si pour une raison ou une autre, CakePHP ne peut crire dans ce rpertoire, vous verrez des avertissements
et des exceptions attrapes vous disant que les donnes de cache nont pas pu tre crites.
1. http ://git-scm.com/
Le choix des noms pour les tables et les colonnes ne sont pas arbitraires. Si vous respectez les conventions
de nommage de CakePHP pour les bases de donnes et les classes (toutes deux expliques au chapitre
Conventions de CakePHP), vous tirerez profit dun grand nombre de fonctionnalits automatiques et vous
viterez des tapes de configurations. CakePHP est suffisamment souple pour implmenter les pires schmas
de bases de donnes, mais respecter les conventions vous fera gagner du temps.
Consultez le chapitre Conventions de CakePHP pour plus dinformations, mais il suffit de comprendre que
nommer notre table posts permet de la relier automatiquement notre model Post, et quavoir des champs
modified et created permet de les avoir grs automagiquement par CakePHP.
Une fois votre nouveau fichier database.php sauvegard, vous devriez tre en mesure douvrir votre
navigateur internet et de voir la page daccueil de CakePHP. Elle devrait galement vous indiquer que votre
fichier de connexion a t trouv, et que CakePHP peut sy connecter avec succs.
Note : Rappelez-vous que vous aurez besoin davoir PDO, et pdo_mysql activs dans votre php.ini.
Configuration facultative
Il y a quelques autres lments qui peuvent tre configurs. La plupart des dveloppeurs configurent les
lments de cette petite liste, mais ils ne sont pas obligatoires pour ce tutoriel. Le premier consiste dfinir
une chane de caractres personnalise (ou grain de sel) afin de scuriser les hashs. Le second consiste
dfinir un nombre personnalis (ou graine) utiliser pour le chiffrage.
Le grain de sel est utilis pour gnrer des hashes. Changez la valeur par dfaut de Security.salt
dans /app/Config/core.php la ligne 187. La valeur de remplacement doit tre longue, difficile
deviner et aussi alatoire que possible :
/**
* Une chane alatoire utilise dans les mthodes de hachage scurises.
*/
Configure::write('Security.salt', 'pl345e-P45s_7h3*S@l7!');
La graine cipher est utilise pour le chiffrage/dchiffrage des chanes de caractres. Changez la valeur
par dfaut de Security.cipherSeed dans /app/Config/core.php la ligne 192. La valeur de
remplacement doit tre un grand nombre entier alatoire :
/**
* Une chane alatoire de chiffre utilise pour le chiffrage/dchiffrage
* des chanes de caractres.
*/
Configure::write('Security.cipherSeed', '7485712659625147843639846751');
URL Rewriting
Apache et mod_rewrite (et .htaccess)
Alors que CakePHP est construit pour travailler avec mod_rewrite et habituellement il lest nous avons
remarqu que certains utilisateurs se battent pour obtenir un bon fonctionnement sur leurs systmes.
Ici il y a quelques trucs que vous pourriez essayer pour que cela fonctionne correctement. Premirement,
regardez votre fichier httpd.conf (Assurez-vous que vous avez dit le httpd.conf du systme plutt que celui
dun utilisateur- ou le httpd.conf dun site spcifique).
Ces fichiers peuvent varier selon les diffrentes distributions et les versions dApache. Vous pouvez allez
voir http ://wiki.apache.org/httpd/DistrosDefaultLayout pour plus dinformations.
1. Assurez-vous quun .htaccess est permis et que AllowOverride est dfini All pour le bon DocumentRoot. Vous devriez voir quelque chose comme :
# Chaque rpertoire auquel Apache a accs peut tre configur avec
# respect pour lesquels les services et les fonctionnalits sont
# autoriss et/ou dsactivs dans ce rpertoire (et ses sous-rpertoires).
#
# Premirement, nous configurons "par dfault" pour tre un ensemble
# trs restrictif de fonctionnalits.
#
<Directory />
Options FollowSymLinks
AllowOverride All
#
Order deny,allow
#
Deny from all
</Directory>
Pour les utilisateurs qui ont apache 2.4 et suprieur, vous devez modifier le fichier de configuration
pour votre httpd.conf ou la configuration de lhte virtuel pour ressembler ce qui suit :
<Directory /var/www/>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
2. Assurez-vous que vous avez charg correctement mod_rewrite. Vous devriez voir quelque chose
comme :
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
Dans la plupart des systmes, ceux-ci vont tre comments donc vous aurez juste besoin de retirer les
symboles # en dbut de ligne.
Aprs que vous avez fait des changements, re-dmarrez Apache pour tre sr que les paramtres soient
actifs.
Vrifiez que vos fichiers .htaccess sont effectivement dans le bon rpertoire.
Cela peut arriver pendant la copie parce que certains systmes dexploitation traitent les fichiers qui
commencent par . en cach et du coup ne les voient pas pour les copier.
3. Assurez-vous que votre copie de CakePHP vient de la section des tlchargements du site de notre
dpt Git, et a t dzipp correctement en vrifiant les fichiers .htaccess.
Le rpertoire root de CakePHP (a besoin dtre copi dans votre document, cela redirige tout vers
votre app CakePHP) :
<IfModule mod_rewrite.c>
RewriteEngine on
[L]
RewriteRule
^$ app/webroot/
RewriteRule
(.*) app/webroot/$1 [L]
</IfModule>
Le rpertoire app de CakePHP (sera copi dans le rpertoire suprieur de votre application avec Bake) :
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule
^$
webroot/
RewriteRule
(.*) webroot/$1
</IfModule>
[L]
[L]
Le rpertoire webroot de CakePHP (sera copi dans le webroot de votre application avec Bake) :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
</IfModule>
Si votre site CakePHP a toujours des problmes avec mod_rewrite, essayez de modifier les
paramtres pour les Htes Virtuels. Si vous tes sur Ubuntu, modifiez le fichier /etc/apache2/sitesavailable/default (lendroit dpend de la distribution). Dans ce fichier, assurez-vous que
AllowOverride None a t chang en AllowOverride All, donc vous devez avoir :
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>
Si vous tes sur Mac OSX, une autre solution est dutiliser loutil virtualhostx 2 pour faire un Hte
Virtuel pour pointer vers votre dossier.
Pour beaucoup de services dhbergement (GoDaddy, 1and1), votre serveur web est en fait dj distribu partir dun rpertoire utilisateur qui utilise dj mod_rewrite. Si vous installez CakePHP dans
un rpertoire utilisateur (http ://exemple.com/~username/cakephp/), ou toute autre structure dURL
qui utilise dj mod_rewrite, vous aurez besoin dajouter les requtes (statements) RewriteBase aux
fichiers .htaccess que CakePHP utilise (/.htaccess, /app/.htaccess, /app/webroot/.htaccess).
2. http ://clickontyler.com/virtualhostx/
Ceci peut tre ajout dans la mme section que la directive RewriteEngine, donc par exemple, votre
fichier .htaccess dans webroot ressemblerait ceci :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
</IfModule>
Les dtails de ces changements dpendront de votre configuration, et pourront inclure des choses
supplmentaires qui ne sont pas lies CakePHP. Merci de vous renseigner sur la documentation en
ligne dApache pour plus dinformations.
4. (Optionel) Pour amliorer la configuration de production, vous devriez empcher les assets invalides
dtre parss par CakePHP. Modifiez votre webroot .htaccess pour quelque chose comme :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/(app/webroot/)?(img|css|js)/(.*)$
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
Ce qui est au-dessus va simplement empcher les assets incorrects dtre envoys index.php et la
place dafficher la page 404 de votre serveur web.
De plus, vous pouvez crer une page HTML 404 correspondante, ou utiliser la page 404 de CakePHP
intgre en ajoutant une directive ErrorDocument :
ErrorDocument 404 /404-not-found
nginx ne fait pas usage de fichiers .htaccess comme Apache et Lighttpd, il est donc ncessaire de crer les
URLs rcrites disponibles dans la configuration du site. selon votre configuration, vous devrez modifier
cela, mais tout le moins, vous aurez besoin de PHP fonctionnant comme une instance FastCGI.
server {
listen
80;
server_name www.example.com;
rewrite ^(.*) http://example.com$1 permanent;
}
server {
listen
80;
server_name example.com;
# root directive should be global
root
/var/www/example.com/public/app/webroot/;
index
index.php;
access_log /var/www/example.com/log/access.log;
error_log /var/www/example.com/log/error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
try_files $uri =404;
fastcgi_pass
127.0.0.1:9000;
fastcgi_index
index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Si pour une raison exotique vous ne pouvez pas changer votre rpertoire racine et devez lancer votre projet
partir dun sous-dossier comme example.com/subfolder/, vous devrez injecter /webroot dans chaque
requte.
location ~ ^/(subfolder)/(.*)? {
index index.php;
set $new_uri /$1/webroot/$2;
try_files $new_uri $new_uri/ /$1/index.php?$args;
... php handling ...
}
Note : Les rcentes configurations de PHP-FPM sont dfinies pour couter sur le socket php-fpm au lieu
du port TCP 9000 sur ladresse 127.0.0.1. Si vous obtenez une erreur 502 de mauvaise passerelle avec la
configuration du dessus, essayez de remplacer le port TCP du fastcgi_pass par le chemin du socket (ex :
fastcgi_pass unix :/var/run/php5-fpm.sock ;).
IIS7 ne supporte pas nativement les fichiers .htaccess. Bien quil existe des add-ons qui peuvent ajouter
ce support, vous pouvez aussi importer les rgles des .htaccess dans IIS pour utiliser les rewrites natifs de
CakePHP. Pour ce faire, suivez ces tapes :
1. Utilisez linstalleur de la plateforme Web de Microsoft 3 pour installer lURL Rewrite Module 2.0 4
ou tlchargez le directement (32-bit 5 / 64-bit 6 ).
2. Crez un nouveau fichier dans votre dossier CakePHP, appel web.config.
3.
4.
5.
6.
http ://www.microsoft.com/web/downloads/platform.aspx
http ://www.iis.net/downloads/microsoft/url-rewrite
http ://www.microsoft.com/en-us/download/details.aspx ?id=5747
http ://www.microsoft.com/en-us/download/details.aspx ?id=7435
3. Utilisez Notepad ou tout autre diteur XML-safe, copiez le code suivant dans votre nouveau fichier
web.config...
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite requests to test.php"
stopProcessing="true">
<match url="^test.php(.*)$" ignoreCase="false" />
<action type="Rewrite" url="app/webroot/test.php{R:1}" />
</rule>
<rule name="Exclude direct access to app/webroot/*"
stopProcessing="true">
<match url="^app/webroot/(.*)$" ignoreCase="false" />
<action type="None" />
</rule>
<rule name="Rewrite routed access to assets(img, css, files, js, favicon)"
stopProcessing="true">
<match url="^(img|css|files|js|favicon.ico)(.*)$" />
<action type="Rewrite" url="app/webroot/{R:1}{R:2}"
appendQueryString="false" />
</rule>
<rule name="Rewrite requested file/folder to index.php"
stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<action type="Rewrite" url="index.php"
appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Une fois que le fichier web.config est cr avec les bonnes rgles de rcriture des liens de IIS, les liens
CakePHP, les CSS, le JavaScript, et le reroutage devraient fonctionner correctement.
URL-Rewriting sur lighttpd
Lighttpd ne supporte pas les fonctions .htaccess, par consquent vous pouvez retirer tous les fichiers .htaccess. Dans la configuration lighttpd, assurez-vous dactiver mod_rewrite. Ajoutez une ligne :
url.rewrite-if-not-file =(
"^([^\?]*)(\?(.+))?$" => "/index.php?url=$1&$3"
)
La rgle ncessaire UrlToolkit (pour le rewriting URL) pour utiliser CakePHP avec Hiawatha est :
UrlToolkit {
ToolkitID = cakephp
RequestURI exists Return
Match .* Rewrite /index.php
}
Si vous ne voulez ou ne pouvez pas utiliser lURL rewriting sur votre serveur web, rfrez-vous la section
core configuration.
Maintenant continuez sur Blog Tutoriel - Ajouter la logique pour commencer construire votre premire
application CakePHP.
La convention de nommage est vraiment trs importante dans CakePHP. En nommant notre model Post,
CakePHP peut automatiquement dduire que ce model sera utilis dans le controller PostsController, et sera
li la table posts de la base de donnes.
Note : CakePHP crera dynamiquement un objet model pour vous, sil ne trouve pas le fichier correspondant
dans /app/Model. Cela veut aussi dire que si vous navez pas nomm correctement votre fichier (par ex.
post.php ou posts.php au lieu de Post.php), CakePHP ne reconnatra pas votre configuration et utilisera ses
objets model par dfaut.
Pour plus dinformations sur les models, comme les prfixes des tables, les callbacks, et la validation, consultez le chapitre Models (Modles) du manuel.
10
models et o les tches lies aux posts sexcutent. Nous placerons ce nouveau controller dans un fichier appel PostsController.php lintrieur du dossier /app/Controller. Voici quoi devrait ressembler le controller de base
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
}
Maintenant, ajoutons une action notre controller. Les actions reprsentent souvent une simple fonction ou une interface dans une application. Par exemple, quand les utilisateurs requtent
www.exemple.com/posts/index (qui est la mme chose que www.exemple.com/posts/), ils pourraient sattendre voir une liste de posts. Le code pour cette action devrait ressembler quelque chose comme a
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
public function index() {
$this->set('posts', $this->Post->find('all'));
}
}
En dfinissant la fonction index() dans notre PostsController, les utilisateurs peuvent accder cette
logique en demandant www.exemple.com/posts/index. De la mme faon, si nous devions dfinir une fonction appele foobar(), les utilisateurs pourrait y accder en demandant www.exemple.com/posts/foobar.
Avertissement : Vous pourriez tre tent de nommer vos controllers et vos actions dune certaine
manire pour obtenir une certaine URL. Rsistez cette tentation. Suivez les conventions CakePHP
(le nom des controllers au pluriel, etc.) et nommez vos actions de faon lisible et comprhensible. Vous
pouvez lier les URLs votre code en utilisant ce quon appelle des routes, on le verra plus tard.
La seule instruction que cette action utilise est set(), pour transmettre les donnes du controller la vue
(que nous crerons la prochaine tape). La ligne dfinit la variable de vue appele posts qui est gale
la valeur de retour de la mthode find(all) du model Post. Notre model Post est automatiquement
disponible via $this->Post, parce que nous avons suivi les conventions de nommage de CakePHP.
Pour en apprendre plus sur les controllers de CakePHP, consultez le chapitre Controllers (Contrleurs).
11
Vous souvenez-vous, dans la dernire section, comment nous avions assign la variable posts la vue en
utilisant la mthode set() ? Cela devrait transmettre les donnes la vue qui ressemblerait quelque chose
comme cela
// print_r($posts) affiche:
Array
(
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => Le titre
[body] => Voici le contenu du post.
[created] => 2008-02-13 18:34:55
[modified] =>
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[title] => Encore un titre
[body] => Et le contenu du post qui suit.
[created] => 2008-02-13 18:34:56
[modified] =>
)
)
[2] => Array
(
[Post] => Array
(
[id] => 3
[title] => Le retour du titre
[body] => C'est trs excitant, non ?
[created] => 2008-02-13 18:34:57
[modified] =>
)
)
)
Les fichiers des vues de CakePHP sont stocks dans /app/View lintrieur dun dossier dont le nom
correspond celui du controller (nous aurons crer un dossier appel Posts dans ce cas). Pour mettre en
forme les donnes de ces posts dans un joli tableau, le code de notre vue devrait ressembler quelque chose
comme cela
<!-- File: /app/View/Posts/index.ctp -->
<h1>Blog posts</h1>
<table>
<tr>
12
<th>Id</th>
<th>Titre</th>
<th>Cr le</th>
</tr>
<!-- Here is where we loop through our $posts array, printing out post info -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td>
<?php echo $this->Html->link($post['Post']['title'],
array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
</td>
<td><?php echo $post['Post']['created']; ?></td>
</tr>
<?php endforeach; ?>
<?php unset($post); ?>
</table>
Vous avez sans doute remarqu lutilisation dun objet appel $this->Html. Cest une instance de la
classe CakePHP HtmlHelper. CakePHP est livr avec un ensemble de helpers (des assistants) pour les
vues, qui ralisent en un clin dil des choses comme le linking (mettre les liens dans un texte), laffichage
des formulaires, du JavaScript et de lAJAX. Vous pouvez en apprendre plus sur la manire de les utiliser
dans le chapitre Helpers (Assistants), mais ce quil est important de noter ici, cest que la mthode link()
gnrera un lien HTML partir dun titre (le premier paramtre) et dune URL (le second paramtre).
Lorsque vous indiquez des URLs dans CakePHP, il est recommand dutiliser les tableaux. Ceci est expliqu
dans le chapitre des Routes. Utiliser les tableaux dans les URLs vous permet de tirer profit des capacits de
CakePHP r-inverser les routes. Vous pouvez aussi utiliser les URLs relatives depuis la base de lapplication comme suit /controller/action/param1/param2.
A ce stade, vous devriez tre en mesure de pointer votre navigateur sur la page
http ://www.exemple.com/posts/index. Vous devriez voir votre vue, correctement formate avec le
titre et le tableau listant les posts.
Si vous avez essay de cliquer sur lun des liens que nous avons crs dans cette vue (le lien sur le titre
dun post mne lURL : /posts/view/un_id_quelconque), vous avez srement t inform par CakePHP
que laction na pas encore t dfinie. Si vous navez pas t inform, soit quelque chose sest mal pass,
soit en fait vous aviez dj dfini laction, auquel cas vous tes vraiment sournois ! Sinon, nous allons la
crer sans plus tarder dans le Controller Posts
// File: /app/Controller/PostsController.php
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
public function index() {
$this->set('posts', $this->Post->find('all'));
}
public function view($id = null) {
if (!$id) {
13
Lappel de set() devrait vous tre familier. Notez que nous utilisons findById() plutt que
find(all) parce que nous voulons seulement rcuprer les informations dun seul post.
Notez que notre action view prend un paramtre : lID du post que nous aimerions voir. Ce paramtre est
transmis laction grce lURL demande. Si un utilisateur demande /posts/view/3, alors la valeur 3 est
transmise la variable $id.
Nous faisons aussi une petite vrification derreurs pour nous assurer quun utilisateur accde bien lenregsitrement. Si un utilisateur requte /posts/view, nous lancerons un NotFoundException et laisserons le Gestionnaire dErreur de CakePHP ErrorHandler prendre le dessus. Nous excutons aussi une
vrification similaire pour nous assurer que lutilisateur a accde un enregistrement qui existe.
Maintenant, crons la vue pour
/app/View/Posts/view.ctp.
notre
nouvelle
action
view
et
plaons-la
dans
Vrifiez que cela fonctionne en testant les liens de la page /posts/index ou en affichant manuellement un
post via /posts/view/1.
14
Note : $this->request->is() prend un unique argument, qui peut tre la METHOD request (get,
put, post, delete) ou toute identifier de request (ajax). Ce nest pas une faon de vrifier une data
poste spcifique. Par exemple, $this->request->is(book) ne retournera pas true si les data du
book ont t postes.
Note : Vous avez besoin dinclure le component Flash (FlashComponent) et le helper Flash (FlashHelper)
dans chaque controller que vous utiliserez. Si ncessaire, incluez-les dans le controller principal (AppController) pour quils soient accessibles tous les controllers.
Voici ce que fait laction add() : si la requte HTTP est de type POST, essayez de sauvegarder les donnes
en utilisant le model Post. Si pour une raison quelconque, la sauvegarde a choue, affichez simplement la
vue. Cela nous donne une chance de voir les erreurs de validation de lutilisateur et dautres avertissements.
Chaque requte de CakePHP contient un objet CakeRequest qui est accessible en utilisant
$this->request. Cet objet contient des informations utiles sur la requte qui vient dtre reue,
et permet de contrler les flux de votre application. Dans ce cas, nous utilisons la mthode
CakeRequest::is() pour vrifier que la requte est de type POST.
Lorsquun utilisateur utilise un formulaire pour poster des donnes dans votre application, ces informations
sont disponibles dans $this->request->data. Vous pouvez utiliser les fonctions pr() ou debug()
pour les afficher si vous voulez voir quoi cela ressemble.
Nous utilisons la mthode FlashComponent::success() du component Flash (FlashComponent)
pour dfinir un message dans une variable session et qui sera affich dans la page juste aprs la redirection.
Dans le layout, nous trouvons la fonction FlashHelper::render() qui permet dafficher et de nettoyer
la variable correspondante. La mthode Controller::redirect du controller permet de rediriger vers
15
une autre URL. Le paramtre array(action => index) sera traduit vers lURL /posts (dans
notre cas laction index du controller Posts). Vous pouvez vous rfrer la fonction Router::url()
dans lAPI 7 pour voir les diffrents formats dURL accepts dans les diffrentes fonctions de CakePHP.
Lappel de la mthode save() vrifiera les erreurs de validation et interrompra lenregistrement si une
erreur survient. Nous verrons la faon dont les erreurs sont traites dans les sections suivantes.
Nous appelons la mthode create() en premier afin de rinitialiser ltat du model pour sauvegarder
les nouvelles informations. Cela ne cre pas rellement un enregistrement dans la base de donnes mais
rinitialise Model : :$id et dfinit Model : :$data en se basant sur le champ par dfaut dans votre base de
donnes.
Nous utilisons le FormHelper pour gnrer la balise douverture dune formulaire HTML. Voici le code
HTML gnr par $this->Form->create()
.. code-block:: html
16
Vous vous demandez peut-tre : comment je fais pour indiquer CakePHP mes exigences de validation ?
Les rgles de validation sont dfinies dans le model. Retournons donc notre model Post et procdons
quelques ajustements
class Post extends AppModel {
public $validate = array(
'title' => array(
'rule' => 'notBlank'
),
'body' => array(
'rule' => 'notBlank'
)
);
}
Le tableau $validate indique CakePHP comment valider vos donnes lorsque la mthode save()
est appele. Ici, jai spcifi que les deux champs body et title ne doivent pas tre vides. Le moteur
de validation de CakePHP est puissant, il dispose dun certain nombre de rgles intgres (code de carte
bancaire, adresse emails, etc.) et dune souplesse pour ajouter vos propres rgles de validation. Pour plus
dinformations sur cette configuration, consultez le chapitre Validation des Donnes.
Maintenant que vos rgles de validation sont en place, utilisez lapplication pour essayer dajouter un post
avec un titre et un contenu vide afin de voir comment cela fonctionne. Puisque que nous avons utilis la
mthode FormHelper::input() du helper Form pour crer nos lments de formulaire, nos messages derreurs de validation seront affichs automatiquement.
17
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
if ($this->request->is(array('post', 'put'))) {
$this->Post->id = $id;
if ($this->Post->save($this->request->data)) {
$this->Flash->success(__('Your post has been updated.'));
return $this->redirect(array('action' => 'index'));
}
$this->Flash->error(__('Unable to update your post.'));
}
if (!$this->request->data) {
$this->request->data = $post;
}
}
Cette action sassure dabord que lutilisateur a essay daccder un enregistrement existant. Sil ny a pas
de paramtre $id pass, ou si le post nexiste pas, nous lanons une NotFoundException pour que le
gestionnaire dErreurs ErrorHandler de CakePHP sen occupe.
Ensuite laction vrifie si la requte est une requte POST ou PUT. Si elle lest, alors nous utilisons les
donnes POST pour mettre jour notre enregistrement Post, ou sortir et montrer les erreurs de validation
lutilisateur.
Sil ny a pas de donnes dfinies dans $this->request->data, nous le dfinissons simplement dans
le post rcupr prcdemment.
La vue ddition devrait ressembler quelque chose comme cela :
<!-- Fichier: /app/View/Posts/edit.ctp -->
<h1>Editer le post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->input('id', array('type' => 'hidden'));
echo $this->Form->end('Save Post');
?>
Cette vue affiche le formulaire ddition (avec les donnes pr-remplies) avec les messages derreur de
validation ncessaires.
Une chose noter ici : CakePHP supposera que vous ditez un model si le champ id est prsent dans le
tableau de donnes. Sil nest pas prsent (ce qui revient notre vue add), CakePHP supposera que vous
insrez un nouveau model lorsque save() sera appele.
Vous pouvez maintenant mettre jour votre vue index avec des liens pour diter des posts :
<!-- Fichier: /app/View/Posts/index.ctp
<h1>Blog posts</h1>
18
19
}
return $this->redirect(array('action' => 'index'));
}
Cette logique supprime le Post spcifi par $id, et utilise $this->Flash->success() pour afficher
lutilisateur un message de confirmation aprs lavoir redirig sur /posts. Si lutilisateur tente une suppression en utilisant une requte GET, une exception est leve. Les exceptions manques sont captures par
le gestionnaire dexceptions de CakePHP et un joli message derreur est affich. Il y a plusieurs Exceptions
intgres qui peuvent tre utilises pour indiquer les diffrentes erreurs HTTP que votre application pourrait
rencontrer.
Etant donn que nous excutons juste un peu de logique et de redirection, cette action na pas de vue. Vous
voudrez peut-tre mettre jour votre vue index avec des liens pour permettre aux utilisateurs de supprimer
des Posts, ainsi :
<!-- Fichier: /app/View/Posts/index.ctp -->
<h1>Blog posts</h1>
<p><?php echo $this->Html->link(
'Ajouter un Post',
array('action' => 'add')
); ?></p>
<table>
<tr>
<th>Id</th>
<th>Titre</th>
<th>Actions</th>
<th>Cr le</th>
</tr>
<!-- Ici, nous bouclons sur le tableau $post afin d'afficher les informations des posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td>
<?php echo $this->Html->link(
$post['Post']['title'],
array('action' => 'view', $post['Post']['id'])
); ?>
</td>
<td>
<?php echo $this->Form->postLink(
'Supprimer',
array('action' => 'delete', $post['Post']['id']),
array('confirm' => 'Etes-vous sr ?'));
?>
<?php echo $this->Html->link(
'Editer',
array('action' => 'edit', $post['Post']['id'])
); ?>
</td>
20
<td>
<?php echo $post['Post']['created']; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
Utiliser postLink() permet de crer un lien qui utilise du Javascript pour supprimer notre post en faisant
une requte POST. Autoriser la suppression par une requte GET est dangereux cause des robots dindexation qui peuvent tous les supprimer.
Note : Ce code utilise aussi le helper Form pour demander lutilisateur une confirmation avant de
supprimer le post.
Routes
Pour certains, le routage par dfaut de CakePHP fonctionne suffisamment bien. Les dveloppeurs qui sont
sensibles la facilit dutilisation et la compatibilit avec les moteurs de recherches apprcieront la manire
dont CakePHP lie des URLs des actions spcifiques. Nous allons donc faire une rapide modification des
routes dans ce tutoriel.
Pour plus dinformations sur les techniques de routages, consultez le chapitre Configuration des Routes.
Par dfaut, CakePHP effectue une redirection dune personne visitant la racine de votre site (par ex :
http ://www.exemple.com) vers le controller Pages (PagesController) et affiche le rendu de la vue appele
home. Au lieu de cela, nous voudrions la remplacer avec notre controller Posts (PostsController).
Le routage de CakePHP se trouve dans /app/Config/routes.php. Vous devrez commenter ou supprimer la ligne qui dfinit la route par dfaut. Elle ressemble cela
Router::connect(
'/',
array('controller' => 'pages', 'action' => 'display', 'home')
);
Cette ligne connecte lURL / la page daccueil par dfaut de CakePHP. Nous voulons que cette URL soit
connecte notre propre controller, remplacez donc la ligne par celle-ci
Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
Cela devrait connecter les utilisateurs demandant / laction index() de notre controller Posts
(PostsController).
Note : CakePHP peut aussi faire du reverse routing (ou routage invers). Par exemple, pour la route
dfinie plus haut, en ajoutant array(controller => posts, action => index)
la fonction retournant un tableau, lURL / sera utilise. Il est dailleurs bien avis de toujours utiliser un
tableau pour les URLs afin que vos routes dfinissent o vont les URLs, mais aussi pour sassurer quelles
aillent dans la mme direction.
21
Conclusion
Crer des applications de cette manire vous apportera, paix, honneur, amour et argent au-del mme de vos
fantasmes les plus fous. Simple nest ce pas ? Gardez lesprit que ce tutoriel tait trs basique. CakePHP
a beaucoup plus de fonctionnalits offrir et il est aussi souple dans dautres domaines que nous navons
pas souhait couvrir ici pour simplifier les choses. Utilisez le reste de ce manuel comme un guide pour
dvelopper des applications plus riches en fonctionnalits.
Maintenant que vous avez cr une application CakePHP basique, vous tes prt pour les choses srieuses.
Commencez votre propre projet et lisez le reste du Cookbook et lAPI 8 .
Si vous avez besoin daide, il y a plusieurs faons dobtenir de laide - merci de regarder la page O obtenir
de laide Bienvenue sur CakePHP !
Prochaines lectures suggres
Voici les diffrents chapitres que les gens veulent souvent lire aprs :
1. Layouts : Personnaliser les Layouts de votre application.
2. Elements : Inclure et r-utiliser les portions de vues.
3. Scaffolding : Construire une bauche dapplication sans avoir coder.
4. Gnration de code avec Bake Gnrer un code CRUD basique.
5. Authentification Simple et Autorisation de lApplication : Tutoriel sur lenregistrement et la connexion
dutilisateurs.
Lectures supplmentaires
Une requte CakePHP typique
Nous avons dcouvert les ingrdients de bases de CakePHP, regardons maintenant comment chaque objet travaille avec les autres pour rpondre une requte simple. Poursuivons sur notre exemple original
de requte, imaginons que notre ami Ricardo vient de cliquer sur le lien Achetez un Cake personnalis
maintenant ! sur la page daccueil dune application CakePHP.
Figure : 2. Typical CakePHP Request.
Noir = lment obligatoire, Gris = lment optionnel, Bleu = rappel (callback)
1. Ricardo clique sur le lien pointant vers http ://www.exemple.com/cakes/buy et son navigateur envoie
une requte au serveur Web.
2. Le routeur analyse lURL afin dextraire les paramtres de cette requte : le controller, laction et tout
argument qui affectera la logique mtier pendant cette requte.
3. En utilisant les routes, lURL dune requte est lie une action dun controller (une mthode dune
classe controller spcifique). Dans notre exemple, il sagit de la mthode buy() du Controller Cakes.
La fonction de rappel du controller, beforeFilter(), est appele avant que toute logique de laction du
controller ne soit excute.
8. http ://api.cakephp.org
22
23
4. Le controller peut utiliser des models pour accder aux donnes de lapplication. Dans cet exemple,
le controller utilise un model pour rcuprer les derniers achats de Ricardo depuis la base de donnes.
Toute mthode de rappel du model, tout behavior ou toute source de donnes peut sappliquer pendant
cette opration. Bien que lutilisation du model ne soit pas obligatoire, tous les controllers CakePHP
ncessitent au dpart, au moins un model.
5. Une fois que le model a rcupr les donnes, elles sont retournes au controller. Des fonctions de
rappel du model peuvent sexcuter.
6. Le controller peut faire usage de components pour affiner les donnes ou pour effectuer dautres
oprations (manipulation de session, authentification ou envoi de mails par exemple).
7. Une fois que le controller a utilis les models et components pour prparer suffisamment les donnes,
ces donnes sont passes la vue grce la mthode set(). Les mthodes de rappel (callbacks) du controller peuvent tre appliques avant lenvoi des donnes. La logique de la vue est excute, laquelle
peut inclure lutilisation delements et/ou de helpers. Par dfaut, la vue est rendue travers un layout
(mise en page).
8. Dautres fonctions de rappel (callbacks) du controller (comme afterFilter) peuvent tre excutes. La vue complte et finale est envoye au navigateur de Ricardo.
Conventions de CakePHP
Nous sommes de grands fans des conventions plutt que de la configuration. Bien que cela rclame un peu
de temps pour apprendre les conventions de CakePHP, terme vous gagnerez du temps : en suivant les
conventions, vous aurez des fonctionnalits automatiques et vous vous librerez du cauchemar de la maintenance par lanalyse des fichiers de configuration. Les conventions sont aussi l pour crer un environnement
de dveloppement uniforme, permettant dautres dveloppeurs de sinvestir dans le code plus facilement.
Les conventions de CakePHP ont t cres partir de nombreuses annes dexprience dans le dveloppement Web et de bonnes pratiques. Alors que nous vous conseillons dutiliser ces conventions lors de vos
dveloppements CakePHP, nous devons mentionner que la plupart de ces principes sont facilement contournables - ce qui est particulirement utile lorsque vous travaillez avec danciennes applications.
Les conventions des Controllers
Les noms des classes de controller sont au pluriel, CamelCased et se terminent par Controller.
PeopleController et LatestArticlesController sont des exemples respectant cette convention.
La premire mthode que vous crivez pour un controller devrait tre index(). Lorsquune requte pointe
vers un controller sans action, le comportement par dfaut de CakePHP est dexcuter la fonction index()
de ce controller. Ainsi, la requte http ://www.exemple.com/apples/ renvoie la fonction index() de
ApplesController, alors que http ://www.exemple.com/apples/view renvoie vers la fonction view()
de ApplesController.
Vous pouvez aussi changer la visibilit des mthodes des controllers dans CakePHP en prfixant les noms
de mthode des controllers avec des underscores. Si une mthode du controller a t prfixe avec un underscore, la mthode ne sera pas accessible directement partir du web mais est disponible pour une utilisation
interne. Par exemple :
24
Alors que la page http ://www.exemple.com/news/latest/ est accessible pour lutilisateur comme dhabitude,
quelquun qui essaie daller sur la page http ://www.example.com/news/_findNewArticles/ aura une erreur,
car la mthode est prcde dun underscore. Vous pouvez aussi utiliser les mots-cls de visibilit de PHP
pour indiquer si la mthode peut ou non tre accessible partir dune URL. Les mthodes non-publiques ne
sont pas accessibles.
Considrations URL pour les noms de Controller Comme vous venez de voir, un controller mot
unique renvoie facilement vers un chemin URL en minuscules. Par exemple, ApplesController
(qui serait dfini dans le nom de fichier ApplesController.php) est accessible ladresse http ://exemple.com/apples.
Les controllers multiples mots peuvent tre de forme inflect qui correspondent au nom du controller :
/redApples
/RedApples
/Red_apples
/red_apples
iront tous vers lindex du controller RedApples. Cependant, la convention est que vos URLs soient en minuscules et avec des underscores, cest pourquoi /red_apples/go_pick est la forme correcte pour accder
laction RedApplesController::go_pick.
Pour plus dinformations sur les URLs de CakePHP et la gestion des paramtres, allez voir Configuration
des Routes.
Conventions des Fichiers et des Noms de Classe
En gnral, les noms de fichiers correspondent aux noms des classes cest--dire en CamelCase. Donc si vous
avez une classe MaChouetteClasse, alors dans Cake, le fichier devra tre nomm MaChouetteClasse.php.
Voici des exemples de la manire dont on nomme les fichiers, pour chacun des diffrents types de classes
que vous utiliseriez habituellement dans une application CakePHP :
La classe controller BisousEtCalinsController devra se trouver dans un fichier nomm BisousEtCalinsController.php.
La classe Component (Composant) MonSuperComponent devra se trouver dans un fichier nomm MonSuperComponent.php.
La classe Model ValeurOption devra se trouver dans un fichier nomm ValeurOption.php.
La classe Behavior (Comportement) SpecialementFunkableBehavior devra se trouver dans un fichier
nomm SpecialementFunkableBehavior.php.
La classe View (Vue) SuperSimpleView devra se trouver dans un fichier nomm SuperSimpleView.ctp.
Blog Tutoriel - Ajouter la logique
25
Les noms de classe de model sont au singulier et en CamelCase. Person, BigPerson et ReallyBigPerson en
sont des exemples.
Les noms de tables correspondant aux models CakePHP sont au pluriel et utilisent le caractre soulign
(underscore). Les tables correspondantes aux models mentionns ci-dessus seront donc respectivement :
people, big_people, et really_big_people.
Note des traducteurs francophones : seul le dernier mot est au pluriel et tous les pluriels franais ne seront
pas compris par CakePHP sans lui indiquer prcisment (par exemple cheval/chevaux). Voir pour cela le
chapitre sur les inflexions.
Pour vous assurer de la syntaxe des mots pluriels et singuliers, vous pouvez utiliser la bibliothque utilitaire
Inflector. Voir la documentation sur Inflector pour plus dinformations.
Les noms des champs avec deux mots ou plus doivent tre avec des underscores comme ici : first_name.
Les cls trangres des relations hasMany, belongsTo ou hasOne sont reconnues par dfaut grce au nom
(singulier) du model associ, suivi de _id. Donc, si un Cuisinier hasMany Cake, la table cakes se rfrera
un cuisinier de la table cuisiniers via une cl trangre cuisinier_id. Pour une table avec un nom de plusieurs
mots comme type_categories, la cl trangre sera type_categorie_id.
Les tables de jointure utilises dans les relations hasAndBelongsToMany (HABTM) entre models doivent
tre nommes daprs le nom des tables des models quelles unissent, par ex des users qui sont lis par une
relation HABTM avec des groups seraient joints par une table groups_users et ces noms doivent tre dans
lordre alphabtique (pommes_zebres plutt que zebres_pommes).
Toutes les tables avec lesquelles les models de CakePHP interagissent ( lexception des tables de jointure),
ncessitent une cl primaire simple pour identifier chaque ligne de manire unique. Si vous souhaitez modliser une table qui na pas de cl primaire sur un seul champ, la convention de CakePHP veut quune cl
primaire sur un seul champ soit ajoute la table.
Si le nom de la cl primaire nest pas id, vous devez dfinir lattribut Model.primaryKey.
CakePHP naccepte pas les cls primaires composes. Dans lventualit o vous voulez manipuler directement les donnes de votre table de jointure, cela veut dire que vous devez soit utiliser les appels directs
query, soit ajouter une cl primaire pour tre en mesure dagir sur elle comme un model normal. Exemple :
CREATE TABLE posts_tags (
id INT(10) NOT NULL AUTO_INCREMENT,
post_id INT(10) NOT NULL,
tag_id INT(10) NOT NULL,
PRIMARY KEY(id
);
26
Plutt que dutiliser une cl auto-incrmente comme cl primaire, vous pouvez aussi utiliser un champ
char(36). CakePHP utilisera alors un UUID de 36 caractres (String : :uuid) lorsque vous sauvegardez un
nouvel enregistrement en utilisant la mthode Model : :save.
Conventions des vues
Les fichiers de vue sont nomms daprs les fonctions du controller quelles affichent, sous une forme avec
underscores. La fonction soyezPret() de la classe PersonnesController cherchera un gabarit de vue dans :
/app/View/Personnes/soyez_pret.ctp.
Le schma classique est /app/View/Controller/nom_de_fonction_avec_underscore.ctp.
En utilisant les conventions CakePHP dans le nommage des diffrentes parties de votre application, vous
gagnerez des fonctionnalits sans les tracas et les affres de la configuration. Voici un exemple rcapitulant
les conventions abordes :
Nom de la table dans la base de donnes : personnes
Classe du Model : Personne, se trouvant dans /app/Model/Personne.php
Classe du Controller : PersonnesController, se trouvant dans /app/Controller/PersonnesController.php
Template de Vue : se trouve dans /app/View/Personnes/index.ctp
En utilisant ces conventions, CakePHP sait quune requte de type http ://exemple.com/personnes/ sera
lie un appel la fonction index() du Controller PersonnesController, dans lequel le model Personne est
automatiquement disponible (et automatiquement li la table personnes dans la base) et rendue dans un
fichier. Aucune de ces relations na t configure par rien dautre que la cration des classes et des fichiers
dont vous aviez besoin de toute faon.
Maintenant que vous avez t initi aux fondamentaux de CakePHP, vous devriez essayer de drouler le
tutoriel du Blog CakePHP Tutoriel dun Blog pour voir comment les choses sarticulent.
Structure du dossier de CakePHP
Aprs avoir tlcharg et extrait CakePHP, voici les fichiers et rpertoires que vous devriez voir :
app
lib
vendors
plugins
.htaccess
index.php
README
Vous remarquerez trois dossiers principaux :
Le dossier app sera celui o vous exercerez votre magie : cest l que vous placerez les fichiers de votre
application.
Le dossier lib est lendroit o nous avons exerc notre propre magie. Engagez-vous personnellement ne
pas modifier les fichiers dans ce dossier. Nous ne pourrons pas vous aider si vous avez modifi le cur
du framework. A la place, regardez dans les Extensions de lApplication modifies.
Enfin, le dossier vendors est lendroit o vous placerez vos librairies PHP tierces dont vous avez besoin
pour vos applications CakePHP.
27
Le dossier App
Le rpertoire app de CakePHP est lendroit o vous raliserez la majorit du dveloppement de votre application. Regardons de plus prs les dossier lintrieur de app.
Config Contient les (quelques) fichiers de configuration utiliss par CakePHP. Informations de connexion
la base de donnes, dmarrage, fichiers de configuration de base et tous fichiers du mme genre
doivent tre rangs ici.
Console Contient les commandes de la console et les Tasks de la console pour votre application. Ce rpertoire peut aussi contenir un rpertoire Templates pour personnaliser la sortie de bake. Pour plus
dinformations, regardez Shells, Tasks & Outils de Console.
Controller Contient vos Controllers et leurs Components.
Lib Contient les librairies qui ne proviennent pas de librairies externes. Cela vous permet de sparer les
librairies internes de votre organisme des librairies externes.
Locale Stocke les fichiers pour linternationalisation.
Model Pour les Models, Behaviors et Sources de Donnes de votre application.
Plugin Contient les packages des Plugins.
Test Ce rpertoire contient tous les cas de test, et les fixtures de test pour votre application. Le rpertoire
Test/Case devra reflter votre application et contenir un ou plusieurs cas de test par classe dans
votre application. Pour plus dinformations sur les cas de test et les fixtures de test, rfrez-vous la
documentation Testing.
tmp Cest ici que CakePHP enregistre les donnes temporaires. La manire dont sont stockes les donnes
actuelles dpend de la configuration que vous avez effectue, mais ce rpertoire est habituellement
utilis pour dposer les descriptions de models, les logs et parfois les informations de session.
Assurez-vous que ce dossier existe et quil est en criture, autrement la performance de votre application sera svrement impacte. En mode debug, CakePHP vous avertira si ce nest pas le cas.
Vendor Toute classe ou librairie tierce doit tre mise ici, de sorte quil sera facile dy accder par la fonction App : :import(vendor,name). Les observateurs aviss noteront que cela semble redondant avec
le rpertoire vendors la racine de larborescence. Nous aborderons les diffrences entre les deux
lorsque nous discuterons de la gestion multi-applications et des configurations systmes plus complexes.
View Les fichiers de prsentation sont placs ici : lments, pages derreur, helpers, layouts et vues.
webroot Dans un environnement de production, ce dossier doit tre la racine de votre application. Les
sous-rpertoires sont utiliss pour les feuilles de style CSS, les images et les fichiers Javascript.
Structure de CakePHP
CakePHP dispose de classes de Controllers (Contrleurs), de Models (Modles), et de Views (Vues), mais il
dispose de classes et objets supplmentaires qui rendent le dveloppement en MVC plus rapide et amusant.
Les Components (Composants), Behaviors (Comportements) et Helpers (Assistants) sont des classes qui
offrent une extensibilit et une rutilisation, permettant dajouter rapidement des fonctionnalits aux classes
MVC de base de vos applications. A ce stade de lecture, nous survolerons ces concepts, mais vous pourrez
dcouvrir comment utiliser ces outils en dtails plus tard.
28
Extensions de lApplication
Controllers, Helpers et Models ont chacun une classe parente, que vous pouvez utiliser pour dfinir des modifications impactant toute lapplication. AppController
(disponible
dans
/app/Controller/AppController.php),
AppHelper
(disponible dans /app/View/Helper/AppHelper.php) et AppModel (disponible dans
/app/Model/AppModel.php) sont de bons choix pour crire les mthodes que vous souhaitez
partager entre tous vos controllers, helpers ou models.
Bien quelles ne soient pas une classe ou un fichier, les Routes jouent un rle important dans les requtes
faites CakePHP. La dfinition des routes indique CakePHP comment lier les URLs aux actions des controllers. Le comportement par dfaut suppose que lURL /controller/action/var1/var2 renvoie
vers Controller::action($var1, $var2) et son action action qui prend deux paramtres
($var1, $var2). Mais vous pouvez utiliser les routes pour personnaliser les URLs et la manire dont elles
sont interprtes par votre application.
Il peut tre judicieux de regrouper certaines fonctionnalits. Un Greffon ou Plugin est un ensemble de
models, de controllers et de vues qui accomplissent une tche spcifique pouvant stendre plusieurs
applications. Un systme de gestion des utilisateurs ou un blog simplifi pourraient tre de bons exemples
de plugins CakePHP.
Extensions du Controller (Components)
Un Component (Composant) est une classe qui sintgre dans la logique du controller. Si vos controllers
ou vos applications doivent partager une logique, alors crer un Component est une bonne solution. A titre
dexemple, la classe intgre EmailComponent rend triviale la cration et lenvoi de courriels. Plutt que
dcrire une mthode dans un seul controller qui effectue ce traitement, vous pouvez empaqueter ce code et
ainsi le partager.
Les controllers sont galement quips de fonctions de rappel (callbacks). Ces fonctions sont votre disposition au cas o vous avez besoin dajouter du code entre les diffrentes oprations internes de CakePHP.
Les callbacks disponibles sont :
afterFilter(), excute aprs la logique du controller, y compris laffichage de la vue.
beforeFilter(), excute avant toute action dun controller.
beforeRender(), excute aprs toute action dun controller mais avant que la vue soit rendue.
Extensions du Model (Behaviors)
De mme, les Behaviors fonctionnent comme des passerelles pour ajouter une fonctionnalit commune
aux models. Par exemple, si vous stockez les donnes dun utilisateur dans une structure en arbre, vous
pouvez spcifier que votre model Utilisateur se comporte comme un arbre, et il acqurera automatiquement
la capacit de suppression, dajout, et de dplacement des noeuds dans votre structure en arbre sous-jacente.
Les models sont aussi soutenus par une autre classe nomme une DataSource (source de donnes). Il sagit
dune couche dabstraction qui permet aux models de manipuler diffrents types de donnes de manire
cohrente. La plupart du temps la source principale de donnes dans CakePHP est une base de donnes,
vous pouvez cependant crire des Sources de Donnes supplmentaires pour reprsenter des flux RSS, des
fichiers CSV, des entres LDAP ou des vnements iCal. Les Sources de Donnes vous permettent dassocier
Blog Tutoriel - Ajouter la logique
29
des enregistrements issus de sources diffrentes : plutt que dtre limit des jointures SQL, les Sources
de Donnes vous permettent de dire votre model LDAP quil est associ plusieurs vnements iCal.
Tout comme les controllers, les models ont des callbacks :
beforeFind()
afterFind()
beforeValidate()
afterValidate()
beforeSave()
afterSave()
beforeDelete()
afterDelete()
Les noms de ces mthodes devraient tre suffisamment explicites pour que vous compreniez leurs rles.
Vous obtiendrez plus de dtails dans le chaptre sur les models.
Extension de la Vue (Helpers)
Un Helper (Assistant) est une classe dassistance pour les vues. De mme que les components sont utiliss
par plusieurs controllers, les helpers permettent diffrentes vues daccder et de partager une mme logique
de prsentation. Lun des helpers intgrs Cake, AjaxHelper, facilite les requtes AJAX dans les vues.
La plupart des applications ont des portions de code pour les vues qui sont rptitives. CakePHP facilite la
rutilisabilit de ce code grce aux Layouts (mises en pages) et aux Elements. Par dfaut, toutes les vues
affiches par un controller ont le mme layout. Les elements sont utiliss lorsque de petites portions de
contenu doivent apparatre dans plusieurs vues.
30
CHAPITRE 2
Installation
CakePHP est rapide et facile installer. Les conditions minimum requises sont un serveur web et une copie
de CakePHP, cest tout ! Bien que ce manuel se focalise principalement sur la configuration avec Apache
(parce que cest le plus utilis couramment), vous pouvez configurer CakePHP pour lancer une diversit de
serveurs web tels que lighttpd ou Microsoft IIS.
Conditions requises
HTTP Server. Par exemple : Apache. mod_rewrite est prfrable, mais en aucun cas ncessaire.
PHP 5.3.0 ou plus (CakePHP version 2.6 et les versions infrieures supportent PHP 5.2.8 ou plus)..
Techniquement, un moteur de base de donnes nest pas ncessaire, mais nous imaginons que la plupart des
applications vont en utiliser un. CakePHP supporte une diversit de moteurs de stockage de donnes :
MySQL (4 ou plus)
PostgreSQL
Microsoft SQL Server
SQLite
Note : Tous les drivers intgrs requirent PDO. Vous devez vous assurer que vous avez les bonnes extensions PDO installes.
Licence
CakePHP est licenci sous la licence MIT. Cela signifie que vous tes libre de modifier, distribuer et reproduire le code source sous la condition que les informations de copyright restent intactes. Vous tes aussi
libres dincorporer CakePHP dans toute code source dapplication commerciale ou ferme.
31
Tlcharger CakePHP
Il y a deux faons dobtenir une copie rcente de CakePHP. Vous pouvez soit tlcharger une copie archive
de (zip/tar.gz/tar.bz2) partir du site web principal, soit faire un check out du code sur dpt de git.
Pour tlcharger la dernire version majeure de CakePHP, visitez le site web principal http ://cakephp.org et
suivez le lien Tlcharger maintenant.
Toutes les versions actuelles de CakePHP sont hberges sur Github 1 . Github hberge CakePHP lui-mme
ainsi que plusieurs autres plugins pour CakePHP. Les versions de CakePHP sont disponibles sur Tlchargements Github 2 .
Sinon, vous pouvez obtenir du code frais avec tous les correctifs de bug et jour des amliorations de
dernire minute. Celui-ci peut tre accessible partir de github en clonant le rpertoire de Github 3
git clone -b 2.x git://github.com/cakephp/cakephp.git
Permissions
CakePHP utilise le rpertoire app/tmp pour un certain nombre doprations. Les descriptions de Model,
les vues mises en cache, et les informations de session en sont juste quelques exemples.
De mme, assurez-vous que le rpertoire app/tmp et tous ses sous-rpertoires dans votre installation cake
sont en criture pour lutilisateur du serveur web.
Un problme habituel est que les rpertoires app/tmp et les sous-rpertoires doivent tre accessible en criture la fois pour le serveur web et et pour lutilisateur des lignes de commande. Sur un systme UNIX,
si votre serveur web est diffrent partir de lutilisateur en ligne de commande, vous pouvez lancer les
commandes suivantes juste une fois dans votre projet pour vous assurer que les permissions sont bien configures :
Configuration
Configurer CakePHP est aussi simple que de le flanquer dans le document root de votre serveur web, ou aussi
complexe et flexible que vous le souhaitez. Cette section couvrira les trois types principaux dinstallation de
CakePHP : dveloppement, production, et avanc.
Dveloppement : Facile mettre en oeuvre, mais les URLs de lapplication contiennent le nom du rpertoire dinstallation de CakePHP et cest moins scuris.
Production : Ncessite dtre habilit configurer le Document Root du serveur, URLs propres, trs
scuris.
1. http ://github.com/cakephp/cakephp
2. https ://github.com/cakephp/cakephp/tags
3. http ://github.com/cakephp/cakephp
32
Chapitre 2. Installation
Avanc : Avec un peu de configuration, vous permet de placer les rpertoires cls de CakePHP diffrents
endroits du systme de fichiers, avec la possibilit de partager un seul rpertoire de la librairie centrale
CakePHP entre plusieurs applications.
Dveloppement
Une installation dveloppement est la mthode la plus rapide pour lancer CakePHP. Cet exemple vous aidera installer une application CakePHP et la rendre disponible ladresse
http ://www.example.com/cake_2_0/. Nous considrons pour les besoins de cet exemple que votre document root pointe sur /var/www/html.
Dcompressez le contenu de larchive CakePHP dans /var/www/html. Vous avez maintenant un dossier
dans votre document root, nomm daprs la version que vous avez tlcharge (par exemple : cake_2.0.0).
Renommez ce dossier en cake_2_0. Votre installation dveloppement devrait ressembler quelque
chose comme cela dans votre systme de fichiers :
/var/www/html/
cake_2_0/
app/
lib/
plugins/
vendors/
.htaccess
index.php
README
Si votre serveur web est configur correctement, vous devriez trouver maintenant votre application CakePHP
accessible ladresse http ://www.exemple.com/cake_2_0/.
Cela copiera CakePHP dans votre rpertoire /home/mark/projects. Si vous ne voulez pas utiliser
git, vous pouvez tlcharger un zipball et les tapes restantes seront les mmes. Ensuite, vous devrez localiser et modifier votre php.ini. Sur les systmes *nix, il se trouve souvent dans /etc/php.ini, mais
en utilisant php -i et en regardant Loaded Configuration File (Fichier de Configuration Charg). Une
fois que vous avez trouv le bon fichier ini, modifier la configuration de include_path pour inclure
/home/mark/projects/cakephp/lib. Un exemple ressemblerait cela :
include_path = .:/home/mark/projects/cakephp/lib:/usr/local/php/lib/php
Dveloppement
33
Aprs avoir redmarr votre serveur web, vous devriez voir les changements dans phpinfo().
Note : Si vous tes sur Windows, les chemins dinclusion sont spars par des ; au lieu de :
Une fois que vous avez configur votre include_path, vos applications devraient tre capable de trouver
automatiquement CakePHP.
Production
Une installation production est une faon plus flexible de lancer CakePHP. Utiliser cette mthode permet
tout un domaine dagir comme une seule application CakePHP. Cet exemple vous aidera installer CakePHP
nimporte o dans votre systme de fichiers et le rendre disponible ladresse : http ://www.exemple.com.
Notez que cette installation demande davoir les droits pour modifier le DocumentRoot sur le serveur web
Apache.
Dcompressez les contenus de larchive CakePHP dans un rpertoire de votre choix. Pour les besoins de cet
exemple, nous considrons que vous avez choisi dinstaller CakePHP dans /cake_install. Votre installation
de production devrait ressembler quelque chose comme ceci dans votre systme de fichiers :
/cake_install/
app/
webroot/ (ce rpertoire est dfini comme rpertoire
``DocumentRoot``)
lib/
plugins/
vendors/
.htaccess
index.php
README
Les dveloppeurs utilisant Apache devraient rgler la directive DocumentRoot pour le domaine :
DocumentRoot /cake_install/app/webroot
Si votre serveur web est configur correctement, vous devriez maintenant accder votre application
CakePHP accessible ladresse : http ://www.exemple.com.
34
Chapitre 2. Installation
Note : Sur certains systmes, linstallation de librairies avec PEAR ncessitera la commande sudo.
Aprs avoir install CakePHP avec PEAR, si PEAR est configur correctement, vous devriez pouvoir
utiliser la commande cake pour crer une nouvelle application. Puisque CakePHP sera localis dans
linclude_path de PHP, vous naurez pas besoin de faire dautres changements.
Installer CakePHP avec Composer
Composer est un outil de gestion de dpendances pour PHP 5.3+. Il rgle plusieurs problmes que linstallateur PEAR a, et simplifie la gestion de plusieurs versions de librairies. Packagist 4 est le dpt principal
des packages installables avec Composer. Puisque CakePHP publie aussi les versions dans Packagist, vous
pouvez installer CakePHP en utilisant Composer 5 . Avant dinstaller CakePHP, vous devrez configurer un
fichier composer.json. Un fichier composer.json pour une application CakePHP ressemblerait ce qui
suit :
{
"name": "example-app",
"require": {
"cakephp/cakephp": "2.8.*"
},
"config": {
"vendor-dir": "Vendor/"
}
}
Sauvegardez ce JSON dans composer.json dans le rpetoire APP de votre projet. Ensuite, tlchargez
le fichier composer.phar dans votre projet. Aprs avoir tlcharg composer, installez CakePHP. Dans le
mme rpertoire que votre fichier composer.json, lancez ce qui suit :
$ php composer.phar install
Une fois que Composer a termin son excution, vous devriez avoir une structure de rpertoire qui ressemble
:
example-app/
composer.phar
composer.json
Vendor/
bin/
autoload.php
composer/
cakephp/
4. https ://packagist.org/
5. http ://getcomposer.org
35
Par dfaut bake va mettre en dur CAKE_CORE_INCLUDE_PATH. Pour rendre votre application plus
portable, vous devrez modifier webroot/index.php, en changeant CAKE_CORE_INCLUDE_PATH en
un chemin relatif :
define(
'CAKE_CORE_INCLUDE_PATH',
APP . '/Vendor/cakephp/cakephp/lib'
);
Note : Si vous pensez crer des tests unitaires pour votre application, vous devrez aussi faire les changements ci-dessus dans webroot/test.php.
Si vous installez dautres librairies avec Composer, vous devrez configurer lautoloader et rgler un problme
dans lautoloader de Composer. Dans votre fichier Config/bootstrap.php, ajoutez ce qui suit :
// Charger l'autoload de Composer.
require APP . 'Vendor/autoload.php';
// Retire et rajoute l'autoloader de CakePHP puisque Composer pense que
// c'est le plus important.
// See http://goo.gl/kKVJO7
spl_autoload_unregister(array('App', 'load'));
spl_autoload_register(array('App', 'load'), true, true);
Vous devriez maintenant avoir une application CakePHP fonctionnelle avec CakePHP install via Composer.
Assurez-vous de garder les fichiers composer.json et composer.lock.json avec le reste de votre code source.
Partager les librairies de CakePHP pour plusieurs applications
Il peut y avoir des situations o vous voulez placer les rpertoires de CakePHP diffrents endroits du
systme de fichiers. Cela est peut tre d des restrictions de lhte partag, ou peut-tre souhaitez-vous
juste que quelques-unes de vos apps puissent partager les mmes librairies de CakePHP. Cette section dcrit
comment dployer vos rpertoires de CakePHP travers le systme de fichiers.
Premirement, ralisez quil y a trois parties principales dune application Cake :
1. Les librairies du coeur de CakePHP, dans /lib/Cake.
2. Le code de votre application, dans /app.
3. Le webroot de lapplication, habituellement dans /app/webroot.
Chacun de ces rpertoires peut tre situ nimporte o dans votre systme de fichier, avec lexception de webroot, qui a besoin dtre acessible pour votre serveur web. Vous pouvez mme dplacer le dossier webroot
en-dehors du dossier app tant que vous dtes CakePHP o vous le mettez.
Pour configurer votre installation de CakePHP, vous aurez besoin de faire quelques changements aux fichiers
suivants.
/app/webroot/index.php
36
Chapitre 2. Installation
Il est recommand dutiliser la constante DS plutt que des slashes pour dlimiter des chemins de fichier.
Cela empche les erreurs de fichiers manquants que vous pourriez obtenir en rsultats en utilisant le mauvais
dlimiteur, et cela rend votre code plus portable.
Apache et mod_rewrite (et .htaccess)
Cette section a t dplace vers URL rewriting.
URL Rewriting
Apache et mod_rewrite (et .htaccess)
Alors que CakePHP est construit pour travailler avec mod_rewrite et habituellement il lest nous avons
remarqu que certains utilisateurs se battent pour obtenir un bon fonctionnement sur leurs systmes.
Ici il y a quelques trucs que vous pourriez essayer pour que cela fonctionne correctement. Premirement,
regardez votre fichier httpd.conf (Assurez-vous que vous avez dit le httpd.conf du systme plutt que celui
dun utilisateur- ou le httpd.conf dun site spcifique).
Ces fichiers peuvent varier selon les diffrentes distributions et les versions dApache. Vous pouvez allez
voir http ://wiki.apache.org/httpd/DistrosDefaultLayout pour plus dinformations.
37
1. Assurez-vous quun .htaccess est permis et que AllowOverride est dfini All pour le bon DocumentRoot. Vous devriez voir quelque chose comme :
# Chaque rpertoire auquel Apache a accs peut tre configur avec
# respect pour lesquels les services et les fonctionnalits sont
# autoriss et/ou dsactivs dans ce rpertoire (et ses sous-rpertoires).
#
# Premirement, nous configurons "par dfault" pour tre un ensemble
# trs restrictif de fonctionnalits.
#
<Directory />
Options FollowSymLinks
AllowOverride All
#
Order deny,allow
#
Deny from all
</Directory>
Pour les utilisateurs qui ont apache 2.4 et suprieur, vous devez modifier le fichier de configuration
pour votre httpd.conf ou la configuration de lhte virtuel pour ressembler ce qui suit :
<Directory /var/www/>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
2. Assurez-vous que vous avez charg correctement mod_rewrite. Vous devriez voir quelque chose
comme :
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
Dans la plupart des systmes, ceux-ci vont tre comments donc vous aurez juste besoin de retirer les
symboles # en dbut de ligne.
Aprs que vous avez fait des changements, re-dmarrez Apache pour tre sr que les paramtres soient
actifs.
Vrifiez que vos fichiers .htaccess sont effectivement dans le bon rpertoire.
Cela peut arriver pendant la copie parce que certains systmes dexploitation traitent les fichiers qui
commencent par . en cach et du coup ne les voient pas pour les copier.
3. Assurez-vous que votre copie de CakePHP vient de la section des tlchargements du site de notre
dpt Git, et a t dzipp correctement en vrifiant les fichiers .htaccess.
Le rpertoire root de CakePHP (a besoin dtre copi dans votre document, cela redirige tout vers
votre app CakePHP) :
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule
^$ app/webroot/
[L]
RewriteRule
(.*) app/webroot/$1 [L]
</IfModule>
Le rpertoire app de CakePHP (sera copi dans le rpertoire suprieur de votre application avec Bake) :
38
Chapitre 2. Installation
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule
^$
webroot/
RewriteRule
(.*) webroot/$1
</IfModule>
[L]
[L]
Le rpertoire webroot de CakePHP (sera copi dans le webroot de votre application avec Bake) :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
</IfModule>
Si votre site CakePHP a toujours des problmes avec mod_rewrite, essayez de modifier les
paramtres pour les Htes Virtuels. Si vous tes sur Ubuntu, modifiez le fichier /etc/apache2/sitesavailable/default (lendroit dpend de la distribution). Dans ce fichier, assurez-vous que
AllowOverride None a t chang en AllowOverride All, donc vous devez avoir :
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>
Si vous tes sur Mac OSX, une autre solution est dutiliser loutil virtualhostx 6 pour faire un Hte
Virtuel pour pointer vers votre dossier.
Pour beaucoup de services dhbergement (GoDaddy, 1and1), votre serveur web est en fait dj distribu partir dun rpertoire utilisateur qui utilise dj mod_rewrite. Si vous installez CakePHP dans
un rpertoire utilisateur (http ://exemple.com/~username/cakephp/), ou toute autre structure dURL
qui utilise dj mod_rewrite, vous aurez besoin dajouter les requtes (statements) RewriteBase aux
fichiers .htaccess que CakePHP utilise (/.htaccess, /app/.htaccess, /app/webroot/.htaccess).
Ceci peut tre ajout dans la mme section que la directive RewriteEngine, donc par exemple, votre
fichier .htaccess dans webroot ressemblerait ceci :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
</IfModule>
Les dtails de ces changements dpendront de votre configuration, et pourront inclure des choses
supplmentaires qui ne sont pas lies CakePHP. Merci de vous renseigner sur la documentation en
ligne dApache pour plus dinformations.
6. http ://clickontyler.com/virtualhostx/
39
4. (Optionel) Pour amliorer la configuration de production, vous devriez empcher les assets invalides
dtre parss par CakePHP. Modifiez votre webroot .htaccess pour quelque chose comme :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/(app/webroot/)?(img|css|js)/(.*)$
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
Ce qui est au-dessus va simplement empcher les assets incorrects dtre envoys index.php et la
place dafficher la page 404 de votre serveur web.
De plus, vous pouvez crer une page HTML 404 correspondante, ou utiliser la page 404 de CakePHP
intgre en ajoutant une directive ErrorDocument :
ErrorDocument 404 /404-not-found
40
Chapitre 2. Installation
}
}
Si pour une raison exotique vous ne pouvez pas changer votre rpertoire racine et devez lancer votre projet
partir dun sous-dossier comme example.com/subfolder/, vous devrez injecter /webroot dans chaque
requte.
location ~ ^/(subfolder)/(.*)? {
index index.php;
set $new_uri /$1/webroot/$2;
try_files $new_uri $new_uri/ /$1/index.php?$args;
... php handling ...
}
Note : Les rcentes configurations de PHP-FPM sont dfinies pour couter sur le socket php-fpm au lieu
du port TCP 9000 sur ladresse 127.0.0.1. Si vous obtenez une erreur 502 de mauvaise passerelle avec la
configuration du dessus, essayez de remplacer le port TCP du fastcgi_pass par le chemin du socket (ex :
fastcgi_pass unix :/var/run/php5-fpm.sock ;).
http ://www.microsoft.com/web/downloads/platform.aspx
http ://www.iis.net/downloads/microsoft/url-rewrite
http ://www.microsoft.com/en-us/download/details.aspx ?id=5747
http ://www.microsoft.com/en-us/download/details.aspx ?id=7435
41
Une fois que le fichier web.config est cr avec les bonnes rgles de rcriture des liens de IIS, les liens
CakePHP, les CSS, le JavaScript, et le reroutage devraient fonctionner correctement.
URL-Rewriting sur lighttpd
Lighttpd ne supporte pas les fonctions .htaccess, par consquent vous pouvez retirer tous les fichiers .htaccess. Dans la configuration lighttpd, assurez-vous dactiver mod_rewrite. Ajoutez une ligne :
url.rewrite-if-not-file =(
"^([^\?]*)(\?(.+))?$" => "/index.php?url=$1&$3"
)
42
Chapitre 2. Installation
A vous de jouer !
Ok, voyons voir CakePHP en action. Selon la configuration que vous utilisez, vous pouvez pointer votre
navigateur vers http ://exemple.com/ ou http ://exemple.com/cake_install/. A ce niveau, vous serez sur la
page home par dfaut de CakePHP, et un message qui vous donnera le statut de la connexion de votre base
de donnes courante.
Flicitations ! Vous tes prt crer votre premire application CakePHP.
Cela ne fonctionne pas ? Si vous avez une erreur lie au timezone de PHP, dcommentez la ligne dans
app/Config/core.php :
/**
* Dcommentez cette ligne et corrigez votre serveur de timezone pour rgler
* toute erreur lie la date & au temps.
*/
date_default_timezone_set('UTC');
A vous de jouer !
43
44
Chapitre 2. Installation
CHAPITRE 3
Bienvenue dans le CookBook, le manuel du framework dapplications web, CakePHP. Avec CakePHP,
dvelopper cest du gteau !
Lire ce manuel suppose que vous ayez une connaissance gnrale de PHP et une connaissance de base
de la programmation oriente-objet (POO). Certaines fonctionnalits livres avec le framework entranent
lutilisation de technologies diffrentes - comme SQL, JavaScript et XML - que ce manuel ne tente pas
dexpliquer, il indique seulement de quelle manire elles sont utilises dans ce contexte.
http ://www.cakephp.org/
http ://en.wikipedia.org/wiki/Application_framework
http ://www.php.net/
http ://en.wikipedia.org/wiki/MIT_License
http ://en.wikipedia.org/wiki/Open_source
http ://en.wikipedia.org/wiki/Rapid_application_development
http ://github.com/cakephp/cakephp/contributors
45
La couche Model
La couche Model reprsente la partie de lapplication qui excute la logique mtier. Cela signifie quelle
est responsable de rcuprer les donnes, de les convertir selon des concepts chargs de sens pour votre
application, tels que le traitement, la validation, lassociation et beaucoup dautres tches concernant la
manipulation des donnes.
A premire vue, lobjet Model peut tre vu comme la premire couche dinteraction avec nimporte quelle
base de donnes que vous pourriez utiliser pour votre application. Mais plus globalement, il fait partie des
concepts majeurs autour desquels vous allez excuter votre application.
Dans le cas dun rseau social, la couche Model soccupe des tches comme de sauvegarder des donnes, de
sauvegarder des associations damis, denregistrer et de rcuprer les photos des utilisateurs, de trouver des
suggestions de nouveaux amis, etc ... Tandis que les objets Models seront Ami, User, Commentaire,
Photo.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
46
http ://en.wikipedia.org/wiki/MIT_License
http ://en.wikipedia.org/wiki/Create,_read,_update_and_delete
http ://en.wikipedia.org/wiki/Scaffold_(programming)
http ://en.wikipedia.org/wiki/Model-view-controller
http ://en.wikipedia.org/wiki/Data_validation
http ://en.wikipedia.org/wiki/Web_template_system
http ://en.wikipedia.org/wiki/Access_control_list
http ://en.wikipedia.org/wiki/Web_cache
http ://httpd.apache.org/
http ://en.wikipedia.org/wiki/Model-view-controller
La couche Vue
La Vue retourne une prsentation des donnes venant du model. Etant spare par les Objets Model, elle est
responsable de lutilisation des informations dont elle dispose pour produire une interface de prsentation
de votre application.
Par exemple, de la mme manire que la couche Model retourne un ensemble de donnes, la Vue utilise
ces donnes pour fournir une page HTML les contenant. Ou un rsultat XML format pour que dautres
lutilisent.
La couche Vue nest pas seulement limite au HTML ou la rpresentation en texte de donnes. Elle peut
aussi tre utilise pour offrir une grande varit de formats en fonction de vos besoins, comme les vidos, la
musique, les documents et tout autre format auquel vous pouvez penser.
La couche Controller
La couche Controller gre les requtes des utilisateurs. Elle est responsable de retourner une rponse avec
laide mutuelle des couches Model et Vue.
Les Controllers peuvent tre imagins comme des managers qui ont pour mission que toutes les ressources
souhaites pour accomplir une tche soient dlgues aux travailleurs corrects. Il attend des requtes
des clients, vrifie leur validit selon lauthentification et les rgles dautorisation, dlguent les donnes
rcupres et traites par le Model, et slectionne les type de prsentation correctes que le client accepte,
pour finalement dlguer le processus daffichage la couche Vue.
47
Bnfices
Pourquoi utiliser CakePHP ? Parce que cest un logiciel vraiment construit selon le patron MVC, qui transforme une application en un dossier labor maintenable, modulable et rapide. Elaborer les tches de lapplication en sparant les models, vues et controllers, allgent votre application. De nouvelles fonctionnalits
sont ajoutes facilement, et les amliorations sur les vieilles fonctionnalits se font en un clin dil. La
conception modulable et spare permet aussi aux dveloppeurs et designeurs de travailler simultanment,
avec la possibilit de prototyper 18 rapidement : La sparation permet aussi aux dveloppeurs de faire des
changements dans une seule partie de lapplication sans affecter les autres.
Si vous navez jamais construit une application de cette manire, cela prend quelques temps pour shabituer,
mais nous sommes confiants quune fois votre premire application construite avec CakePHP, vous ne
voudrez plus faire dune autre faon.
Pour commencer votre premire application CakePHP, Essayez le tutoriel du Blog maintenant
O obtenir de laide
Le site officiel de CakePHP
http ://www.cakephp.org
Le site officiel de CakePHP est toujours un endroit patant visiter. Il propose des liens vers des outils frquemment utiliss par le dveloppeur, des didacticiels vido, des possibilits de faire un don et des
tlchargements.
Le Cookbook
http ://book.cakephp.org
Ce manuel devrait probablement tre le premier endroit o vous rendre pour obtenir des rponses. Comme
pour beaucoup dautres projets open source, nous accueillons de nouvelles personnes rgulirement. Fates
tout votre possible pour rpondre vos questions vous-mme dans un premier temps. Les rponses peuvent
venir lentement, mais elles resteront longtemps et vous aurez ainsi allg notre charge de travail en support
utilisateur. Le manuel et lAPI ont tous deux une version en ligne.
18. http ://en.wikipedia.org/wiki/Software_prototyping
48
La Boulangerie
http ://bakery.cakephp.org
La Boulangerie (Bakery) est une chambre de compensation pour tout ce qui concerne CakePHP. Vous y
trouverez des tutoriels, des tudes de cas et des exemples de code. Lorsque vous serez familiariss avec
CakePHP, connectez-vous pour partager vos connaissances avec la communaut et obtenez en un instant la
gloire et la fortune.
LAPI
http ://api.cakephp.org/
Allez droit au but et atteignez le graal des dveloppeurs, lAPI CakePHP (Application Programming Interface) est la documentation la plus complte sur tous les dtails essentiels au fonctionnement interne du
framework. Cest une rfrence directe au code, donc apportez votre chapeau hlice.
Le canal IRC
Canaux IRC sur irc.freenode.net :
#cakephp Discussion gnrale.
#cakephp-docs Documentation.
#cakephp-bakery Bakery.
#cakephp-fr Canal francophone.
Si vous tes paum, poussez un hurlement sur le canal IRC de CakePHP. Une personne de lquipe de
dveloppement 19 sy trouve habituellement, en particulier durant les heures du jour pour les utilisateurs
dAmrique du Nord et du Sud. Nous serions ravis de vous couter, que vous ayez besoin dun peu daide,
que vous vouliez trouver des utilisateurs dans votre rgion ou que vous souhaitiez donner votre nouvelle
marque de voiture sportive.
O obtenir de laide
49
partagent leurs ides. Cela peut tre une grande ressource pour trouver des rponses archives, des questions frquemment poses et obtenir des rponses aux problmes urgents. Rejoignez dautres utilisateurs de
CakePHP dans les communauts suivantes.
Stackoverflow
http ://stackoverflow.com/ 21
Tagge vos questions avec cakephp et la version spcifique que vous utilisez pour permettre aux utilisateurs
existant de stackoverflow de trouver vos questions.
50
CHAPITRE 4
Controllers (Contrleurs)
Les Controllers sont le C dans MVC. Aprs que le routage a t appliqu et que le bon controller a t
trouv, laction de votre controller est appele. Votre controller devra grer linterprtation des donnes
requtes, sassurer que les bons models sont appels et que la bonne rponse ou vue est rendue. Les controllers peuvent tre imagins comme un homme au milieu entre le Model et la Vue. Le mieux est de garder
des controllers peu chargs, et des models plus fournis. Cela vous aidera rutiliser plus facilement votre
code et facilitera le test de votre code.
Habituellement, les controllers sont utiliss pour grer la logique autour dun seul model. Par exemple, si
vous construisez un site pour grer une boulangerie en-ligne, vous aurez sans doute un RecettesController
qui gre vos recettes et un IngredientsController qui gre vos ingrdients. Cependant, il est aussi possible
davoir des controllers qui fonctionnent avec plus dun model. Dans CakePHP, un controller est nomm
daprs le model principal quil gre.
Les controllers de votre application sont des classes qui tendent la classe CakePHP AppController, qui
hrite elle-mme de la classe Controller du cur. La classe AppController peut tre dfinie dans
/app/Controller/AppController.php et elle devrait contenir les mthodes partages par tous les
controllers de votre application.
Les controllers peuvent inclure un certain nombre de mthodes qui grent les requtes. Celles-ci sont appeles des actions. Par dfaut, chaque mthode publique dans un controller est une action accessible via une
URL. Une action est responsable de linterprtation des requtes et de la cration de la rponse. Habituellement, les rponses sont sous forme de vue rendue, mais il y a aussi dautres faons de crer des rponses.
Le Controller App
Comme indiqu dans lintroduction, la classe AppController est la classe mre de tous les controllers
de votre application. AppController tend elle-mme la classe Controller incluse dans la librairie
du cur de CakePHP. AppController est dfinie dans /app/Controller/AppController.php
comme ceci :
class AppController extends Controller {
}
51
Les attributs et mthodes de controller crs dans AppController seront disponibles dans tous les controllers de votre application. Les Components (que vous dcouvrirez plus loin) sont mieux appropris pour
du code utilis dans la plupart (mais pas ncessairement tous) des controllers.
Bien que les rgles habituelles dhritage de la programmation oriente objet soient appliques, CakePHP
excute galement un travail supplmentaire si des attributs spcifiques des controllers sont fournis, comme
les components ou helpers utiliss par un controller. Dans ces situations, les valeurs des tableaux de
AppController sont fusionnes avec les tableaux de la classe controller enfant. Les valeurs dans la
classe enfant vont toujours surcharger celles dans AppController.
Note : CakePHP fusionne les variables suivantes de la classe AppController avec celles des controllers
de votre application :
$components
$helpers
$uses
Noubliez pas dajouter les helpers Html et Form si vous avez dfini la proprit $helpers dans votre
classe AppController.
Pensez aussi appeler les fonctions de rappel (callbacks) de AppController dans celles du controller enfant
pour de meilleurs rsultats :
public function beforeFilter() {
parent::beforeFilter();
}
52
# /app/Controller/RecettesController.php
class RecettesController extends AppController {
public function view($id) {
//la logique de l'action va ici..
}
public function share($client_id, $recette_id) {
//la logique de l'action va ici..
}
public function search($query) {
//la logique de l'action va ici..
}
}
Le controller ci-dessus est un exemple montrant comment la mthode peut tre utilise avec
requestAction() et des requtes normales. Retourner un tableau de donnes une requte nonrequestAction va entraner des erreurs et devra tre vit. Regardez la section sur requestAction()
pour plus dastuces sur lutilisation de requestAction().
Afin que vous utilisiez efficacement le controller dans votre propre application, nous couvrons certains des
attributs et mthodes du coeur fournis par les controllers de CakePHP.
Les Actions du Controller
53
54
Vous avez slectionn un glaage <?php echo $couleur; ?> pour le gteau.
La mthode set() peut galement prendre un tableau associatif comme premier paramtre. Cela
peut souvent tre une manire rapide daffecter en une seule fois un jeu complet dinformations la
vue :
$data = array(
'couleur' => 'rose',
'type' => 'sucre',
'prix_de_base' => 23.95
);
// donne $couleur, $type, et $prix_de_base
// disponible dans la vue:
$this->set($data);
Depuis 2.5 la variable $title_for_layout est dprcie, utilisez les blocks de vues la place.
Controller::render(string $view, string $layout)
La mthode render() est automatiquement appele la fin de chaque action excute par le controller. Cette mthode excute toute la logique lie la prsentation (en utilisant les variables transmises via la mthode set()), place le contenu de la vue lintrieur de son $layout et transmet
le tout lutilisateur final.
Le fichier de vue utilis par dfaut est dtermin par convention. Ainsi, si laction search() de notre
controller RecettesController est demande, le fichier de vue situ dans /app/view/recettes/search.ctp
sera utilis :
class RecettesController extends AppController {
// ...
public function search() {
// Rend la vue dans /View/Recettes/search.ctp
$this->render();
}
// ...
}
Bien que CakePHP appelle cette fonction automatiquement la fin de chaque action ( moins que
vous nayez dfini $this->autoRender false), vous pouvez lutiliser pour spcifier un fichier
de vue alternatif en prcisant le nom dune action dans le controller, via le paramtre $view.
Si $view commence avec un / on suppose que cest un fichier de vue ou un lment dont le chemin
est relatif au dossier /app/View. Cela permet un affichage direct des lments, ce qui est trs pratique lors dappels AJAX.
// Rend un lment dans /View/Elements/ajaxreturn.ctp
$this->render('/Elements/ajaxreturn');
Le paramtre $layout vous permet de spcifier le layout de la vue qui est rendue.
55
Cela
rendrait
app/View/Posts/fichier_personnalise.ctp
app/View/Posts/mon_action.ctp.
au
lieu
Vous pouvez aussi rendre les vues des plugins en utilisant la syntaxe suivante
$this->render(PluginName.PluginController/custom_file). Par exemple :
de
:
Contrle de Flux
Controller::redirect(mixed $url, integer $status, boolean $exit)
La mthode de contrle de flux que vous utiliserez le plus souvent est redirect(). Cette mthode
prend son premier paramtre sous la forme dune URL relative votre application CakePHP. Quand
un utilisateur a ralis un paiement avec succs, vous aimeriez le rediriger vers un cran affichant le
reu.
public function regler_achats() {
// Placez ici la logique pour finaliser l'achat...
if ($success) {
return $this->redirect(
array('controller' => 'paiements', 'action' => 'remerciements')
);
} else {
return $this->redirect(
array('controller' => 'paiements', 'action' => 'confirmations')
);
}
}
Vous pouvez aussi utiliser une URL relative ou absolue avec $url :
$this->redirect('/paiements/remerciements');
$this->redirect('http://www.exemple.com');
56
Le second paramtre de la fonction redirect() vous permet de dfinir un code de statut HTTP
accompagnant la redirection. Vous aurez peut-tre besoin dutiliser le code 301 (document dplac de
faon permanente) ou 303 (voir ailleurs), en fonction de la nature de la redirection.
Cette mthode ralise un exit() aprs la redirection, tant que vous ne mettez pas le troisime
paramtre false.
Si vous avez besoin de rediriger la page appelante, vous pouvez utiliser :
$this->redirect($this->referer());
Cette mthode supporte aussi les paramtres nomms de base. Si vous souhaitez tre redirig sur une
URL comme : http://www.example.com/commandes/confirmation/produit:pizza/quantite:
vous pouvez utiliser :
$this->redirect(array(
'controller' => 'commandes',
'action' => 'confirmation',
'produit' => 'pizza',
'quantite' => 5
));
57
Callbacks
En plus des Request Life-cycle callbacks, CakePHP supporte aussi les callbacks lis au scaffolding.
Controller::beforeScaffold($method)
$method nom de la mthode appele, par exemple index, edit, etc.
Controller::afterScaffoldSave($method)
$method nom de la mthode appele, soit edit soit update.
Controller::afterScaffoldSaveError($method)
$method nom de la mthode appele, soit edit soit update.
Controller::scaffoldError($method)
$method nom de la mthode appele, par exemple index, edit, etc...
Si $default nest pas dfini, la fonction se met par dfaut sur la racine (root) de votre domaine /.
Le paramtre $local, si il est dfini true, restreint les URLs se rfrant au serveur local.
58
Controller::disableCache()
Utilise pour indiquer au navigateur de lutilisateur de ne pas mettre en cache le rsultat de la requte
courante. Ceci est diffrent du systme de cache de vue couvert dans le chapitre suivant.
Les en-ttes HTTP envoys cet effet sont :
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Last-Modified: [current datetime] GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0
Pragma: no-cache
Si $this->data[Commande][destination] vaut Boulangerie du village, postConditions convertit cette condition en un tableau compatible avec la mthode Model->find(). Soit dans
notre cas, array("Commande.destination" => "Boulangerie du village").
Si vous voulez utiliser un oprateur SQL diffrent entre chaque terme, remplacez-le en utilisant le
second paramtre :
/*
Contenu de $this->request->data
array(
'Commande' => array(
'nb_items' => '4',
'referrer' => 'Ye Olde'
)
)
*/
// Rcuprons maintenant les commandes qui ont au moins 4 items et
contenant 'Ye Olde'
$conditions = $this->postConditions(
$this->request->data,
array(
'nb_items' => '>=',
'referrer' => 'LIKE'
)
);
$commandes = $this->Commande->find('all', compact('conditions'));
59
Le troisime paramtre vous permet de dire CakePHP quel oprateur boolen SQL utiliser entre les
conditions de recherche. Les chanes comme AND, OR et XOR sont des valeurs possibles.
Enfin, si le dernier paramtre est dfini vrai et que $op est un tableau, les champs non-inclus dans
$op ne seront pas inclus dans les conditions retournes.
Controller::paginate()
Cette mthode est utilise pour paginer les rsultats retourns par vos models. Vous pouvez dfinir
les tailles de la page, les conditions utiliser pour la recherche de ces donnes et bien plus encore.
Consultez la section pagination pour plus de dtails sur lutilisation de la pagination.
Controller::requestAction(string $url, array $options)
Cette fonction appelle laction dun controller depuis tout endroit du code et retourne les donnes associes cette action. L$url passe est une adresse relative votre application CakePHP (/nomducontroleur/nomaction/parametres). Pour passer des donnes supplmentaires au controller destinataire,
ajoutez le tableau $options.
Note :
Vous pouvez utiliser requestAction() pour rcuprer lintgralit de laffichage dune vue en passant la valeur return dans les options : requestAction($url,
array(return)). Il est important de noter que faire un requestAction en utilisant return
partir dune mthode dun controller peut entraner des problmes de fonctionnement dans les script
et tags CSS.
Avertissement : Si elle est utilise sans cache, la mthode requestAction() peut engendrer
des faibles performances. Il est rarement appropri de lutiliser dans un controller ou un model.
requestAction() est plutt utilise en conjonction avec des lments (mis en cache) - comme
moyen de rcuprer les donnes pour un lment avant de lafficher. Prenons lexemple de la mise en
place dun lment derniers commentaires dans le layout. Nous devons dabord crer une mthode
de controller qui retourne les donnes :
// Controller/CommentsController.php
class CommentsController extends AppController {
public function latest() {
if (empty($this->request->params['requested'])) {
throw new ForbiddenException();
}
return $this->Comment->find(
'all',
array('order' => 'Comment.created DESC', 'limit' => 10)
);
}
}
Vous devriez toujours inclure des vrifications pour vous assurer que vos mthodes de requestAction sont en fait originaires de requestAction(). Ne pas le faire va autoriser les mthodes requestAction() tre directement accessible dune URL, ce qui nest gnralement pas
souhait.
Si nous crons un lment simple pour appeler cette fonction :
// View/Elements/latest_comments.ctp
60
$comments = $this->requestAction('/comments/latest');
foreach ($comments as $comment) {
echo $comment['Comment']['title'];
}
On peut ensuite placer cet lment nimporte o pour obtenir la sortie en utilisant :
echo $this->element('latest_comments');
Ecrit de cette manire, ds que llment est affich, une requte sera faite au controller pour obtenir
les donnes, les donnes seront traites, et retournes. Cependant, compte tenu de lavertissement
ci-dessus il vaut mieux utiliser des lments mis en cache pour anticiper des traitements inutiles. En
modifiant lappel llment pour quil ressemble ceci :
echo $this->element('latest_comments', array(), array('cache' => true));
Lappel requestAction() ne sera pas effectu tant que le fichier de vue de llment en cache
existe et est valide.
De plus, requestAction() prend dsormais des URLs bases sur des tableau dans le style de
cake :
echo $this->requestAction(
array('controller' => 'articles', 'action' => 'featured'),
array('return')
);
Cela permet lappel de requestAction() dviter lutilisation de Router : :url ce qui peut
amliorer la performance. Les urls bases sur des tableaux sont les mmes que celles utilises par
HtmlHelper::link() avec une seule diffrence. Si vous utilisez des paramtres nomms ou
passs dans vos urls, vous devez les mettre dans un second tableau et les inclure dans la cl correcte. La raison de cela est que requestAction() fusionne seulement le tableau des arguments
nomms avec les membres du tableau de Controller::params et ne place pas les arguments
nomms dans la cl named. Des parties supplmentaires dans le tableau $option vont aussi tre
disponibles dans le tableau Controller : :params de laction requte
echo $this->requestAction('/articles/featured/limit:3');
echo $this->requestAction('/articles/view/5');
Note : Contrairement aux autres places o les URLs en tableau sont analogues aux URLs en chane
de caractre, requestAction les traite diffremment.
61
Quand vous utilisez une url en tableau en conjonction avec requestAction(), vous devez spcifier tous les paramtres dont vous aurez besoin dans laction requte. Ceci inclut les paramtres
comme $this->request->data. En plus de passer tous les paramtres requis, les paramtres
nomms et passs doivent tre faits dans le second tableau comme vu ci-dessus.
Controller::loadModel(string $modelClass, mixed $id)
La fonction loadModel() devient pratique quand vous avez besoin dutiliser un model qui nest
pas le model du controller par dfaut ou un de ses models associs :
$this->loadModel('Article');
$recentArticles = $this->Article->find(
'all',
array('limit' => 5, 'order' => 'Article.created DESC')
);
$this->loadModel('User', 2);
$user = $this->User->read();
62
donc accs son model Recette, disponible via $this->Recette, et notre controller Produits proposera un accs son model via $this->Produit. Cependant, quand vous autorisez un controller
accder dautres models via la variable $uses, le nom du model primaire du controller courant
doit galement tre inclu. Ceci est illustr dans lexemple ci-dessous.
Si vous ne souhaitez pas utiliser un Model dans votre controller, dfinissez public $uses =
array(). Cela vous permettra dutiliser un controller sans avoir besoin dun fichier Model correspondant. Cependant, les models dfinis dans AppController seront toujours chargs. Vous
pouvez aussi utiliser false pour ne charger absolument aucun model. Mme ceux dfinis dans
AppController.
Modifi dans la version 2.1 : $uses a maintenant une nouvelle valeur par dfaut, il gre aussi false
diffremment.
property Controller::$helpers
Les Helpers HtmlHelper, FormHelper et SessionHelper sont toujours accessibles par dfaut, tout comme le SessionComponent. Mais si vous choisissez de dfinir votre propre tableau
$helpers dans AppController, assurez-vous dy inclure HtmlHelper et FormHelper si vous
voulez quils soient toujours disponibles par dfaut dans vos propres controllers. Pour en savoir plus
au sujet de ces classes, regardez leurs sections respectives plus loin dans le manuel.
Jetons maintenant un il sur la faon dindiquer un Controller CakePHP que vous avez dans
lide dutiliser dautres classes MVC :
class RecipesController extends AppController {
public $uses = array('Recipe', 'User');
public $helpers = array('Js');
public $components = array('RequestHandler');
}
Toutes ces variables sont fusionnes avec leurs valeurs hrites, par consquent ce nest pas ncessaire
de re-dclarer (par exemple) le helper FormHelper ou tout autre dclar dans votre controller App.
property Controller::$components
Le tableau de components vous permet de dfinir quel Components (Composants) un controller va
utiliser. Comme les $helpers et $uses, les components dans vos controllers sont fusionns avec
ceux dans AppController. Comme pour les $helpers, vous pouvez passer les paramtres dans
les components. Regardez Configuration des Components pour plus dinformations.
Autres Attributs
Tandis que vous pouvez vrifier les dtails pour tous les attributs des controllers dans lAPI 3 , il y a dautres
attributs du controller qui mritent leurs propres sections dans le manuel.
3. http ://api.cakephp.org
63
CakeRequest
CakeRequest est lobjet requte utilis par dfaut dans CakePHP. Il centralise un certain nombre
de fonctionnalits pour interroger et interagir avec les donnes demandes. Pour chaque requte, un
CakeRequest est cre et passe en rfrence aux diffrentes couches de lapplication que la requte
de donnes utilise. Par dfaut CakeRequest est assigne $this->request, et est disponible dans
les Controllers, Vues et Helpers. Vous pouvez aussi y accder dans les Components en utilisant la rfrence
du controller. Certaines des tches incluses que CakeRequest permet :
Transformer les tableaux GET, POST, et FILES en structures de donnes avec lesquelles vous tes familiers.
Fournir une introspection de lenvironnement se rapportant la demande. Des choses comme les envois
den-ttes (headers), ladresse IP du client et les informations des sous-domaines/domaines sur lesquels
le serveur de lapplication tourne.
Fournit un accs aux paramtres de la requte la fois en tableaux indics et en proprits dun objet.
Accder aux paramtres de la requte
CakeRequest propose plusieurs interfaces pour accder aux paramtres de la requte. La premire est par
des tableaux indexs, la seconde est travers $this->request->params, et la troisime est par des
proprits dobjets :
$this->request['controller'];
$this->request->controller;
$this->request->params['controller']
Tout ce qui est au-dessus retournera la mme valeur. Plusieurs faons daccder aux paramtres ont t faites
pour faciliter la migration des applications existantes. Tous les lments de route Les Elments de Route sont
accessibles travers cette interface.
En plus des lments de routes Les Elments de Route, vous avez souvent besoin daccder aux arguments
passs Arguments Passs et aux paramtres nomms Paramtres Nomms. Ceux-ci sont aussi tous les deux
disponibles dans lobjet request :
// Arguments passs
$this->request['pass'];
$this->request->pass;
$this->request->params['pass'];
64
// Paramtres nomms
$this->request['named'];
$this->request->named;
$this->request->params['named'];
Tous ceux-ci vous fourniront un accs aux arguments passs et aux paramtres nomms. Il y a de nombreux
paramtres importants et utiles que CakePHP utilise en interne, ils sont aussi trouvables dans les paramtres
de la requte :
plugin Le plugin grant la requte, va tre nul quand il ny a pas de plugins.
controller Le controller gre la requte courante.
action Laction gre la requte courante.
prefix Le prfixe pour laction courante. Voir Prefix de Routage pour plus dinformations.
bare Prsent quand la requte vient de requestAction() et inclut loption bare. Les requtes vides
nont pas de layout de rendu.
requested Prsent et mis true quand laction vient de requestAction().
Accder aux paramtres Querystring
Les paramtres Querystring peuvent tre lus en utilisant CakeRequest::$query :
// l'URL est /posts/index?page=1&sort=title
$this->request->query['page'];
// Vous pouvez aussi y accder par un tableau
// accesseur BC, va tre dprci dans les versions futures
$this->request['url']['page'];
Vous pouvez soit directement accder la proprit $query, soit vous pouvez utiliser
CakeRequest::query() pour lire lURL requte sans erreur. Toute cl qui nexiste pas va
retourner null :
$foo = $this->request->query('value_that_does_not_exist');
// $foo === null
Vous pouvez soit accder directement la proprit $data, soit vous pouvez utiliser
CakeRequest::data() pour lire le tableau de donnes sans erreurs. Toute cl nexistant pas va
retourner null :
65
$foo = $this->request->data('Value.that.does.not.exist');
// $foo == null
Puisque certaines mthodes de desrialization ont besoin de paramtres supplmentaires quand elles sont
appeles, comme le paramtre de type tableau pour json_decode ou si vous voulez convertir les XML
en objet DOMDocument, CakeRequest::input() supporte aussi le passement dans des paramtres
supplmentaires :
// Obtenir les donnes encodes en Xml soumises avec une action PUT/POST
$data = $this->request->input('Xml::build', array('return' => 'domdocument'));
66
Les deux mthodes appeles vont retourner la mme valeur. Pour linstant, les mthodes sont toujours
disponibles dans RequestHandlerComponent, mais sont deprcies et seront retires dans 3.0.0.
Vous pouvez aussi facilement tendre les dtecteurs de la requte qui sont disponibles, en utilisant
CakeRequest::addDetector() pour crer de nouveaux types de dtecteurs. Il y a quatre diffrents
types de dtecteurs que vous pouvez crer :
Comparaison avec valeur denvironnement - Une comparaison de la valeur denvironnement, compare
une valeur attrape partir de env() pour une valeur connue, la valeur denvironnement est vrifie
quitablement avec la valeur fournie.
La comparaison de la valeur model - La comparaison de la valeur model vous autorise comparer une
valeur attrape partir de env() avec une expression rgulire.
Comparaison base sur les options - La comparaison base sur les options utilise une liste doptions pour
crer une expression rgulire. De tels appels pour ajouter un dtecteur doptions dj dfini, va fusionner
les options.
Les dtecteurs de Callback - Les dtecteurs de Callback vous permettront de fournir un type callback
pour grer une vrification. Le callback va recevoir lobjet requte comme seul paramtre.
Quelques exemples seraient :
// Ajouter un dtecteur d'environnement.
$this->request->addDetector(
'post',
array('env' => 'REQUEST_METHOD', 'value' => 'POST')
);
// Ajouter un dtecteur de valeur model.
$this->request->addDetector(
'iphone',
array('env' => 'HTTP_USER_AGENT', 'pattern' => '/iPhone/i')
);
// Ajouter un dtecteur d'options
$this->request->addDetector('internalIp', array(
'env' => 'CLIENT_IP',
'options' => array('192.168.0.101', '192.168.0.100')
));
// Ajouter un dtecteur de callback. Peut soit tre une fonction anonyme
// ou un callback rgulier.
$this->request->addDetector(
'awesome',
array('callback' => function ($request) {
return isset($request->awesome);
})
);
CakeRequest
inclut
aussi
des
mthodes
comme
CakeRequest::domain(),
CakeRequest::subdomains() et CakeRequest::host() qui facilitent la vie des applications avec sous-domaines.
Vous pouvez utiliser plusieurs dtecteurs intgrs :
is(get) Vrifie si la requte courante est un GET.
is(put) Vrifie si la requte courante est un PUT.
is(post) Vrifie si la requte courante est un POST.
En savoir plus sur les controllers
67
CakeRequest et RequestHandlerComponent
Puisque plusieurs des fonctionnalits offertes par CakeRequest taient lapanage de
RequestHandlerComponent, une reflexion tait ncessaire pour savoir si il tait toujours ncessaire.
Dans 2.0, RequestHandlerComponent agit comme un sugar daddy en fournissant une couche de
facilit au-dessus de loffre utilitaire de CakeRequest. RequestHandlerComponent permet par
exemple de changer les layouts et vues bass sur les types de contenu ou ajax. Cette sparation des utilitaires
entre les deux classes vous permet de plus facilement choisir ce dont vous avez besoin.
Interagir avec les autres aspects de la requte
Vous pouvez utiliser CakeRequest pour voir une quantit de choses sur la requte. Au-del des dtecteurs,
vous pouvez galement trouver dautres informations sur les diverses proprits et mthodes.
$this->request->webroot contient le rpertoire webroot.
$this->request->base contient le chemin de base.
$this->request->here contient ladresse complte de la requte courante.
$this->request->query contient les paramtres de la chane de requte.
API de CakeRequest
class CakeRequest
CakeRequest encapsule la gestion des paramtres de la requte, et son introspection.
CakeRequest::domain($tldLength = 1)
Retourne le nom de domaine sur lequel votre application tourne.
CakeRequest::subdomains($tldLength = 1)
Retourne un tableau avec le sous-domaine sur lequel votre application tourne.
CakeRequest::host()
Retourne lhte o votre application tourne.
CakeRequest::method()
Retourne la mthode HTTP o la requte a t faite.
CakeRequest::onlyAllow($methods)
Dfinit les mthodes HTTP autorises, si elles ne correspondent pas, elle va lancer une MethodNotAllowedException. La rponse 405 va inclure len-tte Allow ncessaire avec les mthodes passes.
Introduit dans la version 2.3.
Obsolte depuis la version 2.5 : Utilisez CakeRequest::allowMethod() la place.
68
CakeRequest::allowMethod($methods)
Dfinit les mthodes HTTP autorises, si cela ne correspond pas, une exception MethodNotAllowedException sera lance. La rponse 405 va inclure len-tte ncessaire Allow avec les mthodes
passes.
Introduit dans la version 2.5.
CakeRequest::referer($local = false)
Retourne ladresse de rfrence de la requte.
CakeRequest::clientIp($safe = true)
Retourne ladresse IP du visiteur courant.
CakeRequest::header($name)
Vous permet daccder tout en-tte HTTP_* utilis pour la requte :
$this->request->header('User-Agent');
CakeRequest::data($name)
Fournit une notation en point pour accder aux donnes requtes. Permet la lecture et la modification
des donnes requtes, les appels peuvent aussi tre chans ensemble :
// Modifier une donne requte, ainsi vous pouvez pr-enregistrer certains champs.
$this->request->data('Post.title', 'New post')
->data('Comment.1.author', 'Mark');
// Vous pouvez aussi lire des donnes.
$value = $this->request->data('Post.title');
CakeRequest::query($name)
Fournit un accs aux donnes requtes de lURL avec notation en point :
// l\'URL est /posts/index?page=1&sort=title
$value = $this->request->query('page');
69
CakeRequest::accepts($type = null)
Trouve quels types de contenu le client accepte ou vrifie si ils acceptent un type particulier de contenu.
Rcupre tous les types :
<?php
$this->request->accepts();
CakeRequest::param($name)
Lit les valeurs en toute scurit dans $request->params. Celle-ci enlve la ncessit dappeler
isset() ou empty() avant lutilisation des valeurs de param.
Introduit dans la version 2.4.
property CakeRequest::$data
Un tableau de donnes POST. Vous pouvez utiliser CakeRequest::data() pour lire cette proprit dune manire qui supprime les erreurs notice.
property CakeRequest::$query
Un tableau des paramtres de chane requts.
property CakeRequest::$params
Un tableau des lments de route et des paramtres requts.
property CakeRequest::$here
Retourne lURL requte courante.
property CakeRequest::$base
Le chemin de base de lapplication, normalement /, moins que votre application soit dans un sousrpertoire.
property CakeRequest::$webroot
Le webroot courant.
CakeResponse
CakeResponse est la classe de rponse par dfaut dans CakePHP. Elle encapsule un nombre de fonctionnalits et de caractristiques pour la gnration de rponses HTTP dans votre application. Elle aide
70
aussi tester puisquelle peut tre mocked/stubbed, vous permettant dinspecter les en-ttes qui vont tre
envoys. Comme CakeRequest, CakeResponse consolide un certain nombre de mthodes quon pouvait trouver avant dans Controller, RequestHandlerComponent et Dispatcher. Les anciennes
mthodes sont dprcies en faveur de lutilisation de CakeResponse.
CakeResponse fournit une interface pour envelopper les tches de rponse communes lies, telles que :
Envoyer des en-ttes pour les redirections.
Envoyer des en-ttes de type de contenu.
Envoyer tout en-tte.
Envoyer le corps de la rponse.
Changer la classe de rponse
CakePHP utilise CakeResponse par dfaut. CakeResponse est flexible et transparente pour lutilisation de la classe. Si vous avez besoin de la remplacer avec une classe spcifique de lapplication, vous pouvez
lcraser et remplacer CakeResponse avec votre propre classe en remplaant la classe CakeResponse
utilise dans app/webroot/index.php.
Cela fera que tous les controllers dans votre application utiliseront VotreResponse au lieu
de CakeResponse. Vous pouvez aussi remplacer linstance de rponse de la configuration
$this->response dans vos controllers. Ecraser lobjet rponse est porte de main pour les tests car il
vous permet dcraser les mthodes qui interagissent avec header(). Voir la section sur CakeResponse et
les tests pour plus dinformations.
Grer les types de contenu
Vous pouvez contrler le Content-Type des rponses de votre application en utilisant
CakeResponse::type(). Si votre application a besoin de grer les types de contenu qui
ne sont pas construits dans CakeResponse, vous pouvez faire correspondre ces types avec
CakeResponse::type() comme ceci :
// Ajouter un type vCard
$this->response->type(array('vcf' => 'text/v-card'));
// Configurer la rponse de Type de Contenu pour vcard.
$this->response->type('vcf');
Habituellement, vous voudrez faire correspondre des types de contenu supplmentaires dans le callback
beforeFilter() de votre controller, afin que vous puissiez tirer parti de la fonctionnalit de vue de
commutation automatique de RequestHandlerComponent, si vous lutilisez.
Envoyer des fichiers
Il y a des fois o vous voulez envoyer des fichiers en rponses de vos requtes. Avant la version 2.3, vous
pouviez utiliser MediaView pour faire cela. Depuis 2.3, MediaView est dprcie et vous pouvez utiliser
CakeResponse::file() pour envoyer un fichier en rponse :
71
Comme montr dans lexemple ci-dessus, vous devez passer le chemin du fichier la mthode.
CakePHP va envoyer le bon en-tte de type de contenu si cest un type de fichier connu list
dans CakeResponse::$_mimeTypes. Vous pouvez ajouter des nouveaux types avant dappeler
CakeResponse::file() en utilisant la mthode CakeResponse::type().
Si vous voulez, vous pouvez aussi forcer un fichier tre tlcharg au lieu dtre affich dans le navigateur
en spcifiant les options :
$this->response->file(
$file['path'],
array('download' => true, 'name' => 'foo')
);
72
Rgler le mme header() de multiples fois entranera lcrasement des prcdentes valeurs,
un peu comme les appels rguliers den-tte. Les en-ttes ne sont aussi pas envoys quand
CakeResponse::header() est appele ; la place, ils sont simplement conservs jusqu ce que la
rponse soit effectivement envoye.
Introduit dans la version 2.4.
Vous pouvez maintenant utiliser la mthode pratique CakeResponse::location() pour directement
dfinir ou rcuprer len-tte de localisation du redirect.
Interagir avec le cache du navigateur
Vous avez parfois besoin de forcer les navigateurs ne pas mettre en cache les rsultats de laction dun
controller. CakeResponse::disableCache() est justement prvu pour cela :
public function index() {
// faire quelque chose.
$this->response->disableCache();
}
Avertissement : En utilisant disableCache() avec downloads partir de domaines SSL pendant que vous
essayez denvoyer des fichiers Internet Explorer peut entraner des erreurs.
Vous pouvez aussi dire aux clients que vous voulez quils mettent en cache des rponses. En utilisant
CakeResponse::cache() :
public function index() {
//faire quelque chose
$this->response->cache('-1 minute', '+5 days');
}
Ce qui est au-dessus dira aux clients de mettre en cache la rponse rsultante pendant 5 jours, en esprant
acclrer lexprience de vos visiteurs. CakeResponse::cache() dfinit valeur Last-Modified en
premier argument. Expires, et max-age sont dfinis en se basant sur le second paramtre. Le Cache-Control
est dfini aussi public.
Rglage fin du Cache HTTP
Une des faons les meilleures et les plus simples de rendre votre application plus rapide est dutiliser le
cache HTTP. Avec la mise en cache des models, vous navez qu aider les clients dcider si ils doivent
utiliser une copie mise en cache de la rponse en configurant un peu les en-ttes comme les temps modifis,
les balises dentit de rponse et autres.
En savoir plus sur les controllers
73
Oppos lide davoir coder la logique de mise en cache et de sa nullit (rafrachissement) une fois
que les donnes ont chang, HTPP utilise deux models, lexpiration et la validation qui habituellement sont
beaucoup plus simples que davoir grer le cache soi-mme.
En dehors de lutilisation de CakeResponse::cache() vous pouvez aussi utiliser plusieurs autres
mthodes pour affiner le rglage des en-ttes de cache HTTP pour tirer profit du navigateur ou linverse
du cache du proxy.
Len-tte de Cache Control
La classe CakeResponse vous aide configurer cet en-tte avec quelques mthodes utiles
qui vont produire un en-tte final valide Cache Control. Premirement il y a la mthode
CakeResponse::sharable(), qui indique si une rponse peut tre considre comme partageable
pour diffrents utilisateurs ou clients. Cette mthode contrle gnralement la partie public ou private
de cet en-tte. Dfinir une rponse en priv indique que tout ou une partie de celle-ci est prvue pour un
unique utilisateur. Pour tirer profit des mises en cache partages, il est ncessaire de dfinir la directive de
contrle en publique.
Le deuxime paramtre de cette mthode est utilis pour spcifier un max-age pour le cache, qui est le
nombre de secondes aprs lesquelles la rponse nest plus considre comme rcente :
public function view() {
...
// Dfini le Cache-Control en public pour 3600 secondes
$this->response->sharable(true, 3600);
}
public function mes_donnees() {
...
// Dfini le Cache-Control en private pour 3600 secondes
$this->response->sharable(false, 3600);
}
CakeResponse expose des mthodes spares pour la dfinition de chaque component dans len-tte
Cache-Control.
Len-tte dExpiration
74
Aussi sous le model dexpiration de cache, vous pouvez dfinir len-tte Expires, qui selon la spcification
HTTP est la date et le temps aprs que la rponse ne soit plus considre comme rcente. Cet en-tte peut
tre dfini en utilisant la mthode CakeResponse::expires() :
public function view() {
$this->response->expires('+5 days');
}
Cette mthode accepte aussi une instance DateTime ou toute chane de caractre qui peut tre parse par
la classe DateTime.
Len-tte Etag
Len-tte Last-Modified
75
Len-tte Vary
Dans certains cas, vous voudrez offrir diffrents contenus en utilisant la mme URL. Cest souvent le cas
quand vous avez une page multilingue ou que vous rpondez avec diffrents HTMLs selon le navigateur qui
requte la ressource. Dans ces circonstances, vous pouvez utiliser len-tte Vary :
$this->response->vary('User-Agent');
$this->response->vary('Accept-Encoding', 'User-Agent');
$this->response->vary('Accept-Language');
De plus, vous pouvez faciliter encore plus lexcution des tests partir dune ligne de commande, pendant
que vous pouvez mocker pour viter les erreurs denvois den-ttes qui peuvent arriver en essayant de
configurer les en-ttes dans CLI.
API de CakeResponse
class CakeResponse
CakeResponse fournit un nombre de mthodes utiles pour interagir avec la rponse que vous envoyez
un client.
CakeResponse::header($header = null, $value = null)
Vous permet de configurer directement un ou plusieurs en-ttes envoyer avec la rponse.
CakeResponse::location($url = null)
Vous permet de dfinir directement len-tte de localisation du redirect envoyer avec la rponse :
76
77
CakeResponse::body($content = null)
Configurer le contenu du body pour la rponse.
CakeResponse::send()
Une fois que vous avez fini de crer une rponse, appeler send() enverra tous les en-ttes configurs
ainsi que le body. Ceci est fait automatiquement la fin de chaque requte par Dispatcher.
CakeResponse::file($path, $options = array())
Vous permet de dfinir un fichier pour laffichage ou le tlchargement.
Introduit dans la version 2.3.
Scaffolding
Obsolte depuis la version 2.5 : Le scaffolding dynamique sera retir et remplac dans 3.0
Une application scaffolding (chafaudage en Franais) est une technique permettant au dveloppeur de
dfinir et crer une application qui peut construire, afficher, modifier et dtruire facilement des objets. Le
Scaffolding dans CakePHP permet galement aux dveloppeurs de dfinir comment les objets sont lis entre
eux, et de crer ou casser ces liens.
Pour crer un scaffold, vous navez besoin que dun model et de son controller. Dclarez la variable $scaffold
dans le controller, et lapplication est dj prte tourner !
Le scaffolding par CakePHP est vraiment bien imagin. Il vous permet de mettre en place une application
basique CRUD (Cration, Vue, Edition et Destruction) en quelques minutes. Il est si bien fait que vous aurez
envie de lutiliser dans toutes vos applications. Attention ! Nous pensons aussi que le scaffolding est utile,
mais veuillez raliser que ce nest... quun chafaudage ! Cest une structure trs simple mettre en oeuvre,
et il vaut mieux ne lutiliser quau dbut dun projet. Il na pas t conu pour tre flexible, mais uniquement
pour tre un moyen temporaire de mettre en place votre application. A partir du moment o vous voudrez
adapter les fonctions et les vues associes, il vous faudra dsactiver le scaffolding et crire votre propre
code. bake console de CakePHP, que vous pourrez apprendre connatre dans la prochaine section, est une
bonne alternative : il va gnrer tout le code quivalent ce que ferait le scaffolding.
Le Scaffolding est utiliser au tout dbut du dveloppement dune application Internet. Le schma de votre
base de donnes est encore susceptible de changer, ce qui est tout faire normal ce stade du processus de
cration. Ceci a un inconvnient : un dveloppeur dteste crer des formulaires dont il ne verra jamais lutilisation relle. Cest pour rduire le stress du dveloppeur que le Scaffolding a t introduit dans CakePHP.
Il analyse les tables de votre base et cre de faon simple une liste des enregistrements, avec les boutons
dajout, de suppression et de modification, des formulaires pour ldition et une vue pour afficher un enregistrement en particulier.
Pour ajouter le Scaffolding dans votre application, ajoutez la variable $scaffold dans votre controller
class CategoriesController extends AppController {
public $scaffold;
}
En supposant que vous avez bien cre un model Category dans le bon dossier
(app/Model/Category.php), vous pouvez aller sur http ://exemple.com/categories pour voir
votre nouveau scaffold.
78
Note : Crer des mthodes dans un controller contenant la variable $scaffold peut donner des rsultats
inattendus. Par exemple, si vous crez une mthode index() dans ce controller, votre mthode remplacera
celle rendue normalement par la fonctionnalit de scaffold
Le Scaffolding prend bien en compte les relations contenues dans votre model. Ainsi, si votre model Category a une relation belongsTo avec le model User, vous verrez les identifiants des users dans laffichage
de vos catgories. Puisque scaffolding connat les associations entre models, vous ne verrez pas denregistrements lis dans les vues via scaffold jusqu ce que vous ajoutiez manuellement un code dassociation
au model. Par exemple, si le model Group hasMany User et que User belongsTo Group, vous devrez
ajouter manuellement le code suivant dans vos models User et Group. Avant de faire cela, la vue affiche un
select vide pour le Group dans le Nouveau formulaire User ; after populated avec les IDs ou noms partir
de la table du Group dans le Nouveau formulaire User :
// Dans Group.php
public $hasMany = 'User';
// Dans User.php
public $belongsTo = 'Group';
Si vous prfrez voir autre chose en plus des identifiants (par exemple les prnoms des users), vous
pouvez affecter la variable $displayField dans le model. Voyons comment dfinir la variable
$displayField dans la classe des users, afin que le prnom soit montr en lieu et place de lunique
identifiant. Cette astuce permet de rendre le scaffolding plus lisible dans de nombreux cas :
class User extends AppModel {
public $displayField = 'first_name';
}
Cest une mthode facile pour crer rapidement une interface dadministration simple. Gardez lesprit
que vous ne pouvez pas avoir de mthodes de scaffolding la fois dans la partie admin et dans la partie non-admin en mme temps. Comme avec le scaffolding normal, vous pouvez surcharger les mthodes
individuelles et les remplacer par vos propres mthodes :
En savoir plus sur les controllers
79
Une fois que vous avez remplac une action de scaffolding, vous devrez crer une vue pour cette action.
Personnaliser les vues obtenues par le Scaffolding
Si vous dsirez un rendu un peu diffrent de vos vues obtenues par le Scaffolding, vous pouvez crer des
mises en pages personnalises. Nous continuons de vous recommander de ne pas utiliser cette technique
pour produire vos sites, mais pouvoir modifier les vues peut tre utile pour leur dveloppement.
La personnalisation des vues scaffoldes pour un controller spcifique (PostsController dans notre exemple)
doit tre place comme ceci :
app/View/Posts/scaffold.index.ctp
app/View/Posts/scaffold.form.ctp
app/View/Posts/scaffold.view.ctp
Les vues scaffoldes personnalises pour tous les controllers doivent tre places comme ceci :
app/View/Scaffolds/index.ctp
app/View/Scaffolds/form.ctp
app/View/Scaffolds/view.ctp
Le Controller Pages
Le cur de CakePHP est livr avec un controller par dfaut PagesController.php. Cest un
controller simple et optionnel qui permet de rendre un contenu statique. La page daccueil que vous
voyez juste aprs linstallation est dailleurs gnre laide de ce controller. Ex : Si vous crivez
un fichier de vue app/View/Pages/a_propos.ctp, vous pouvez y accder en utilisant lurl
http://exemple.com/pages/a_propos. Vous pouvez modifier le controller Pages selon vos besoins.
Quand vous cuisinez une application avec lutilitaire console de CakePHP, le controller Pages est copi dans votre dossier app/Controller/ et vous pouvez le
modifier selon vos besoins. Ou vous pouvez simplement copier le fichier partir de
lib/Cake/Console/Templates/skel/Controller/PagesController.php.
Modifi dans la version 2.1 : Avec CakePHP 2.0, le controller Pages tait une partie de lib/Cake. Depuis
2.1, le controller Pages ne fait plus partie du coeur, mais se situe dans le dossier app.
Avertissement : Ne modifiez directement AUCUN fichier du dossier lib/Cake pour viter les problmes lors des mises jour du coeur dans le futur.
80
Components (Composants)
Les Components (Composants) sont des regroupements de logique applicative qui sont partags entre les
controllers. CakePHP est galement livr avec un fantastique ensemble de components, que vous pouvez
utiliser pour vous aider. Si vous vous surprenez vouloir copier et coller des choses entre vos controllers,
alors vous devriez envisager de regrouper plusieurs fonctionnalits dans un Component. Crer des components permet de garder un code de controller propre et de rutiliser du code entre diffrents projets.
Chacun de ces components dorigine est dtaill dans son chapitre spcifique. Regardez Components (Composants). Cette section dcrit la faon de configurer et dutiliser les components et la faon de crer vos
propres components.
Configuration des Components
De nombreux components du cur ncessitent une configuration. Quelques exemples : Authentification et
Cookie. Toute configuration pour ces components, et pour les components en gnral, se fait dans le tableau
des $components de la mthode beforeFilter() de vos controllers :
class PostsController extends AppController {
public $components = array(
'Auth' => array(
'authorize' => array('controller'),
'loginAction' => array(
'controller' => 'users',
'action' => 'login'
)
),
'Cookie' => array('name' => 'CookieMonster')
);
La portion de code prcdente est un exemple de configuration dun component avec le tableau
$components. Tous les components du coeur permettent aux paramtres dtre configurs dans la mthode de votre controller beforeFilter(). Cest utile quand vous avez besoin dassigner les rsultats
dune fonction la proprit dun component. Ceci peut aussi tre exprim comme ceci :
public function beforeFilter() {
$this->Auth->authorize = array('controller');
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login'
);
$this->Cookie->name = 'CookieMonster';
}
Cest possible, cependant, que le component ncessite certaines options de configuration avant que le controller beforeFilter() soit lanc. Pour cela, certains components permettent aux options de configuration dtre dfinies dans le tableau $components :
81
Consultez la documentation approprie pour connatre les options de configuration que chaque component
fournit.
Un paramtre commun utiliser est loption className, qui vous autorise les alias des components. Cette
fonctionnalit est utile quand vous voulez remplacer $this->Auth ou une autre rfrence de Component
commun avec une implmentation sur mesure :
// app/Controller/PostsController.php
class PostsController extends AppController {
public $components = array(
'Auth' => array(
'className' => 'MyAuth'
)
);
}
// app/Controller/Component/MyAuthComponent.php
App::uses('AuthComponent', 'Controller/Component');
class MyAuthComponent extends AuthComponent {
// Ajouter votre code pour surcharger le AuthComponent du coeur
}
Note : Puisque les Models et les Components sont tous deux ajouts aux controllers en tant que proprit,
82
ils partagent le mme espace de noms. Assurez vous de ne pas donner le mme nom un component et
un model.
Vous navez parfois pas besoin de rendre le component accessible sur chaque action. Dans ce cas l, vous
pouvez charger la vole en utilisant la Component Collection. A partir de lintrieur dun controller, vous
pouvez faire comme ce qui suit :
$this->OneTimer = $this->Components->load('OneTimer');
$this->OneTimer->getTime();
Note : Gardez lesprit que le chargement dun component la vole ne va pas appeler la mthode initialize.
Si le component que vous appelez a cette mthode, vous devrez lappeler manuellement aprs le chargement.
Note : Tous les components comme Math doivent tendre Component. Ne pas le faire vous enverra une
exception.
Une fois notre component termin, nous pouvons lutiliser au sein des controllers de lapplication en plaant
son nom (sans la partie Component) dans le tableau $components du controller. Le controller sera
En savoir plus sur les controllers
83
automatiquement pourvu dun nouvel attribut nomm daprs le component, travers lequel nous pouvons
accder une instance de celui-ci :
/* Rend le nouveau component disponible par $this->Math
ainsi que le component standard $this->Session */
public $components = array('Math', 'Session');
Les Components dclars dans AppController seront fusionns avec ceux dclars dans vos autres
controllers. Donc il ny a pas besoin de re-dclarer le mme component deux fois.
Quand vous incluez des Components dans un Controller, vous pouvez aussi dclarer un ensemble de
paramtres qui seront passs la mthode initialize() du Component. Ces paramtres peuvent alors tre
pris en charge par le Component :
public $components = array(
'Math' => array(
'precision' => 2,
'generateurAleatoire' => 'srand'
),
'Session', 'Auth'
);
Parfois un de vos components a besoin dutiliser un autre component. Dans ce cas, vous pouvez inclure
dautres components dans votre component exactement de la mme manire que dans vos controllers - en
utilisant la variable $components :
// app/Controller/Component/CustomComponent.php
class CustomComponent extends Component {
// l'autre component que votre component utilise
public $components = array('Existing');
public function initialize($controller) {
$this->Existing->foo();
}
public function bar() {
// ...
}
}
// app/Controller/Component/ExistingComponent.php
class ExistingComponent extends Component {
public function initialize($controller) {
$this->Parent->bar();
}
84
Note : Au contraire dun component inclus dans un controller, aucun callback ne sera attrap pour un
component inclus dans un component.
API de Component
class Component
La classe de base de Component vous offre quelques mthodes pour le chargement facile des
autres Components travers ComponentCollection comme nous lavons trait avec la gestion
habituelle des paramtres. Elle fournit aussi des prototypes pour tous les callbacks des components.
Component::__construct(ComponentCollection $collection, $settings = array())
Les Constructeurs pour la classe de base du component. Tous les paramtres se trouvent dans
$settings et ont des proprits publiques. Ils vont avoir leur valeur change pour correspondre
aux valeurs de $settings.
Les Callbacks
Component::initialize(Controller $controller)
Est appele avant la mthode du controller beforeFilter.
Component::startup(Controller $controller)
Est appele aprs la mthode du controller beforeFilter mais avant que le controller nexcute laction
prvue.
Component::beforeRender(Controller $controller)
Est appele aprs que le controller excute la logique de laction requte, mais avant le rendu de la
vue et le layout du controller.
Component::shutdown(Controller $controller)
Est appele avant que la sortie soit envoye au navigateur.
Component::beforeRedirect(Controller $controller, $url, $status=null, $exit=true)
Est invoque quand la mthode de redirection du controller est appele, mais avant toute action qui
suit. Si cette mthode retourne false, le controller ne continuera pas de rediriger la requte. Les variables $url, $status et $exit ont la mme signification que pour la mthode du controller. Vous pouvez
aussi retourner une chane de caractre qui sera interprte comme une URL pour rediriger ou retourner un array associatif avec la cl url et ventuellement status et exit.
85
86
CHAPITRE 5
Views (Vues)
Les Views (Vues) sont le V dans MVC. Les vues sont charges de gnrer la sortie spcifique requise par la
requte. Souvent, cela est fait sous forme HTML, XML ou JSON, mais le streaming de fichiers et la cration
de PDFs que les utilisateurs peuvent tlcharger sont aussi de la responsabilit de la couche View.
CakePHP a quelques classes de vue dj construites pour grer les scnarios de rendu les plus communs :
Pour crer des services web XML ou JSON, vous pouvez utiliser Vues JSON et XML.
Pour servir des fichiers protgs, ou gnrer des fichiers dynamiquement, vous pouvez utiliser Envoyer
des fichiers.
Pour crer plusieurs vues pour un thme, vous pouvez utiliser Thmes.
Templates de Vues
La couche view de CakePHP cest la faon dont vous parlez vos utilisateurs. La plupart du temps, vos vues
afficheront des documents (X)HTML pour les navigateurs, mais vous pourriez aussi avoir besoin de fournir
des donnes AMF un objet Flash, rpondre une application distante via SOAP ou produire un fichier
CSV pour un utilisateur.
Les fichiers de vue de CakePHP sont crits en pur PHP et ont par dfaut .ctp (Cakephp TemPlate) comme
extension. Ces fichiers contiennent toute la logique de prsentation ncessaire lorganisation des donnes
reues du controller, dans un format qui satisfasse laudience que vous recherchez. Si vous prfrez utiliser
un langage de template comme Twig, ou Smarty, une sous-classe de View fera le pont entre votre language
de template et CakePHP.
Un fichier de vue est stock dans /app/View/, dans un sous-dossier portant le nom du controller qui utilise ce fichier. Il a un nom de fichier correspondant son action. Par exemple, le
fichier de vue pour laction view() du controller Products devra normalement se trouver dans
/app/View/Products/view.ctp.
La couche vue de CakePHP peut tre constitue dun certain nombre de parties diffrentes. Chaque partie a
diffrent usages qui seront prsents dans ce chapitre :
views : Les Views sont la partie de la page qui est unique pour laction lance. Elles sont la substance de
la rponse de votre application.
87
elements : morceaux de code de view plus petits, rutilisables. Les lments sont habituellement rendus
dans les vues.
layouts : fichiers de vue contenant le code de prsentation qui se retrouve dans plusieurs interfaces de
votre application. La plupart des vues sont rendues lintrieur dun layout.
helpers : ces classes encapsulent la logique de vue qui est requise de nombreux endroits de la couche
view. Parmi dautres choses, les helpers de CakePHP peuvent vous aider crer des formulaires, des
fonctionnalits AJAX, paginer les donnes du model ou dlivrer des flux RSS.
Vues tendues
Introduit dans la version 2.1.
Une vue tendue vous permet denrouler une vue dans une autre. En combinant cela avec view blocks, cela
vous donne une faon puissante pour garder vos vues DRY. Par exemple, votre application a une sidebar qui
a besoin de changer selon la vue spcifique en train dtre rendue. En tendant un fichier de vue commun,
vous pouvez viter de rpeter la balise commune pour votre sidebar, et seulement dfinir les parties qui
changent :
// app/View/Common/view.ctp
<h1><?php echo $this->fetch('title'); ?></h1>
<?php echo $this->fetch('content'); ?>
<div class="actions">
<h3>Related actions</h3>
<ul>
<?php echo $this->fetch('sidebar'); ?>
</ul>
</div>
Le fichier de vue ci-dessus peut tre utilis comme une vue parente. Il sattend ce que la vue ltendant
dfinisse des blocks sidebar et title. Le block content est un block spcial que CakePHP cre. Il
contiendra tous les contenus non capturs de la vue tendue. En admettant que notre fichier de vue a une
variable $post avec les donnes sur notre post. Notre vue pourrait ressembler ceci :
<?php
// app/View/Posts/view.ctp
$this->extend('/Common/view');
$this->assign('title', $post);
$this->start('sidebar');
?>
<li>
<?php
echo $this->Html->link('edit', array(
'action' => 'edit',
$post['Post']['id']
)); ?>
</li>
<?php $this->end(); ?>
88
Lexemple ci-dessus vous montre comment vous pouvez tendre une vue, et remplir un ensemble de bloc.
Tout contenu qui ne serait pas dj dans un bloc dfini, sera captur et plac dans un block spcial appel
content. Quand une vue contient un appel vers un extend(), lexcution continue jusqu la fin de la
vue actuelle. Une fois termin, la vue tendue va tre gnre. En appelant extend() plus dune fois dans
un fichier de vue, le dernier appel va outrepasser les prcdents :
$this->extend('/Common/view');
$this->extend('/Common/index');
Le code prcdent va dfinir /Common/index.ctp comme tant la vue parente de la vue actuelle.
Vous pouvez imbriquer les vues autant que vous le voulez et que cela vous est ncessaire. Chaque vue peut
tendre une autre vue si vous le souhaitez. Chaque vue parente va rcuprer le contenu de la vue prcdente
en tant que bloc content.
Note : Vous devriez viter dutiliser content comme nom de block dans votre application. CakePHP
lutilise pour dfinir le contenu non-captur pour les vues tendues.
Vous pouvez aussi le rattacher lintrieur dun block en utilisant start() plusieurs fois. La mthode
assign() peut tre utilise pour nettoyer ou outrepasser un block nimporte quel moment :
89
Dans 2.3, certaines nouvelles mthodes ont t ajoutes pour travailler avec les blocs. Le prepend() pour
ajouter du contenu avant un block existant :
// Ajoutez avant la sidebar
$this->prepend('sidebar', 'ce contenu va au-dessus de la sidebar');
La mthode startIfEmpty() peut tre utilise pour commencer un bloc seulement si il est vide ou non
dfini. Si le block existe dj, le contenu captur va tre cart. Cest utile quand vous voulez dfinir le
contenu par dfaut de faon conditionnel pour un bloc, qui ne doit pas dj exister :
// Dans un fichier de vue.
// Cre un block de navbar
$this->startIfEmpty('navbar');
echo $this->element('navbar');
echo $this->element('notifications');
$this->end();
// Dans une vue/layout parente
<?php $this->startIfEmpty('navbar'); ?>
<p>Si le block n est pas dfini pour l instant - montrer ceci la place</p>
<?php $this->end(); ?>
// Quelque part plus loin dans la vue/layout parent
echo $this->fetch('navbar');
Dans lexemple ci-dessus, le block navbar va seulement contenir le contenu ajout dans la premire section. Puisque le block a t dfini dans la vue enfant, le contenu par dfaut avec la balise <p> sera cart.
Note : Vous devriez viter dutiliser content comme nom de bloc. Celui-ci est utilis par CakePHP en
interne pour tendre les vues, et le contenu des vues dans le layout.
Vous pouvez galement utiliser fetch pour afficher du contenu, sous conditions, qui va entourer un block
existant. Ceci est trs utile dans les layouts, ou dans les vues tendues lorsque vous voulez, sous conditions,
afficher des en-ttes ou autres balises :
90
// dans app/View/Layouts/default.ctp
<?php if ($this->fetch('menu')): ?>
<div class="menu">
<h3>Menu options</h3>
<?php echo $this->fetch('menu'); ?>
</div>
<?php endif; ?>
Depuis 2.3.0, vous pouvez aussi fournir une valeur par dfaut pour un bloc qui ne devrait pas avoir de
contenu. Cela vous permet dajouter facilement du contenu placeholder, pour des dclarations vides. Vous
pouvez fournir une valeur par dfaut en utilisant le 2me argument :
<div class="shopping-cart">
<h3>Your Cart</h3>
<?php echo $this->fetch('cart', 'Votre cart est vide'); ?>
</div>
Le HtmlHelper vous permet aussi de contrler vers quels blocks vont les scripts :
// dans votre vue
$this->Html->script('carousel', array('block' => 'scriptBottom'));
// dans votre layout
echo $this->fetch('scriptBottom');
91
Layouts
Un layout contient le code de prsentation qui entoure une vue. Tout ce que vous voulez voir dans toutes
vos vues devra tre plac dans un layout.
Le fichier de layout par dfaut de CakePHP est plac dans /app/View/Layouts. Si vous voulez changer
entirement le look de votre application, alors cest le bon endroit pour commencer, parce que le code de
vue de rendu du controller est plac lintrieur du layout par dfaut quand la page est rendue.
Les autres fichiers de layout devront tre placs dans /app/View/Layouts. Quand vous crez un layout,
vous devez dire CakePHP o placer la sortie pour vos vues. Pour ce faire, assurez-vous que votre layout
contienne $this->fetch(content). Voici un exemple de ce quoi un layout pourrait ressembler :
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $this->fetch('title'); ?></title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<!-- Include external files and scripts here (See HTML helper for more info.) -->
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');
?>
</head>
<body>
<!-- Si vous voulez afficher une sorte de menu pour toutes vos vues, mettez
le ici -->
<div id="header">
<div id="menu">...</div>
</div>
<!-- Voil l'endroit ou je souhaite que mes vues soient affiches -->
<?php echo $this->fetch('content'); ?>
<!-- Ajoute un footer sur chaque page affiche -->
<div id="footer">...</div>
</body>
</html>
Note : Avant la version 2.1, la mthode fetch() ntait pas disponible, fetch(content) remplace
$content_for_layout et les lignes fetch(meta), fetch(css) et fetch(script)
taient contenues dans la variable $scripts_for_layout dans la version 2.0.
Les blocks script, css et meta contiennent tout contenu dfini dans les vues en utilisant le helper HTML
intgr. Il est utile pour inclure les fichiers JavaScript et les CSS partir des vues.
Note : Quand vous utilisez HtmlHelper::css() ou HtmlHelper::script() dans les fichiers de
vues, spcifiez false dans loption inline option pour placer la source html dans un block avec le mme
nom. (Regardez lAPI pour plus de dtails sur leur utilisation).
92
Par exemple, si une section de mon site incorpore un plus petit espace pour une bannire publicitaire, je
peux crer un nouveau layout avec le plus petit espace de publicit et le spcifier comme un layout pour
toutes les actions du controller en utilisant quelque chose comme :
class UsersController extends AppController {
public function view_active() {
$this->set('title_for_layout', 'Voir les Utilisateurs actifs');
$this->layout = 'default_small_ad';
}
public function view_image() {
$this->layout = 'image';
//sort une image de l\'utilisateur
}
}
CakePHP dispose de deux fonctionnalits de layout dans le coeur (en plus du layout default de CakePHP)
que vous pouvez utiliser dans votre propre application : ajax et flash. Le layout AJAX est pratique pour
laborer des rponses AJAX - cest un layout vide (la plupart des appels ajax ne ncessitent quun peu de
balise en retour, et pas une interface de rendu complte). Le layout flash est utilis pour les messages montrs
par la mthode Controller::flash().
Trois autres layouts, xml, js, et rss, existent dans le coeur permettant de servir rapidement et facilement du
contenu qui nest pas du text/html.
Layouts
93
Si vous souhaitez utiliser un layout qui existe dans un plugin, vous pouvez utiliser la syntaxe de plugin. Par
exemple pour utiliser le layout de contact partir du plugin Contacts :
class UsersController extends AppController {
public function view_active() {
$this->layout = 'Contacts.contact';
}
}
Elements
Beaucoup dapplications ont des petits blocks de code de prsentation qui doivent tre rpliqus dune
page une autre, parfois des endroits diffrents dans le layout. CakePHP peut vous aider rpter des
parties de votre site web qui doivent tre rutilises. Ces parties rutilisables sont appeles des Elements.
Les publicits, les boites daides, les contrles de navigation, les menus supplmentaires, les formulaires
de connexion et de sortie sont souvent intgrs dans CakePHP en elements. Un element est tout btement
une mini-vue qui peut tre inclue dans dautres vues, dans les layouts, et mme dans dautres elements. Les
elements peuvent tre utiliss pour rendre une vue plus lisible, en plaant le rendu dlments rptitifs dans
ses propres fichiers. Ils peuvent aussi vous aider rutiliser des fragments de contenu dans votre application.
Les elements se trouvent dans le dossier /app/View/Elements/, et ont une extension .ctp. Ils sont
affichs en utilisant la mthode element de la vue :
echo $this->element('helpbox');
Dans le fichier element, toutes les variables passs sont disponibles comme des membres du paramtre du
tableau (de la mme manire que Controller::set() fonctionne dans le controller avec les fichiers
de vues). Dans lexemple ci-dessus, le fichier /app/View/Elements/helpbox.ctp peut utiliser la
variable $helptext :
// A l'intrieur de app/View/Elements/helpbox.ctp
echo $helptext; //outputs "Oh, this text is very helpful."
La mthode View::element() supporte aussi les options pour lelement. Les options supportes sont
cache et callbacks. Un exemple :
echo $this->element('helpbox', array(
"helptext" => "Ceci est pass l'element comme $helptext",
"foobar" => "Ceci est pass l'element via $foobar",
),
94
array(
// utilise la configuration de cache "long_view"
"cache" => "long_view",
// dfini true pour avoir before/afterRender appel pour l'element
"callbacks" => true
)
);
La mise en cache delement est facilite par la classe Cache. Vous pouvez configurer les elements devant
tre stocks dans toute configuration de Cache que vous avez dfini. Cela vous donne une grande flexibilit
pour choisir o et combien de temps les elements sont stocks. Pour mettre en cache les diffrentes versions
du mme element dans une application, fournissez une valeur unique de la cl cache en utilisant le format
suivant :
$this->element('helpbox', array(), array(
"cache" => array('config' => 'short', 'key' => 'unique value')
)
);
Vous pouvez tirer profit des elements en utilisant requestAction(). La fonction requestAction()
rcupre les variables de vues partir dune action dun controller et les retourne en tableau. Cela permet
vos elements de fonctionner dans un style MVC pur. Crez une action du controller qui prpare les variables de la vue pour vos elements, ensuite appelez requestAction() depuis lintrieur du deuxime
paramtre de element() pour alimenter en variables de vues lelement depuis votre controller.
Pour ce faire, ajoutez quelque chose comme ce qui suit dans votre controller, en reprenant lexemple du
Post :
class PostsController extends AppController {
// ...
public function index() {
$posts = $this->paginate();
if ($this->request->is('requested')) {
return $posts;
}
$this->set('posts', $posts);
}
}
Et ensuite dans lelement, nous pouvons accder au model des posts pagins. Pour obtenir les cinq derniers
posts dans une liste ordonne, nous ferions ce qui suit :
<h2>Derniers Posts</h2>
<?php
$posts = $this->requestAction(
'posts/index/sort:created/direction:asc/limit:5'
);
?>
<ol>
<?php foreach ($posts as $post): ?>
<li><?php echo $post['Post']['title']; ?></li>
<?php endforeach; ?>
</ol>
Elements
95
Si vous rendez le mme element plus dune fois dans une vue et que vous avez activ la mise en cache,
assurez-vous de dfinir le paramtre key avec un nom diffrent chaque fois. Cela vitera que chaque
appel successif ncrase le rsultat de la mise en cache du prcdent appel de element(). Par exemple :
echo $this->element(
'helpbox',
array('var' => $var),
array('cache' => array('key' => 'first_use', 'config' => 'view_long')
);
echo $this->element(
'helpbox',
array('var' => $differenVar),
array('cache' => array('key' => 'second_use', 'config' => 'view_long')
);
Ce qui est au-dessus va senqurir que les deux rsultats delement sont mis en cache sparment. Si vous
voulez que tous les elements mis en cache utilisent la mme configuration du cache, vous pouvez sauvegarder quelques rptitions, en configurant View::$elementCache dans la configuration de Cache que
vous souhaitez utiliser. CakePHP va utiliser cette configuration, quand aucune nest donne.
2.1
Si vous utilisez un plugin et souhaitez utiliser les elements partir de lintrieur dun plugin, utilisez juste
la syntaxe de plugin habituelle. Si la vue est rendue pour un controller/action dun plugin, le nom du plugin
va automatiquement tre prfix pour tous les elements utiliss, moins quun autre nom de plugin ne soit
prsent. Si lelement nexiste pas dans le plugin, il ira voir dans le dossier principal APP.
echo $this->element('Contacts.helpbox');
Si votre vue fait parti dun plugin, vous pouvez ne pas mettre le nom du plugin. Par exemple, si vous tes
dans le ContactsController du plugin Contacts :
96
echo $this->element('helpbox');
// et
echo $this->element('Contacts.helpbox');
Remplacer la mthode render vous laisse le contrle total sur la faon dont votre contenu est rendu.
API de View
class View
Les mthodes de View sont accessibles dans toutes les vues, element et fichiers de layout. Pour appeler toute
mthode de view, utilisez $this->method()
View::set(string $var, mixed $value)
Les Views ont une mthode set() qui est analogue set() qui se trouvent dans les objets du
controller. Utiliser set() partir de votre fichier de vue va ajouter les variables au layout et aux elements qui seront rendus plus tard. Regarder Les Mthodes du Controller pour plus dinformations sur
lutilisation de set().
Dans votre fichier de vue, vous pouvez faire :
$this->set('activeMenuButton', 'posts');
97
Ensuite dans votre fichier de layout la variable $activeMenuButton sera disponible et contiendra
la valeur posts.
View::get(string $var, $default = null)
Rcupre la valeur dune viewVar avec le nom de $var.
Depuis 2.5 vous pouvez fournir une valeur par dfaut dans le cas o la variable nest pas dj dfinie.
Modifi dans la version 2.5 : Largument $default a t ajout dans 2.5.
View::getVar(string $var)
Rcupre la valeur de viewVar avec le nom $var.
Obsolte depuis la version 2.3 : Utilisez View::get() la place.
View::getVars()
Rcupre une liste de toutes les variables de view disponibles dans le cadre de rendu courant. Retourne
un tableau des noms de variable.
View::element(string $elementPath, array $data, array $options = array())
Rend un element ou une vue partielle. Regardez la section sur Elements pour plus dinformations et
dexemples.
View::uuid(string $object, mixed $url)
Gnre un ID de DOM unique pour un objet non pris au hasard, bas sur le type dobjet et lURL.
Cette mthode est souvent utilise par les helpers qui ont besoin de gnrer un ID de DOM unique
pour les elements comme le JsHelper :
$uuid = $this->uuid(
'form',
array('controller' => 'posts', 'action' => 'index')
);
//$uuid contains 'form0425fe3bad'
View::append($name, $content)
Ajoute dans le block avec $name. Regardez la section sur les Utiliser les Blocs de Vues pour des
exemples.
Introduit dans la version 2.1.
View::prepend($name, $content)
Ajoute avant dans le block avec $name. Regardez la section Utiliser les Blocs de Vues pour des
exemples.
Introduit dans la version 2.3.
View::startIfEmpty($name)
Commence un block si il est vide. Tout le contenu dans le block va tre captur et cart si le block
est dj dfini.
Introduit dans la version 2.3.
View::assign($name, $content)
Assigne la valeur dun block. Cela va surcharger tout contenu existant. Regardez la section sur les
Utiliser les Blocs de Vues pour des exemples.
Introduit dans la version 2.1.
View::fetch($name, $default = )
Rcupre la valeur dun block. Si un block est vide ou non dfini, va tre retourn. Regardez la
section sur les Utiliser les Blocs de Vues pour des exemples.
Introduit dans la version 2.1.
View::extend($name)
Etend la vue/element/layout courant avec celle contenu dans $name. Regardez la section sur les Vues
tendues pour les exemples.
Introduit dans la version 2.1.
property View::$layout
Dfinit le layout qui va entourer la vue courante.
property View::$elementCache
La configuration de cache utilise pour les elements de cache. Dfinir cette proprit va changer la
configuration par dfaut utilise pour mettre en cache les elements. Celle par dfaut peut tre surcharge en utilisant loption cache dans la mthode element.
property View::$request
Une instance de CakeRequest. Utilisez cette instance pour accder aux informations qui concernent
la requte courante.
property View::$output
Contient le dernier contenu rendu dune view, ou dun fichier de view, ou dun contenu de layout.
Obsolte depuis la version 2.1 : Utilisez $view->Blocks->get(content); la place.
property View::$Blocks
Une instance de ViewBlock. Utilis pour fournir la fonctionnalit des blocks de view dans le rendu
de view.
Introduit dans la version 2.1.
API de View
99
Modifi dans la version 2.1 : Les versions antrieures 2.1 ont besoin de dfinir $this->viewClass =
Theme. 2.1 enlve cette condition puisque la classe normale View supporte les thmes.
Vous pouvez galement dfinir ou modifier le nom du thme dans une action ou dans les fonctions de
callback beforeFilter ou beforeRender :
$this->theme = 'AutreExemple';
Les fichiers de vue du thme ont besoin dtre dans le dossier /app/View/Themed/. Dans le dossier
du thme, crez un dossier utilisant le mme nom que le nom de votre thme. Par exemple, Le thme cidessus serait trouv dans /app/View/Themed/AutreExemple. Il est important de se souvenir que
CakePHP attend des noms de thme en CamelCase. Au-del de a, la structure de dossier dans le dossier
/app/View/Themed/Exemple/ est exactement le mme que /app/View/.
Par exemple, le fichier de vue pour une action edit dun controller Posts se trouvera dans
/app/View/Themed/Exemple/Posts/edit.ctp. Les fichiers de Layout se trouveront dans
/app/View/Themed/Exemple/Layouts/.
Si un fichier de vue ne peut pas tre trouv dans le thme, CakePHP va essayer de localiser le fichier de vue
dans le dossier /app/View/. De cette faon, vous pouvez crer des fichiers de vue master et simplement
les remplacer au cas par cas au sein de votre dossier de thme.
Assets du thme
Les thmes peuvent contenir des assets statiques ainsi que des fichiers de vue. Un thme peut inclure tout
asset ncessaire dans son rpertoire webroot. Cela permet un packaging facile et une distribution des thmes.
Pendant le dveloppement, les requtes pour les assets du thme seront grs par Dispatcher. Pour
amliorer la performance des environnements de production, il est recommand, soit que vous fassiez un
lien symbolique, soit que vous copiez les assets du thme dans le webroot de application. Voir ci-dessous
pour plus dinformations.
Pour utiliser le nouveau webroot du thme, crez des rpertoires comme :
``app/View/Themed/<nomDuTheme>/webroot<chemin_vers_fichier>``
dans votre thme. Le Dispatcher se chargera de trouver les assets du thme corrects dans vos chemins de
vue.
100
Tous les helpers integrs dans CakePHP ont intgrs lexistence des thmes et vont crer des chemins daccs
corrects automatiquement. Comme pour les fichiers de vue, si un fichier nest pas dans le dossier du thme,
il sera par dfaut dans le dossier principal webroot
//Quand dans un thme avec un nom de 'purple_cupcake'
$this->Html->css('main.css');
//cre un chemin comme
/theme/purple_cupcake/css/main.css
//et fait un lien vers
app/View/Themed/PurpleCupcake/webroot/css/main.css
Cest un fait bien connu que de servir les assets par le biais de PHP est assur dtre plus lent que de servir ces
assets sans invoquer PHP. Et tandis que lquipe du coeur a pris des mesures pour rendre le plugin et lasset
du thme servis aussi vite que possible, il peut y avoir des situations o plus de performance est requis. Dans
ces situations, il est recommand soit que vous fassiez un lien symbolique soit que vous fassiez une copie
sur les assets du plug-in/thme vers des rpertoires dans app/webroot avec des chemins correspondant
ceux utiliss par cakephp.
app/Plugin/DebugKit/webroot/js/my_file.js devient app/webroot/DebugKit/js/my_file.js.
app/View/Themed/Navy/webroot/css/navy.css devient app/webroot/theme/Navy/css/navy.css
Vues Media
class MediaView
Obsolte depuis la version 2.3 : Utilisez Envoyer des fichiers la place.
Les vues Media vous permettent denvoyer des fichiers binaires lutilisateur. Par exemple, vous souhaiteriez avoir un rpertoire de fichiers en dehors de webroot pour empcher les utilisateurs de faire un lien
direct sur eux. Vous pouvez utiliser la vue Media pour tirer le fichier partir dun fichier spcial dans /app/,
vous permettant damliorer lauthentification avant la livraison du fichier lutilisateur.
Pour utiliser la vue Media, vous avez besoin de dire votre controller dutiliser la classe MediaView au lieu
de la classe View par dfaut. Aprs a, passez juste les paramtres en plus pour spcifier o votre fichier se
trouve :
class ExempleController extends AppController {
public function download() {
$this->viewClass = 'Media';
// Download app/outside_webroot_dir/example.zip
$params = array(
'id'
=> 'example.zip',
'name'
=> 'example',
'download' => true,
'extension' => 'zip',
'path'
=> APP . 'outside_webroot_dir' . DS
);
101
$this->set($params);
}
}
Ici vous trouvez un exemple de rendu dun fichier qui a un type mime qui nest pas inclu dans le tableau
$mimeType de MediaView. Nous utilisons aussi un chemin relatif qui va tre par dfaut dans votre dossier
app/webroot :
public function download() {
$this->viewClass = 'Media';
// Render app/webroot/files/example.docx
$params = array(
'id'
=> 'example.docx',
'name'
=> 'example',
'extension' => 'docx',
'mimeType' => array(
'docx' => 'application/vnd.openxmlformats-officedocument' .
'.wordprocessingml.document'
),
'path'
=> 'files' . DS
);
$this->set($params);
}
Paramtres configurables
id LID est le nom du fichier tel quil rside sur le serveur de fichiers, y compris lextension de fichier.
name Le nom vous permet de spcifier un nom de fichier alternatif envoyer lutilisateur. Spcifiez le
nom sans lextension du fichier.
download Une valeur bolenne indiquant si les en-ttes doivent tre dfinis pour forcer le tlchargement.
extension Lextension du fichier. Ceci est en correspondance avec une liste interne de types mime acceptables. Si le type MIME spcifi nest pas dans la liste (ou envoy dans le tableau de paramtres
mimeType), le fichier ne sera pas tlcharg.
path Le nom du dossier, y compris le sparateur de rpertoire finale. Le chemin doit tre absolu, mais peut
tre par rapport au dossier app/webroot.
mimeType Un tableau avec des types MIME supplmentaires fusionner avec une liste interne dans MediaView de types mime acceptables.
cache Une valeur boolenne ou entire - Si la valeur est vraie, elle permettra aux navigateurs de mettre en
cache le fichier (par dfaut false si non dfinie), sinon rglez le sur le nombre de secondes dans le
futur pour lorsque le cache expirera.
102
En activant RequestHandlerComponent dans votre application, et en activant le support pour les extensions xml et/ou json, vous pouvez automatiquement vous appuyer sur les nouvelles classes de vue.
XmlView et JsonView feront rfrence aux vues de donnes pour le reste de cette page.
Il y a deux faons de gnrer des vues de donnes. La premire est en utilisant la cl _serialize, et la
seconde en crant des fichiers de vue normaux.
Activation des vues de donnes dans votre application
Avant que vous puissiez utiliser les classes de vue de donnes, vous aurez besoin de faire un peu de configuration :
1. Activez les extensions json et/ou xml avec Router::parseExtensions(). Cela permettra au
Router de grer les multiples extensions.
2. Ajoutez le RequestHandlerComponent la liste de components de votre controller. Cela activera automatiquement le changement de la classe de vue pour les types de contenu.
Introduit dans la version 2.3 : La mthode RequestHandlerComponent::viewClassMap() a t
ajoute pour lier les types aux viewClasses. La configuration de viewClassMap ne va pas fonctionner avec
les versions prcdentes.
Aprs avoir ajout Router::parseExtensions(json); votre fichier de routes, CakePHP
changera automatiquement les classes de vue quand une requte sera faite avec lextension .json, ou
quand len-tte Accept sera application/json.
Utilisation des vues de donnes avec la cl _serialize
La cl _serialize est une variable de vue spciale qui indique quel autre(s) variable(s) de vue devraient
tre srialise(s) quand on utilise la vue de donnes. Cela vous permet de sauter la dfinition des fichiers de
vue pour vos actions de controller si vous navez pas besoin de faire un formatage avant que vos donnes ne
soient converties en json/xml.
Si vous avez besoin de faire tout type de formatage ou de manipulation de vos variables de vue avant la
gnration de la rponse, vous devrez utiliser les fichiers de vue. La valeur de _serialize peut tre soit
une chane de caractre, soit un tableau de variables de vue srialiser :
class PostsController extends AppController {
public $components = array('RequestHandler');
public function index() {
$this->set('posts', $this->Paginator->paginate());
$this->set('_serialize', array('posts'));
}
}
103
Vous pouvez faire des manipulations encore beaucoup plus complexes, comme utiliser les helpers pour
formater.
Note : Les classes de vue de donnes ne supportent pas les layouts. Elles supposent que le fichier de vue va
afficher le contenu srialis.
class XmlView
Une classe de vue pour la gnration de vue de donnes Xml. Voir au-dessus pour savoir comment
vous pouvez utiliser XmlView dans votre application
Par dfaut quand on utilise _serialize, XmlView va enrouler vos variables de vue srialises
avec un noeud <response>. Vous pouvez dfinir un nom personnalis pour ce noeud en utilisant la
variable de vue _rootNode.
Introduit dans la version 2.3 : La fonctionnalit _rootNode a t ajoute.
class JsonView
Une classe de vue pour la gnration de vue de donnes Json. Voir au-dessus pour savoir comment
vous pouvez utiliser XmlView dans votre application.
104
JSONP response
Introduit dans la version 2.4.
Quand vous utilisez JsonView, vous pouvez utiliser la variable de vue spciale _jsonp pour permettre de
retourner une rponse JSONP. La dfinir true fait que la classe de vue vrifie si le paramtre de chaine
de la requte nomme callback est dfinie et si cest la cas, permet denrouler la rponse json dans le nom
de la fonction fournie. Si vous voulez utiliser un nom personnalis de paramtre de requte la place de
callback, dfinissez _jsonp avec le nom requis la place de true.
Helpers (Assistants)
Les Helpers (Assistants) sont des classes comme les components, pour la couche de prsentation de votre
application. Ils contiennent la logique de prsentation qui est partage entre plusieurs vues, elements ou
layouts. Ce chapitre vous montrera comment crer vos propres helpers et soulignera les tches basiques que
les helpers du cur de CakePHP peuvent vous aider accomplir.
CakePHP dispose dun certain nombre de helpers qui aident la cration des vues. Ils aident la cration
de balises bien-formates (y compris les formulaires), aident la mise en forme du texte, les dures et les
nombres, et peuvent mme acclrer la fonctionnalit AJAX. Pour plus dinformations sur les helpers inclus
dans CakePHP, regardez le chapitre pour chaque helper :
CacheHelper
class CacheHelper(View $view, array $settings = array())
Le helper Cache permet la mise en cache des layouts (mises en page) et des vues permettant de gagner du
temps pour la rcupration de donnes rptitives. Le systme de cache des vues de CakePHP parse les
layout et les vues comme de simple fichier PHP + HTML. Il faut noter que le helper Cache fonctionne de
faon assez diffrente des autres helpers. Il ne possde pas de mthodes appeles directement. A la place,
une vue est marque de tags, indiquant quels blocs de contenus ne doivent pas tre mis en cache. Le Helper
Cache utilise alors les callbacks du helper pour traiter le fichier et ressortir pour gnrer le fichier de cache.
Quand une URL est appele, CakePHP vrifie si cette requte a dj t mise en cache. Si cest le cas, le
processus de distribution de lURL est abandonn. Chacun des blocs non mis en cache sont rendus selon le
processus normal, et la vue est servie. Cela permet de gagner beaucoup de temps pour chaque requte vers
une URL mise en cache, puisquun minimum de code est excut. Si CakePHP ne trouve pas une vue mise
en cache, ou si le cache a expir pour lURL appele, le processus de requte normal se poursuit.
Utilisation du Helper
Il y a deux tapes franchir avant de pouvoir utiliser le Helper Cache. Premirement dans votre
APP/Config/core.php d-commenter lappel Configure write pour Cache.check. Ceci dira
CakePHP de regarder dans le cache, et de gnrer laffichage des fichiers en cache lors du traitement des
demandes.
Une fois que vous avez dcomment la ligne Cache.check vous devez ajouter le helper votre tableau
$helpers de votre controller :
En savoir plus sur les vues
105
Vous devrez aussi ajouter CacheDispatcher vos filtres de dispatcher dans votre bootstrap :
Configure::write('Dispatcher.filters', array(
'CacheDispatcher'
));
Introduit dans la version 2.3 : Si vous avez une configuration avec des domaines ou des langages multiples,
vous pouvez utiliser Configure : :write(Cache.viewPrefix, YOURPREFIX) ; pour stocker les fichiers de
vue prfixs mis en cache.
Options de configuration supplmentaires Le Helper Cache (CacheHelper) dispose de plusieurs options
de configuration additionnelles que vous pouvez utiliser pour ajuster et rgler ces comportements. Ceci est
ralis a travers la variable $cacheAction dans vos controllers. $cacheAction doit tre rgler par un
tableau qui contient laction que vous voulez cacher, et la dure en seconde durant laquelle vous voulez que
cette vue soit cache. La valeur du temps peut tre exprim dans le format strtotime(). (ex. 1 hour,
ou 3 minutes).
En utilisant lexemple dun controller darticles ArticlesController, qui reoit beaucoup de trafic qui ont
besoins dtre mise en cache :
public $cacheAction = array(
'view' => 36000,
'index' => 48000
);
Ceci mettra en cache laction view 10 heures et laction index 13 heures. En plaant une valeur usuelle de
strtotime() dans $cacheAction vous pouvez mettre en cache toutes les actions dans le controller :
public $cacheAction = "1 hour";
Vous pouvez aussi activer les callbacks controller/component pour les vues caches cres avec
CacheHelper. Pour faire cela, vous devez utiliser le format de tableau pour $cacheAction et crer
un tableau comme ceci :
public $cacheAction = array(
'view' => array('callbacks' => true, 'duration' => 21600),
'add' => array('callbacks' => true, 'duration' => 36000),
'index' => array('callbacks' => true, 'duration' => 48000)
);
En paramtrant callbacks => true vous dites au CacheHelper (Assistant Cache) que vous voulez que
les fichiers gnrs crent les components et les models pour le controller. De manire additionnelle, lance la
mthode initialize du component, le beforeFilter du controller, et le dmarrage des callbacks de component.
Note : Dfinir callbacks => true fait chouer en partie le but de la mise en cache. Cest aussi la raison pour
laquelle ceci est dsactiv par dfaut.
106
Il y aura des fois o vous ne voudrez par mettre en cache une vue intgrale. Par exemple, certaines parties
dune page peuvent tre diffrentes, selon que lutilisateur est actuellement identifi ou quil visite votre site
en tant quinvit.
Pour indiquer que des blocs de contenu ne doivent pas tre mis en cache, entourez-les par < !nocache>
< !/nocache> comme ci-dessous :
<!--nocache-->
<?php if ($this->Session->check('User.name')) : ?>
Bienvenue, <?php echo h($this->Session->read('User.name')); ?>.
<?php else: ?>
<?php echo $html->link('Login', 'users/login')?>
<?php endif; ?>
<!--/nocache-->
Note : Vous ne pouvez pas utiliser les tags nocache dans les lments. Puisquil ny a pas de callbacks
autour des lments, ils ne peuvent tre cachs.
Il est noter, quune fois une action mise en cache, la mthode du controller correspondante ne sera plus
appele. Quand un fichier cache est cr, lobjet request, et les variables de vues sont srialises avec
serialize() de PHP.
Avertissement : Si vous avez des variables de vues qui contiennent des contenus inserialisable comme
les objets SimpleXML, des gestionnaires de ressource (resource handles), ou des classes closures Il se
peut que vous ne puissiez pas utiliser la mise en cache des vues.
Nettoyer le Cache
Il est important de se rappeler que CakePHP va nettoyer le cache si un model utilis dans la vue mise en
cache a t modifi. Par exemple, si une vue mise en cache utilise des donnes du model Post et quil y a
eu une requte INSERT, UPDATE, ou DELETE sur Post, le cache de cette vue est nettoy, et un nouveau
contenu sera gnr la prochaine requte.
Note : Ce systme de nettoyage automatique requiert que le nom du controller/model fasse partie de lURL.
Si vous avez utilis le routing pour changer vos URLs cela ne fonctionnera pas.
Si vous avez besoin de nettoyer le cache manuellement, vous pouvez le faire en appelant Cache : :clear().
Cela nettoiera toutes les donnes mises en cache, lexception des fichiers de vues mis en cache. Si vous
avez besoin de nettoyer les fichiers de vues, utilisez clearCache().
Flash
class FlashHelper(View $view, array $config = array())
107
FlashHelper fournit une faon de rendre les messages flash qui sont dfinis dans $_SESSION par FlashComponent. FlashComponent et FlashHelper utilisent principalement des elements pour rendre les messages
flash. Les elements flash se trouvent dans le rpertoire app/View/Elements/Flash. Vous remarquerez
que le template de lApp de CakePHP est livr avec deux elements flash : success.ctp et error.ctp.
FlashHelper remplace la mthode flash() de SessionHelper et doit tre utilis la place de cette
mthode.
Rendre les Messages Flash
Pour afficher un message flash, vous pouvez simplement utiliser la mthode render() du FlashHelper :
<?php echo $this->Flash->render() ?>
Par dfaut, CakePHP utilise une cl flash pour les messages flash dans une session. Mais si vous spcifiez
une cl lors de la dfinition du message flash dans FlashComponent, vous pouvez spcifier la cl flash
rendre :
<?php echo $this->Flash->render('other') ?>
Vous pouvez aussi surcharger toutes les options qui sont dfinies dans FlashComponent :
// Dans votre Controller
$this->Flash->set('The user has been saved.', array(
'element' => 'success'
));
// Dans votre View: Va utiliser great_success.ctp au lieu de success.ctp
<?php echo $this->Flash->render('flash', array(
'element' => 'great_success'
));
Note : Par dfaut, CakePHP nchappe pas le HTML dans les messages flash. Si vous utilisez une requte
ou des donnes dutilisateur dans vos messages flash, vous devez les chapper avec h lors du formatage de
vos messages.
Pour plus dinformations sur le tableau doptions disponibles, consultez la section FlashComponent.
FormHelper
class FormHelper(View $view, array $settings = array())
Le Helper Form prend en charge la plupart des oprations lourdes en cration du formulaire. Le Helper
Form se concentre sur la possibilit de crer des formulaires rapidement, dune manire qui permettra de
rationaliser la validation, la re-population et la mise en page (layout). Le Helper Form est aussi flexible
- Il va faire peu prs tout pour vous en utilisant les conventions, ou vous pouvez utiliser des mthodes
spcifiques pour ne prendre uniquement que ce dont vous avez besoin.
108
Cration de Formulaire
La premire mthode dont vous aurez besoin dutiliser pour prendre pleinement avantage du Helper Form
(Helper Formulaire) est create(). Cette mthode affichera un tag douverture de formulaire.
FormHelper::create(string $model = null, array $options = array())
Tous les paramtres sont optionnels. Si create() est appele sans paramtres, CakePHP supposera
que vous voulez crer un formulaire en rapport avec le controller courant, ou lURL actuelle. La
mthode par dfaut pour les formulaires est POST. Llment du formulaire est galement renvoy
avec un DOM ID. Cet identifiant est cr partir du nom du model, et du nom du controller en
notation CamelCase (les majuscules dlimitent les mots). Si jappelle create() dans une vue de
UsersController, jobtiendrai ce genre de rendu dans ma vue :
<form id="UserAddForm" method="post" action="/users/add">
Note :
Vous pouvez aussi passer false pour $model. Ceci placera vos donne de formulaire dans le tableau : $this->request->data (au lieu du sous
tableau :$this->request->data[Model]). Cela peut tre pratique pour des formulaires courts qui ne reprsenteraient rien dans votre base de donnes.
La mthode create() nous permet galement de personnaliser plusieurs paramtres. Premirement,
vous pouvez spcifier un nom de model. Ce faisant, vous modifiez le contexte de ce formulaire. Tous
les champs seront supposs dpendre de ce model (sauf si spcifi), et tous les models devront tre
lis lui. Si vous ne spcifiez pas de model, CakePHP supposera que vous utilisez le model par dfaut
pour le controller courant.
// si vous tes sur /recipes/add
echo $this->Form->create('Recipe');
Affichera :
<form id="RecipeAddForm" method="post" action="/recipes/add">
109
// Puisque $this->request->data['Recipe']['id'] = 5,
// nous aurons un formulaire d'dition
<?php echo $this->Form->create('Recipe'); ?>
Affichera :
<form id="RecipeEditForm" method="post" action="/recipes/edit/5">
<input type="hidden" name="_method" value="PUT" />
Note : Comme cest un formulaire de modification, un champ cach (hidden) est cr pour rcrire
la mthode HTTP par dfaut
A la cration de formulaires pour les models dans des plugins. Nous devrons toujours utiliser la
syntaxe de plugin la cration dun formulaire. Cela assurera que le formulaire est correctement
gnr :
echo $this->Form->create('ContactManager.Contact');
Le tableau $options est lendroit o la plupart des paramtres de configurations sont stocks. Ce
tableau spcial peut contenir un certain nombre de paires cl-valeur qui peuvent affecter la manire
dont le formulaire sera cr.
Modifi dans la version 2.0.
LUrl par dfaut pour tous les formulaires, est maintenant lUrl incluant passed, named, et les
paramtres de requte (querystring). Vous pouvez redfinir cette valeur par dfaut en fournissant
$options[url] en second paramtre de $this->Form->create().
Options pour create() Il y plusieurs options pour create() :
$options[type] Cette cl est utilise pour spcifier le type de formulaire crer. Les valeurs que
peuvent prendre cette variable sont post, get, file, put et delete.
Choisir post ou get changera la mthode de soumission du formulaire en fonction de votre choix.
echo $this->Form->create('User', array('type' => 'get'));
Affichera :
<form id="UserAddForm" method="get" action="/users/add">
Affichera :
<form id="UserAddForm" enctype="multipart/form-data"
method="post" action="/users/add">
Quand vous utilisez put ou delete, votre formulaire aura un fonctionnement quivalent un formulaire
de type post, mais quand il sera envoy, la mthode de requte HTTP sera respectivement rcrite avec
PUT ou DELETE. Cela permettra CakePHP de crer son propre support REST dans les navigateurs
web.
110
$options[action] La cl action vous permet de dfinir vers quelle action de votre controller
pointera le formulaire. Par exemple, si vous voulez que le formulaire appelle laction login() de votre
controller courant, vous creriez le tableau $options comme ceci
echo $this->Form->create('User', array('action' => 'login'));
Affichera :
<form id="UserLoginForm" method="post" action="/users/login">
</form>
$options[url] Si laction que vous dsirez appeler avec le formulaire nest pas dans le controller
courant, vous pouvez spcifier une URL dans le formulaire en utilisant la cl url de votre tableau $options. LURL ainsi fournie peut tre relative votre application CakePHP
echo $this->Form->create(null, array(
'url' => array('controller' => 'recipes', 'action' => 'add')
));
Affichera :
<form method="post" action="/recipes/add">
Affichera :
<form method="get" action="http://www.google.com/search">
Regardez aussi la mthode HtmlHelper::url() pour plus dexemples sur les diffrents types
dURLs.
$options[default] Si la variable default est dfinie false, laction de soumission du formulaire est change de telle manire que le bouton submit (de soumission) ne soumet plus le formulaire.
Si le formulaire a t cr pour tre soumis par AJAX, mettre la variable default FALSE supprime
le comportement par dfaut du formulaire, ainsi vous pouvez collecter les donnes et les soumettre par
AJAX la place.
$options[inputDefaults] Vous pouvez dclarer un jeu doptions par dfaut pour input()
avec la cl inputDefaults pour personnaliser vos input par dfaut :
echo $this->Form->create('User', array(
'inputDefaults' => array(
'label' => false,
'div' => false
)
));
Tous les input crs partir de ce point hriteraient des options dclares dans inputDefaults. Vous pouvez
redfinir le defaultOptions en dclarant loption dans lappel input() :
111
Fermer le Formulaire
Si une chane est fournie comme premier argument end(), le FormHelper affichera un bouton submit
nomm en consquence en mme temps que la balise de fermeture du formulaire.
echo $this->Form->end('Termine');
Affichera :
<div class="submit">
<input type="submit" value="Termine" />
</div>
</form>
Affichera :
<div class="glass-pill"><input type="submit" value="Update!" name="Update"></div>
112
Il y a plusieurs faons pour crer des Forms inputs (entre de formulaire) Commenons par regarder
input(). Cette mthode inspecte automatiquement le champ du model qui lui est fourni afin de crer
une entre approprie pour ce champ. En interne input() dlgue aux autre mthode du FormHelper.
FormHelper::input(string $fieldName, array $options = array())
Cre les lments suivants en donnant un Model.field particulier :
div enveloppante (wrapping div).
label de llment (Label element)
input de(s) llment(s) (Input element(s))
Erreur de llment avec un message si cest applicable.
Le type dinput cr dpends de la colonne datatype :
Column Type Champ de formulaire rsultant
string (char, varchar, etc.) text
boolean, tinyint(1) checkbox
text textarea
text, avec le nom de password, passwd, ou psword password
text, avec le nom de email email
text, avec le nom de tel, telephone, ou phone tel
date day, month, et year selects
datetime, timestamp day, month, year, hour, minute, et meridian selects
time hour, minute, et meridian selects
binary file
Le paramtre $options vous permet de personnaliser le fonctionnement de input(), et contrle
finement ce qui est gnr.
Le div entourant aura un nom de classe required ajout la suite si les rgles de validation pour
le champ du Model ne spcifient pas allowEmpty => true. Une limitation de ce comportement
est que le champ du model doit avoir t charg pendant la requte. Ou tre directement associ au
model fourni par create().
Introduit dans la version 2.5 : Le type binaire mappe maintenant vers un input de fichier.
Introduit dans la version 2.3. Depuis 2.3, lattribut HTML5 required va aussi tre ajout selon
les rgles de validation du champ. Vous pouvez explicitement dfinir la cl required dans le
tableau doptions pour la surcharger pour un champ. Pour chapper la validation attrape par le
navigateur pour lensemble du formulaire, vous pouvez dfinir loption formnovalidate =>
true pour linput button que vous gnrez en utilisant FormHelper::submit() ou dfinir
novalidate => true dans les options pour FormHelper::create().
Par exemple, supposons que votre model User contient les champs username (varchar), password
(varchar), approved (datetime) et quote (text). Vous pouvez utiliser la mthode input() de lHelper
Formulaire (Formhelper) pour crer une entre approprie pour tous les champs du formulaire.
echo $this->Form->create();
echo $this->Form->input('username');
//text
113
echo $this->Form->input('password');
echo $this->Form->input('approved');
echo $this->Form->input('quote');
//password
//day, month, year, hour, minute,
//meridian
//textarea
echo $this->Form->end('Add');
Outre les options spcifique pour input() vu ci-dessus, vous pouvez spcifier nimporte quelle
options pour le type dinput et nimporte quel attribut HTML (actuellement dans le focus). Pour plus
dinformation sur les $options et $htmlAttributes voir HTMLHelper.
Supposons un User hasAndBelongsToMany Group. Dans votre controller, dfinissez une variable
camelCase au pluriel (groupe -> groupes dans cette exemple, ou ExtraFunkyModele -> extraFunkyModeles) avec les options de slections. Dans laction du controller vous pouvez dfinir
$this->set('groups', $this->User->Group->find('list'));
Et dans la vue une slection multiple peut tre cre avec ce simple code :
echo $this->Form->input('Group');
Si vous voulez un champ de slection utilisant une relation belongsTo ou hasOne, vous pouvez ajouter
ceci dans votre controller Users (en supposant que lUser belongsTo Group) :
$this->set('groups', $this->User->Group->find('list'));
Si votre nom de model est compos de deux mots ou plus, ex. UserGroup, quand vous passez les
donnes en utilisant set() vous devrez nommer vos donnes dans un format CamelCase (les Majuscules sparent les mots) et au pluriel comme ceci
$this->set('userGroups', $this->UserGroup->find('list'));
// ou bien
$this->set(
'reallyInappropriateModelNames',
$this->ReallyInappropriateModelName->find('list')
);
Note : Essayez dviter lutilisation de FormHelper : :input() pour gnrer les boutons submit.
Utilisez plutt FormHelper::submit().
114
En plus des champs de contrle (fields control), inputs() permet dutiliser quelques options supplmentaires.
fieldset Mis false pour dsactiver le jeu de champs (fieldset). Si une chane est fournit, elle
sera utilise comme nom de classe (classname) pour llment fieldset.
legend Mis false pour dsactiver la lgende (legend) pour le jeu de champs input (input set)
gnr. Ou fournit une chane pour personnaliser le texte de la lgende (legend).
Conventions de nommage des champs Le Helper Form est assez volu. Lorsque vous dfinissez un
nom de champ avec les mthodes du Helper Form, celui-ci gnre automatiquement une balise input base
sur le nom de model courant, selon le format suivant :
<input type="text" id="ModelnameFieldname" name="data[Modelname][fieldname]">
Ceci permet domettre le nom du model lors de la gnration des inputs du model pour lequel le formulaire
t cr. Vous pouvez crez des inputs pour des models associs , ou des models arbitraires en passant
dans Modelname.fieldname comme premier paramtre :
echo $this->Form->input('Modelname.fieldname');
Si vous avez besoin de spcifier de multiples champs en utilisant le mme nom de champ, crant ainsi un
tableau qui peut tre sauver en un coup avec saveAll(), utilisez les conventions suivantes :
echo $this->Form->input('Modelname.0.fieldname');
echo $this->Form->input('Modelname.1.fieldname');
Affichera :
<input type="text" id="Modelname0Fieldname"
name="data[Modelname][0][fieldname]">
<input type="text" id="Modelname1Fieldname"
name="data[Modelname][1][fieldname]">
Le Helper Form utilise plusieurs suffixes de champ en interne pour la cration de champ input datetime. Si
vous utilisez des champs nomms year, month, day, hour, minute, or meridian et rencontrez des
problmes pour obtenir un input correct, vous pouvez dfinir le nom name de lattribut pour remplacer le
behavior par dfaut :
115
Affichera :
<div class="input file">
<label for="UserField">Field</label>
<input type="file" name="data[User][field]" value="" id="UserField" />
</div>
<div class="input email">
<label for="UserEmail">Email</label>
<input type="email" name="data[User][email]" value="" id="UserEmail" />
</div>
$options[div] Utilisez cette option pour dfinir les attributs de la div contentant linput. En utilisant une valeur chane configurera le nom de classe de la div. Un tableau cls/valeurs paramtrera les
attributs de la div. Alternativement, vous pouvez dfinir cet cl false pour dsactiver le rendu de la div.
Dfinir le nom de classe :
echo $this->Form->input('User.name', array(
'div' => 'class_name'
));
Affichera :
<div class="class_name">
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
116
Affichera :
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
$options[label] Dfinissez cette cl la chane que vous voudriez afficher dans le label qui
accompagne le input :
echo $this->Form->input('User.name', array(
'label' => "Alias de l'user"
));
Affichera :
<div class="input">
<label for="UserName">Alias de l'user</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
<div class="input">
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Dfinissez ceci dans un tableau pour fournir des options supplmentaires pour llment label. Si vous
faites cela, vous pouvez utiliser une cl text dans le tableau pour personnaliser le texte du label :
echo $this->Form->input('User.name', array(
'label' => array(
'class' => 'bidule',
'text' => 'le traducteur est fou hihaaarrrr!!!'
)
));
Affichera :
<div class="input">
<label for="UserName" class="bidule">le traducteur est fou hihaaarrrr!!!</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
117
$options[error] En utilisant cette cl vous permettra de transformer les messages de model par
dfaut et de les utiliser, par exemple, pour dfinir des messages i18n. (cf internationalisation). comporte
un nombre de sous-options qui contrles lenveloppe de llment (wrapping) . Le nom de classe de
llment envelopp, ainsi que les messages derreurs qui contiennent du HTML devront tre chapps.
Pour dsactiver le rendu des messages derreurs dfinissez la cl error false :
$this->Form->input('Model.field', array('error' => false));
Pour viter que le code HTML soit automatiquement chapp dans le rendu du message derreur, dfinissez la sous-option escape false :
$this->Form->input('Model.field', array(
'error' => array(
'attributes' => array('escape' => false)
)
));
Pour surcharger les messages derreurs du model utilisez un tableau avec les cls respectant les rgles de
validation :
$this->Form->input('Model.field', array(
'error' => array('tooShort' => __("Ceci n'est pas assez long"))
));
Comme vu ci-dessus vous pouvez dfinir les messages derreurs pour chacune des rgles de validation de
vos models. Vous pouvez de plus fournir des messages i18n pour vos formulaires.
Introduit dans la version 2.3 : Support pour loption errorMessage a t ajout dans 2.3
$options[before],
$options[between],
$options[separator],
et
$options[after]
Utilisez ces cls si vous avez besoin dinjecter quelques balises la sortie de la mthode input().
echo $this->Form->input('field', array(
'before' => '--avant--',
'after' => '--aprs--',
'between' => '--entre---'
));
Affichera :
<div class="input">
--avant-<label for="UserField">Field</label>
--entre--<input name="data[User][field]" type="text" value="" id="UserField" />
--aprs-</div>
Pour les input de type radio lattribut separator peut tre utilis pour injecter des balise pour sparer
input/label.
118
Affichera :
<div class="input">
--avant-<input name="data[User][field]" type="radio" value="1" id="UserField1" />
<label for="UserField1">1</label>
--sparateur-<input name="data[User][field]" type="radio" value="2" id="UserField2" />
<label for="UserField2">2</label>
--entre----aprs-</div>
Pour un lment de type date et datetime lattribut separator peut tre utilis pour modifier la chane
entre les select. Par dfaut -.
$options[format] Lordre du code HTML gnr par FormHelper est contrlable comme vous le
souhaitez. loption format supporte un tableau de chane dcrivant le model de page que vous voudriez
que llment suive. Les cls de tableau supportes sont :
array('before', 'input', 'between', 'label', 'after','error')
$options[inputDefaults] Sil vous semble rpter la mme option dans de multiples appels
input(), vous pouvez utiliser inputDefaults pour garder un code propre.
echo $this->Form->create('User', array(
'inputDefaults' => array(
'label' => false,
'div' => false
)
));
Tous les inputs crs a partir de ce point hriterons des valeurs dclares dans inputDefaults. Vous pouvez
redfinir defaultOptions en dclarant loption dans lappel de linput() :
// Pas de div, ni label
echo $this->Form->input('password');
// a un lment label
echo $this->Form->input('username', array('label' => 'Username'));
Si vous avez besoin de changer plus tard les valeurs par dfaut, vous pourrez utiliser
FormHelper::inputDefaults().
GET Form Inputs Quand vous utilisez FormHelper pour gnrer des inputs pour les formulaires GET,
les noms dinput seront automatiquement raccourcis pour que les noms soient plus lisibles pour les humains.
Par exemple :
En savoir plus sur les vues
119
Si vous voulez surcharger les attributs name gnrs, vous pouvez utiliser loption name :
// Cre le plus habituel <input name="data[User][email]" type="text" />
echo $this->Form->input('User.email', array('name' => 'data[User][email]'));
En plus de la mthode gnrique input(), le FormHelper des mthodes spcifiques pour gnrer
diffrents types dinputs. Ceci peut tre utilis pour gnrer juste un extrait de code input, et combin avec
dautres mthodes comme label() et error() pour gnrer des layouts (mise en page) compltements
personnalises.
Options Communes Beaucoup des diffrentes mthodes dinput supportent un jeu doptions communes.
Toutes ses options sont aussi supports par input(). Pour rduire les rptitions les options communes
partages par toutes les mthodes input sont :
$options[class] Vous pouvez dfinir le nom de classe pour un input :
echo $this->Form->input('title', array('class' => 'class-perso'));
$options[id] Dfinir cette cl pour forcer la valeur du DOM id pour cet input.
$options[default] Utilis pour dfinir une valeur par dfaut au champ input. La valeur est
utilise si les donnes passes au formulaire ne contiennent pas de valeur pour le champ (ou si aucune
donne nest transmise)
Exemple dutilisation :
echo $this->Form->input('ingredient', array('default' => 'Sucre'));
Exemple avec un champ slectionn (Taille Moyen sera slectionn par dfaut) :
$sizes = array('s' => 'Small', 'm' => 'Medium', 'l' => 'Large');
echo $this->Form->input('size', array('options' => $sizes, 'default' => 'm'));
Note : Vous ne pouvez pas utiliser default pour slectionner une chekbox - vous devez plutt dfinir
cette valeur dans $this->request->data dans votre controller, ou dfinir loption checked de
input true.
La valeur par dfaut des champs Date et datetime peut tre dfinie en utilisant la cl selected.
Attention lutilisation de false pour assigner une valeur par dfaut. Une valeur false est utilis pour
dsactiver/exclure les options dun champ, ainsi default => false ne dfinirait aucune valeur.
A la place, utilisez default => 0.
En plus des options ci-dessus, vous pouvez mixer nimporte quel attribut HTML que vous souhaitez utiliser.
Chacun des nom doptions non-special sera trait comme un attribut HTML, et appliqu a llment HTML
gnr.
120
Note : La cl selected pour les inputs de type date et datetime peuvent aussi tre des timestamps UNIX.
$options[empty] Est dfini true, pour forcer linput rester vide.
Quand pass une list select (liste de selection), ceci crera une option vide avec une valeur vide dans la
liste droulante. Si vous voulez une valeur vide avec un texte affich ou juste une option vide, passer une
chane pour vider :
echo $this->Form->input('field', array(
'options' => array(1, 2, 3, 4, 5),
'empty' => '(choisissez)'
));
Sortie:
.. code-block:: html
<div class="input">
<label for="UserField">Field</label>
<select name="data[User][field]" id="UserField">
<option value="">(choisissez)</option>
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
<option value="3">4</option>
<option value="4">5</option>
</select>
</div>
Note : Si vous avez besoin de dfinir la valeur par dfaut dun champ password vide, utilisez value=>
(deux fois simple cote) la place.
Une liste de paire de cl-valeur peut tre fournie pour un champ de type date ou datetime :
echo $this->Form->dateTime('Contact.date', 'DMY', '12',
array(
'empty' => array(
'day' => 'DAY', 'month' => 'MONTH', 'year' => 'YEAR',
'hour' => 'HOUR', 'minute' => 'MINUTE', 'meridian' => false
)
)
);
Affiche :
En savoir plus sur les vues
121
$options[hiddenField] Pour certain types d input (checkboxes, radios) un input cach est
cr ainsi la cl dans $this->request->data existera mme sans valeur spcifie :
<input type="hidden" name="data[Post][Published]" id="PostPublished_" value="0" />
<input type="checkbox" name="data[Post][Published]" value="1" id="PostPublished" />
Retournera :
<input type="checkbox" name="data[Post][Published]" value="1" id="PostPublished" />
Si vous voulez crer de multiples blocs dentrs regroups ensemble dans un formulaire, vous devriez
utiliser ce paramtre sur tous les inputs except le premier. Si le input cach est en place diffrents
endroits cest seulement le dernier groupe de valeur dinput qui sera sauvegard.
Dans cet exemple , seules les couleurs tertiaires seront passes, et les couleurs primaires seront rcrite :
<h2>Couleurs Primaires</h2>
<input type="hidden" name="data[Color][Color]" id="Couleurs_" value="0" />
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursRouges" />
<label for="CouleursRouges">Rouge</label>
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursBleus" />
<label for="CouleursBleus">Bleu</label>
122
En dsactivant le champ cach hiddenField dans le second groupe dinput empchera ce behavior.
Vous pouvez dfinir une valeur diffrente pour le champ cach autre que 0 comme N :
echo $this->Form->checkbox('published', array(
'value' => 'Y',
'hiddenField' => 'N',
));
Crera 4 options dans la select box minute. Une toute les 15 minutes.
$options[round] Peut tre dfini up ou down pour forcer larrondi dans quelque soit la direction. Par dfaut null qui arrondit la moiti suprieure selon interval.
Introduit dans la version 2.4.
lments de Formulaire-Mthodes spcifiques
Tous les elements sont crs dans un form pour le model User comme dans les exemples ci-dessous.
Pour cette raison, le code HTML gnr contiendra des attributs qui font rfrence au model User Ex :
name=data[User][username], id=UserUsername
123
Affichera :
<label for="UserName">Name</label>
<label for="UserName">Your username</label>
$options peut soit tre un tableau dattributs HTML, ou une chane qui sera utilise comme nom
de classe :
echo $this->Form->label('User.name', null, array('id' => 'user-label'));
echo $this->Form->label('User.name', 'Your username', 'highlight');
Affichera :
<label for="UserName" id="user-label">Name</label>
<label for="UserName" class="highlight">Your username</label>
Affichera :
<input name="data[User][username]" type="text" class="users" id="UserUsername" />
Affichera :
<input name="data[User][password]" value="" id="UserPassword" type="password">
Affichera :
<input name="data[User][id]" id="UserId" type="hidden">
124
Si le form est dit (qui est le tableau $this->request->data va contenir les informations
sauvegardes pour le model User), la valeur correspondant au champ id sera automatiquement
ajoute au HTML gnr. Exemple pour data[User][id] = 10 :
<input name="data[User][id]" id="UserId" type="hidden" value="10" />
Modifi dans la version 2.0 : Les champs cachs nenlvent plus la classe attribute. Cela signifie que
si il y a des erreurs de validation sur les champs cachs, le nom de classe error-field sera appliqu.
FormHelper::textarea(string $fieldName, array $options)
Cre un champ input textarea (zone de texte).
echo $this->Form->textarea('notes');
Affichera :
<textarea name="data[User][notes]" id="UserNotes"></textarea>
Si le form est dit (ainsi, le tableau $this->request->data va contenir les informations sauvegardes pour le model User), la valeur correspondant au champs notes sera automatiquement
ajoute au HTML gnr. Exemple :
<textarea name="data[User][notes]" id="UserNotes">
Ce texte va tre dit.
</textarea>
Note : Le type dinput textarea permet lattribut $options dchapper escape lequel
dtermine si oui ou non le contenu du textarea doit tre chapp. Par dfaut true.
echo $this->Form->textarea('notes', array('escape' => false);
// OU....
echo $this->Form->input('notes', array('type' => 'textarea', 'escape' => false);
Options
En plus de Options Communes, textarea() supporte quelques options spcifiques :
$options[rows], $options[cols] Ces deux cls spcifient le nombre de lignes et
de colonnes :
echo $this->Form->textarea('textarea', array('rows' => '5', 'cols' => '5'));
Affichera :
<textarea name="data[Form][textarea]" cols="5" rows="5" id="FormTextarea">
</textarea>
Affichera :
125
Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />
Affichera :
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />
Affichera :
<input
<input
<label
<input
<label
Si pour quelque raisons vous ne voulez pas du input cach, dfinissez $attributes[value]
une valeur slectionne ou le boolen false
Modifi dans la version 2.1 : Loption dattribut $attributes[disabled] a t ajoute dans
CakePHP 2.1.
FormHelper::select(string $fieldName, array $options, array $attributes)
Cre un menu de slection, rempli des lments compris dans $options, avec loption spcifie
par $attributes[value] sera montr comme slectionn par dfaut. Dfinir false la cl
empty dans la variable $attributes pour empcher loption empty par dfaut :
126
Affichera :
<select name="data[User][genre]" id="UserGenre">
<option value=""></option>
<option value="H">Homme</option>
<option value="F">Femme</option>
</select>
Linput de type select permet un attribut $option spcial appele escape qui accepte un
boolen et dtermine si il faut que lentit HTML encode le contenu des options slectionnes. Par
dfaut true :
$options = array('H' => 'Homme', 'F' => 'Femme');
echo $this->Form->select('genre', $options, array('escape' => false));
Affichera :
<select name="data[User][field]" id="UserField">
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
<option value="3">4</option>
<option value="4">5</option>
</select>
Les options peuvent aussi tre fournies comme des paires cl-valeur :
echo $this->Form->select('field', $options, array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2',
'Value 3' => 'Label 3'
));
Affichera :
<select name="data[User][field]" id="UserField">
<option value="Value 1">Label 1</option>
<option value="Value 2">Label 2</option>
<option value="Value 3">Label 3</option>
</select>
Si vous souhaitez gnrer un select avec des groupes optionnels, passez les donnes dans un format
hirarchique. Ceci fonctionnera avec les checkboxes multiples et les boutons radios galement, mais
au lieu des groupes optionnels enveloppez les lments dans des fieldsets :
127
$options = array(
'Group 1' => array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
),
'Group 2' => array(
'Value 3' => 'Label 3'
)
);
echo $this->Form->select('field', $options);
Affichera :
<select name="data[User][field]" id="UserField">
<optgroup label="Group 1">
<option value="Value 1">Label 1</option>
<option value="Value 2">Label 2</option>
</optgroup>
<optgroup label="Group 2">
<option value="Value 3">Label 3</option>
</optgroup>
</select>
$attributes[multiple] Si multiple a t dfini true pour un input select, celui ci autorisera les slections multiples :
echo $this->Form->select('Model.field', $options, array('multiple' => true));
Vous pouvez galement dfinir checkbox multiple pour afficher une liste de check boxes relis :
$options = array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
);
echo $this->Form->select('Model.field', $options, array(
'multiple' => 'checkbox'
));
Affichera :
$options = array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
);
echo $this->Form->select('Model.field', $options, array(
'multiple' => 'checkbox',
'disabled' => array('Value 1')
));
Output :
<div class="input select">
<label for="ModelField">Field</label>
<input name="data[Model][field]" value="" id="ModelField"
type="hidden">
<div class="checkbox">
<input name="data[Model][field][]" disabled="disabled"
value="Value 1" id="ModelField1" type="checkbox">
<label for="ModelField1">Label 1</label>
</div>
<div class="checkbox">
<input name="data[Model][field][]" value="Value 2"
id="ModelField2" type="checkbox">
<label for="ModelField2">Label 2</label>
</div>
</div>
Modifi dans la version 2.3 : Le support pour les tableaux dans $attributes[disabled] a
t ajoute dans 2.3.
FormHelper::file(string $fieldName, array $options)
Pour ajouter un champ upload un formulaire, vous devez vous assurer que le enctype du formulaire
est dfinit a multipart/form-data, donc commenons avec une fonction create comme ci-dessous :
echo $this->Form->create('Document', array(
'enctype' => 'multipart/form-data'
));
// OU
echo $this->Form->create('Document', array('type' => 'file'));
Ensuite ajoutons lune ou lautre des deux lignes dans le fichier de vue de votre formulaire :
echo $this->Form->input('Document.submittedfile', array(
'between' => '<br />',
'type' => 'file'
));
// OU
echo $this->Form->file('Document.submittedfile');
En raisons des limitations du code HTML lui mme, il nest pas possible de placer des valeurs par
dfauts dans les champs inputs de type file. A chacune des fois ou le formulaire sera affich, la valeur
sera vide.
129
Lors de la soumission, le champ file fournit un tableau tendu de donnes au script recevant les
donnes de formulaire.
Pour lexemple ci-dessus, les valeurs dans le tableau de donnes soumis devraient tre organises
comme la suite, si CakePHP t install sur un server Windows .tmp_name aura un chemin
diffrent dans un environnement Unix :
$this->request->data['Document']['submittedfile'] = array(
'name' => conference_schedule.pdf,
'type' => application/pdf,
'tmp_name' => C:/WINDOWS/TEMP/php1EE.tmp,
'error' => 0,
'size' => 41737,
);
Ce tableau est gnr par PHP lui-mme, pour plus de dtails sur la faon dont PHP gre les donnes
passes a travers les champs files. lire la section file uploads du manuel de PHP 2 .
Validation des Uploads Ci dessous lexemple dune mthode de validation dfinit dans votre model pour
valider si un fichier t uploader avec succs :
public function isUploadedFile($params) {
$val = array_shift($params);
if ((isset($val['error']) && $val['error'] == 0) ||
(!empty( $val['tmp_name']) && $val['tmp_name'] != 'none')
) {
return is_uploaded_file($val['tmp_name']);
}
return false;
}
Affichera :
<form enctype="multipart/form-data" method="post" action="/users/add">
<input name="data[User][avatar]" value="" id="UserAvatar" type="file">
130
Il est encapsul entre des div par dfaut ; vous pouvez empcher cela en dclarant
$options[div] = false :
echo $this->Form->submit();
Affichera :
<div class="submit"><input value="Submit" type="submit"></div>
Vous pouvez aussi passer une URL relative ou absolue vers une image pour le paramtre caption au
lieu dun caption text :
echo $this->Form->submit('ok.png');
Affichera :
<div class="submit"><input type="image" src="/img/ok.png"></div>
$this->Form->button('Un bouton');
$this->Form->button('Un autre Bouton', array('type' => 'button'));
$this->Form->button('Initialise le Formulaire', array('type' => 'reset'));
$this->Form->button('Soumettre le Formulaire', array('type' => 'submit'));
Affichera :
<button
<button
<button
<button
type="submit">Un bouton</button>
type="button">Un autre Bouton</button>
type="reset">Initialise le Formulaire</button>
type="submit">Soumettre le Formulaire</button>
Le input de type button supporte loption escape qui accepte un boolen et dtermine si oui ou
non lentit HTML encode le $title du bouton. Par dfaut false :
echo $this->Form->button('Submit Form', array('type' => 'submit', 'escape' => true));
131
Affichera :
<select
<option
<option
<option
<option
<option
<option
<option
<option
name="data[User][purchased][annee]" id="UserPurchasedYear">
value=""></option>
value="2009">2009</option>
value="2008">2008</option>
value="2007">2007</option>
value="2006">2006</option>
value="2005">2005</option>
value="2004">2004</option>
value="2003">2003</option>
<option value="2002">2002</option>
<option value="2001">2001</option>
132
<option value="2000">2000</option>
</select>
Affichera :
<select name="data[User][mob][month]" id="UserMobMonth">
<option value=""></option>
<option value="01">January</option>
<option value="02">February</option>
<option value="03">March</option>
<option value="04">April</option>
<option value="05">May</option>
<option value="06">June</option>
<option value="07">July</option>
<option value="08">August</option>
<option value="09">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
Vous pouvez passer votre propre tableau des mois utiliser en paramtrant lattribut monthNames,
ou avoir les mois affichs comme des nombres en passant false. (Note : les mois par dfaut sont
internationaliss et peuvent tre traduits en utilisant la localisation) :
echo $this->Form->month('mob', array('monthNames' => false));
Affichera :
<select name="data[User][created][day]" id="UserCreatedDay">
<option value=""></option>
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
...
<option value="31">31</option>
</select>
133
Tous les champs crs partir ce point de retour vont hriter des options dclares dans inputDefaults. Vous
pouvez surcharger les options par dfaut en dclarant loption dans lappel input() :
134
SecurityComponent offre plusieurs fonctionnalits qui rendent vos formulaires plus sres et plus
scuriss. En incluant simplement le component scurit SecurityComponent dans votre controller,
vous bnficierez automatiquement de CSRF (Cross-site request forgery) et des fonctionnalits pour viter
la falsification.
Quand vous utilisez le SecurityComponent (component de scurit), vous devez toujours fermer vos formulaires en utilisant FormHelper::end(). Ceci assurera que les inputs jeton spciaux _Token seront
gnrs.
FormHelper::unlockField($name)
Dverrouille un champ en le rendant exempt du hachage (hashing) du SecurityComponent. Ceci
permet galement au champ dtre manipul par Javascript. Le paramtre $name devra tre le nom
dentit de linput :
$this->Form->unlockField('User.id');
135
Les champs cachs nenlvent plus les attributs de classe. Cela signifie que si il y a des erreurs de validation
sur les champs cachs le nom de classe error-field sera appliqu.
HTMLHelper
class HtmlHelper(View $view, array $settings = array())
Le rle du Helper Html dans CakePHP est de fabriquer les options du HTML plus facilement, plus rapidement. Lutilisation de cet Helper permettra votre application dtre plus lgre bien ancre et plus flexible
de lendroit ou il est plac en relation avec la racine de votre domaine.
De nombreuses mthodes du Helper Html contiennent un paramtre $htmlAttributes, qui vous permet dinsrer un attribut supplmentaire sur vos tags. Voici quelques exemples sur la faon dutiliser les
paramtres $htmlAttributes :
Attributs souhaits: <tag class="someClass" />
Paramtre du tableau: array('class' => 'someClass')
Attributs souhaits: <tag name="foo" value="bar" />
Paramtre du tableau: array('name' => 'foo', 'value' => 'bar')
Note : Le Helper html est disponible dans toutes les vues par dfaut. Si vous recevez une erreur vous
informant quil nest pas disponible, cest habituellement d a son nom qui a t oubli de la configuration
manuelle de la variable $helpers du controller.
La tche la plus importante que le Helper Html accomplit est la cration dun balisage bien form. Nayez
pas peur de lutiliser souvent - vous pouvez cacher les vues dans cakePHP pour conomiser du temps CPU
quand les vues sont rendues et dlivres. Cette section couvrira les mthodes du Helper Html et comment
les utiliser.
HtmlHelper::charset($charset=null)
Paramtres
$charset (string) Jeu de caractre dsir. Sil est null, la valeur de
App.encoding sera utilise.
Utilis pour crer une balise meta spcifiant le jeu de caractres du document. UTF-8 par dfaut.
Exemple dutilisation :
echo $this->Html->charset();
Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Sinon :
echo $this->Html->charset('ISO-8859-1');
136
Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
Affichera :
<link rel="stylesheet" type="text/css" href="/css/forms.css" />
Le premier paramtre peut tre un tableau pour inclure des fichiers multiples.
echo $this->Html->css(array('forms', 'tables', 'menu'));
Affichera :
<link rel="stylesheet" type="text/css" href="/css/forms.css" />
<link rel="stylesheet" type="text/css" href="/css/tables.css" />
<link rel="stylesheet" type="text/css" href="/css/menu.css" />
Vous pouvez inclure un fichier CSS depuis un plugin charg en utilisant syntaxe de plugin. Pour
inclure app/Plugin/DebugKit/webroot/css/toolbar.css, vous pouvez utiliser ce qui
suit :
echo $this->Html->css('DebugKit.toolbar.css');
Si vous voulez inclure un fichier CSS qui partage un nom avec un plugin charg vous pouvez faire ce qui suit. Par exemple vous avez un plugin Blog, et souhaitez inclure galement
app/webroot/css/Blog.common.css :
.. versionchanged:: 2.4
137
Paramtres
$type (string) Le type de balise meta dsir.
$url (mixed) LURL de la balise meta, soit une chane ou un tableau de routing.
$options (array) Un tableau d attributs HTML.
Cette mthode est pratique pour faire des liens vers des ressources externes comme RSS/Atom feeds
et les favicons. Comme avec css(), vous pouvez spcifier si vous voulez lapparition de la balise en
ligne ou lajouter au bloc meta en dfinissant la cl inline false dans les paramtres $options, ex.
- array(inline => false).
Si vous dfinissez lattribut type en utilisant le paramtre $options, CakePHP contient certains raccourcis :
type valeur rsultante
html
text/html
rss
application/rss+xml
atom application/atom+xml
icon
image/x-icon
<?php
echo $this->Html->meta(
'favicon.ico',
'/favicon.ico',
array('type' => 'icon')
);
?>
// Output (line breaks added)
<link
href="http://example.com/favicon.ico"
title="favicon.ico" type="image/x-icon"
rel="alternate"
/>
<?php
echo $this->Html->meta(
'Comments',
'/comments/index.rss',
array('type' => 'rss')
);
?>
// Output (line breaks added)
<link
href="http://example.com/comments/index.rss"
title="Comments"
type="application/rss+xml"
rel="alternate"
/>
Cette mthode peut aussi tre utilise pour ajouter les balises de mots cls et les descriptions. Exemple :
<?php
echo $this->Html->meta(
'keywords',
'enter any meta keyword here'
);
138
?>
// Sortie
<meta name="keywords" content="enter any meta keyword here" />
<?php
echo $this->Html->meta(
'description',
'enter any meta description here'
);
?>
// Sortie
<meta name="description" content="enter any meta description here" />
Si vous voulez ajouter une balise personnalise alors le premier paramtre devra tre un tableau. Pour
ressortir une balise de robots noindex, utilisez le code suivant :
echo $this->Html->meta(array('name' => 'robots', 'content' => 'noindex'));
Modifi dans la version 2.1 : La valeur par dfaut de doctype est HTML5 avec la version 2.1.
HtmlHelper::style(array $data, boolean $oneline = true)
Paramtres
$data (array) Un ensemble de cl => valeurs avec des proprits CSS.
139
Affichera
background:#633; border-bottom:1px solid #000; padding:10px;
Affichera :
<img src="/img/cake_logo.png" alt="CakePHP" />
Pour crer un lien dimage, spcifiez le lien de destination en utilisant loption url dans
$htmlAttributes.
echo $this->Html->image("recipes/6.jpg", array(
"alt" => "Brownies",
'url' => array('controller' => 'recipes', 'action' => 'view', 6)
));
Affichera :
<a href="/recipes/view/6">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Si vous crez des images dans des mails, ou voulez des chemins absolus pour les images,
vous pouvez utiliser loption fullBase :
echo $this->Html->image("logo.png", array('fullBase' => true));
Affichera :
<img src="http://example.com/img/logo.jpg" alt="" />
Vous pouvez inclure des fichiers images depuis un plugin charg en utilisant la syntaxe
de plugin. Pour inclure app/Plugin/DebugKit/webroot/img/icon.png, vous
pouvez faire cela :
echo $this->Html->image('DebugKit.icon.png');
140
Si vous voulez inclure un fichier image qui partage un nom avec un plugin charg vous pouvez faire ce qui suit. Par exemple si vous avez in plugin Blog, et voulez inclure galement
app/webroot/js/Blog.icon.png :
echo $this->Html->image('Blog.icon.png', array('plugin' => false));
Affichera :
<a href="/pages/home" class="button" target="_blank">Enter</a>
Affichera :
<a href="http://www.yourdomain.com/dashboards/index">Dashboard</a>
Affichera :
141
Affichera :
<a href="/images/view/1?height=400&width=500">View image</a>
Quand il y a utilisation de paramtres nomms, utilisez la syntaxe en tableau et incluez les noms
pour TOUS les paramtres dans lURL. En utilisant la syntaxe en chane pour les paramtres (par ex
recipes/view/6/comments :false va rsulter ce que les caractres seront chapps du HTML et le
lien ne fonctionnera pas comme souhait.
<?php
echo $this->Html->link(
$this->Html->image("recipes/6.jpg", array("alt" => "Brownies")),
array(
'controller' => 'recipes',
'action' => 'view',
'id' => 6,
'comments' => false
)
);
Affichera :
<a href="/recipes/view/id:6/comments:false">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Les caractres spciaux HTML de $title seront convertis en entits HTML. Pour dsactiver cette
conversion, dfinissez loption escape false dans le tableau $options :
<?php
echo $this->Html->link(
$this->Html->image("recipes/6.jpg", array("alt" => "Brownies")),
"recipes/view/6",
array('escape' => false)
);
Affichera :
<a href="/recipes/view/6">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Dfinir escape false va aussi dsactiver lchappement des attributs du lien. Puisque depuis 2.4,
vous pouvez utiliser loption escapeTitle pour juste dsactiver lchappement du titre et pas des
attributs.
142
<?php
echo $this->Html->link(
$this->Html->image('recipes/6.jpg', array('alt' => 'Brownies')),
'recipes/view/6',
array('escapeTitle' => false, 'title' => 'hi "howdy"')
);
Affichera :
<a href="/recipes/view/6" title="hi "howdy"">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
143
'video.mp4',
array(
'src' => 'video.ogg',
'type' => "video/ogg; codecs='theora, vorbis'"
)
),
array('autoplay')
); ?>
// Sortie
<video autoplay="autoplay">
<source src="/files/video.mp4" type="video/mp4"/>
<source src="/files/video.ogg" type="video/ogg;
codecs='theora, vorbis'"/>
</video>
< ?php echo $this->Html->tag(span, Bonjour le Monde, array(class => welcome)) ; ?>
// Affichera <span class=welcome>Bonjour le Monde</span>
// Pas de texte spcifi. < ?php echo $this->Html->tag(span, null, array(class => welcome)) ; ?>
// Affichera <span class=welcome>
Note :
Le texte nest pas chapp par dfaut mais vous pouvez utiliser
$htmlOptions[escape] = true pour chapper votre texte. Ceci remplace un quatrime paramtre boolean $escape = false qui tait prsent dans les prcdentes versions.
HtmlHelper::div(string $class, string $text, array $options)
Paramtres
$class (string) Le nom de classe de la div.
$text (string) Le contenu de la div.
$options (array) Un tableau dattributs attributs html.
Utilis pour les sections de balisage envelopps dans des div. Le premier paramtre spcifie une
classe CSS, et le second est utilis pour fournir le texte envelopper par les balises div. Si le dernier
paramtre t dfini true, $text sera affich en HTML-chapp.
Si aucun texte nest spcifi, seulement une balise div douverture est retourne. :
144
<?php
echo $this->Html->div('error', 'Entrez votre numro de carte bleue S.V.P');
?>
// Affichera
<div class="error">Entrez votre numro de carte bleue S.V.P</div>
Affichera :
<script type="text/javascript" href="/js/scripts.js"></script>
Vous pouvez lier des fichiers avec des chemins absolus tant quils ne se trouvent pas dans
app/webroot/js :
145
echo $this->Html->script('/autrerep/fichier_script');
Affichera :
<script type="text/javascript" href="http://code.jquery.com/jquery.min.js"></script>
Le premier paramtre peut tre un tableau pour inclure des fichiers multiples.
echo $this->Html->script(array('jquery', 'wysiwyg', 'scripts'));
Affichera :
<script type="text/javascript" href="/js/jquery.js"></script>
<script type="text/javascript" href="/js/wysiwyg.js"></script>
<script type="text/javascript" href="/js/scripts.js"></script>
Vous pouvez insrer dans la balise script un bloc spcifique en utilisant loption block.
echo $this->Html->script('wysiwyg', array('block' => 'scriptBottom'));
Dans votre layout, vous pouvez ressortir toutes les balises script ajoutes dans scriptBottom :
echo $this->fetch('scriptBottom');
Vous pouvez inclure des fichiers de script depuis un plugin en utilisant la syntaxe syntaxe de plugin.
Pour inclure app/Plugin/DebugKit/webroot/js/toolbar.js vous devriez faire cela :
echo $this->Html->script('DebugKit.toolbar.js');
Si vous voulez inclure un fichier de script qui partage un nom de fichier avec un plugin charg
vous pouvez faire cela. Par exemple si vous avez Un plugin Blog, et voulez inclure galement
app/webroot/js/Blog.plugins.js, vous devriez :
echo $this->Html->script('Blog.plugins.js', array('plugin' => false));
Modifi dans la version 2.1 : Loption block a t ajout. Le support de la syntaxe syntaxe de plugin
a t ajout.
HtmlHelper::scriptBlock($code, $options = array())
Paramtres
$code (string) Le code placer dans la balise script.
$options (array) Un tableau dattributs attributs html.
Gnre un bloc de code contenant des options $options[inline] dfinies de $code
mettre false pour voir le bloc de script apparatre dans le bloc de script de
la vue. Dautres options dfinies seront ajoutes comme attributs dans les balises de
script. $this->Html->scriptBlock(stuff, array(defer => true)); crera
une balise script avec lattribut defer="defer".
HtmlHelper::scriptStart($options = array())
Paramtres
146
HtmlHelper::nestedList(array $list, array $options = array(), array $itemOptions = array(), string $tag = ul)
Paramtres
$list (array) Ensemble dlments lister.
$options (array) Attributs HTML supplmentaires des balises de listes (ol/ul) ou
si ul/ol utilise cela comme une balise.
$itemOptions (array) Attributs additionnels des balises de listes item(LI).
$tag (string) Type de balise liste utiliser (ol/ul).
Fabrique une liste imbrique (UL/OL) dans un tableau associatif :
$list = array(
'Languages' => array(
'English' => array(
'American',
'Canadian',
'British',
),
'Spanish',
'German',
)
);
echo $this->Html->nestedList($list);
Sortie :
// Affichera (sans les espaces blancs)
<ul>
<li>Languages
<ul>
<li>English
<ul>
<li>American</li>
<li>Canadian</li>
<li>British</li>
</ul>
147
</li>
<li>Spanish</li>
<li>German</li>
</ul>
</li>
</ul>
// Affichera
<tr>
<th>Date</th>
<th>Title</th>
<th>Active</th>
</tr>
echo $this->Html->tableHeaders(
array('Date','Title','Active'),
array('class' => 'status'),
array('class' => 'product_table')
);
Sortie :
<tr class="status">
<th class="product_table">Date</th>
<th class="product_table">Title</th>
<th class="product_table">Active</th>
</tr>
Modifi dans la version 2.2 : tableHeaders() accepte maintenant les attributs par cellule, regardez ci-dessous.
Depuis 2.2 vous pouvez dfinir des attributs par colonne, ceux-ci sont utiliss la place de ceux par
dfaut dans $thOptions :
echo $this->Html->tableHeaders(array(
'id',
array('Name' => array('class' => 'highlight')),
array('Date' => array('class' => 'sortable'))
));
Sortie :
148
<tr>
<th>id</th>
<th class="highlight">Name</th>
<th class="sortable">Date</th>
</tr>
Sortie :
<tr><td>Jul 7th, 2007</td><td>Best Brownies</td><td>Yes</td></tr>
<tr><td>Jun 21st, 2007</td><td>Smart Cookies</td><td>Yes</td></tr>
<tr><td>Aug 1st, 2006</td><td>Anti-Java Cake</td><td>No</td></tr>
echo $this->Html->tableCells(array(
array('Jul 7th, 2007', array('Best Brownies', array('class' => 'highlight')) , 'Ye
array('Jun 21st, 2007', 'Smart Cookies', 'Yes'),
array('Aug 1st, 2006', 'Anti-Java Cake', array('No', array('id' => 'special'))),
));
// Sortie
<tr><td>Jul 7th, 2007</td><td class="highlight">Best Brownies</td><td>Yes</td></tr>
<tr><td>Jun 21st, 2007</td><td>Smart Cookies</td><td>Yes</td></tr>
<tr><td>Aug 1st, 2006</td><td>Anti-Java Cake</td><td id="special">No</td></tr>
echo $this->Html->tableCells(
array(
array('Red', 'Apple'),
array('Orange', 'Orange'),
array('Yellow', 'Banana'),
),
array('class' => 'darker')
);
149
Output :
<tr class="darker"><td>Red</td><td>Apple</td></tr>
<tr><td>Orange</td><td>Orange</td></tr>
<tr class="darker"><td>Yellow</td><td>Banana</td></tr>
150
Output :
<form action="http://example.com" method="post" class="myform">
Vous
pouvez
alors
charger
ces
balises
$this->Html->loadConfig(html5_tags);.
dfinis
en
appelant
3. http ://api.cakephp.org/2.4/class-Router.html#_url
151
Loption $startText peut aussi accepter un tableau. Cela donne plus de contrle travers le premier lien gnr :
echo $this->Html->getCrumbs(' > ', array(
'text' => $this->Html->image('home.png'),
'url' => array('controller' => 'pages', 'action' => 'display', 'home'),
'escape' => false
));
Une cl qui nest pas text ou url sera passe link() comme paramtre $options.
Modifi dans la version 2.1 : Le paramtre $startText accepte maintenant un tableau.
HtmlHelper::addCrumb(string $name, string $link = null, mixed $options = null)
Maintenant, dans votre vue vous allez devoir ajouter ce qui suit pour dmarrer le fil dAriane sur
chacune de vos pages.
$this->Html->addCrumb('Users', '/users');
$this->Html->addCrumb('Add User', array('controller' => 'users', 'action' => 'add'));
Ceci ajoutera la sortie Home > Users > Add User dans votre layout o le fil dAriane a t ajout.
HtmlHelper::getCrumbList(array $options = array(), mixed $startText)
Paramtres
$options (array) Un tableau d attributs HTML pour les elements contenant
<ul>. Peut aussi contenir les options separator, firstClass, lastClass et escape.
$startText (string|array) Le texte ou lelment qui prcde ul.
Retourne le fil dAriane comme une liste (x)html.
Cette mthode utilise HtmlHelper::tag() pour gnrer la liste et ces lments. Fonctionne de
la mme manire que getCrumbs(), il utilise toutes les options que chacun des fils a ajout. Vous
pouvez utiliser le paramtre $startText pour fournir le premier lien de fil. Cest utile quand vous
voulez inclure un lien racine. Cette option fonctionne de la mme faon que loption $startText
pour getCrumbs().
Modifi dans la version 2.1 : Le paramtre $startText a t ajout.
Modifi dans la version 2.3 : Les options separator, firstClass et lastClass ont t ajoutes.
Modifi dans la version 2.5 : Loption escape a t ajoute.
JSHelper
class JsHelper(View $view, array $settings = array())
152
Avertissement : JsHelper est actuellement dprci et compltement retir de 3.x. Nous recommandons
dutiliser du JavaScript classique et de directement intragir avec les librairies si possible.
Depuis le dbut le support de CakePHP pour Javascript a t orient vers Prototype/Scriptaculous (librairie
JavaScript). Tandis que nous continuons de penser quil sagit dexcellentes bibliothques Javascript, il a
t demand la communaut de supporter dautres librairies. Plutt que denlever Prototype en faveur
dune autre librairie JavaScript. Nous avons cr un adaptateur fonctionnant sur le principe dun Helper
et avons inclu 3 des librairies les plus demandes. Prototype/scriptaculous, Mootools/Mootools-more, et
jQuery/jQueryUI. Bien que lAPI nest pas aussi vaste que le Helper Ajax, nous pensons que la solution
base sur ladaptateur permet une solution plus extensible offrant aux dveloppeurs la puissance et la flexibilit dont ils ont besoin pour rpondre leurs besoins spcifiques.
Les moteurs Javascript forment lpine dorsale du nouveau Helper Js. Un moteur JavaScript traduit un
lment Javascript abstrait dans un code JavaScript concret spcifique la librairie en cours dutilisation.
De plus ils crent un systme extensible utiliser pour les autres.
Utilisation dun moteur Javascript spcifique
Avant tout, tlchargez votre librairie JavaScript prfre et placez la dans app/webroot/js.
Puis, vous devez inclure la librairie dans votre page. Pour linclure dans toutes les pages, ajoutez cette ligne
dans la section <head> de app/View/Layouts/default.ctp :
echo $this->Html->script('jquery'); // Inclut la librairie Jquery
Remplacez jquery par le nom de votre fichier de librairie (.js sera ajout au nom).
Par dfaut les scripts sont mis en cache, et vous devez explicitement imprimer le cache. Pour faire cela la
fin de chacune des pages, incluez cette ligne juste avant la balise de fin de </body>
echo $this->Js->writeBuffer(); // crit les scripts en mmoire cache
Attention : Vous devez inclure la librairie dans votre page et afficher le cache pour que le helper fonctionne.
La selection du moteur Javascript est dclare quand vous incluez le helper dans votre controller
public $helpers = array('Js' => array('Jquery'));
La partie ci-dessus utilise le moteur Jquery dans les instances du Helper Js dans vos vues. Si vous ne dclarez
pas un moteur spcifique, le moteur Jquery sera utilis par dfaut. Comme il est mentionn ci-dessus, il y a
trois moteurs implments dans le noyau, mais nous encourageons la communaut tendre la compatibilit
des librairies.
Utilisation de jQuery avec dautres librairies La librairie jQuery, et virtuellement tous ses plugins sont
limits au sein de lespace jQuery. Comme rgle gnrale, les objets globaux sont stocks dans lespace JQuery, ainsi vous ne devriez pas avoir de clash entre Jquery et dautre librairies (comme Prototype,
MooTools, ou YUI).
153
Ceci dit, il y a une mise en garde : Par dfaut, jQuery utilise $ comme raccourci de jQuery
Pour redfinir le raccourci $, utilisez la variable jQueryObject :
$this->Js->JqueryEngine->jQueryObject = '$j';
echo $this->Html->scriptBlock(
'var $j = jQuery.noConflict();',
array('inline' => false)
);
// Demande jQuery de se placer dans un mode noconflict
Utilisation du Helper Js dans des helpers personnaliss Dclarez le Helper Js dans le tableau
$helpers de votre Helper personnalis :
public $helpers = array('Js');
Note : Il nest pas possible de dclarer le moteur JavaScript dans un Helper personnalis. Ceci naurait
aucun effet.
Si vous tes prt utiliser un moteur JavaScript autre que celui par dfaut, fates le paramtrage du Helper
dans votre controller comme ceci :
public $helpers = array(
'Js' => array('Prototype'),
'CustomHelper'
);
Les helpers de moteur Javascript suivent les conventions normales des helper, avec quelques restrictions supplmentaires. Ils doivent avoir le suffixe Engine. DojoHelper nest pas bon, DojoEngineHelper est
correct. De plus ils doivent tendre JsBaseEngineHelper afin de tirer parti du meilleur de la nouvelle
API.
Utilisation du moteur Javascript
Le JsHelper fournit quelques mthodes, et agit comme une faade pour le moteur helper. Vous ne devriez
pas accder au moteur helper except dans de rares occasions. Utilisez les fonctionnalits de faade du
Helper Js vous permet de tirer parti de la mise en mmoire tampon et de la mthode caractristique de
chanage intgr ; (le chanage de mthode ne fonctionne que dans PHP5).
154
Par dfaut le Helper Js bufferise presque tous les codes du script gnrs, ce qui vous permet de rcuprer
les scripts partout dans la vue, les lments et les mises en page, et de les ressortir un endroit. La
Rcupration des scripts bufferiss est ralis avec $this->Js->writeBuffer(); ceci retournera
le contenu du buffer dans une balise script. Vous pouvez dsactiver le buffering gnralis avec la proprit $bufferScripts ou en dfinissant buffer => false dans les mthodes qui prennent des
$options.
tant donn que la plupart des mthodes en Javascript commencent avec une slection dlments dans le
DOM, $this->Js->get() retourne un $this, vous permettent denchaner les mthodes en utilisant la
selection. Le chanage de mthode vous permet dcrire moins, et de rendre votre code plus expressif .
$this->Js->get('#foo')->event('click', $eventCode);
Est un exemple de chanage de mthode. Le chanage de mthode nest pas possible dans PHP4 et lexemple
ci-dessus devrait tre crit comme :
$this->Js->get('#foo');
$this->Js->event('click', $eventCode);
Options communes Dans le but de simplifier le dveloppement et comme les librairies JavaScript peuvent
changer, un ensemble courant doptions est pris en charge par JsHelper, ces options courantes seront
mappes en dehors des options spcifiques de la librairies en interne. Si vous ne prvoyez pas la commutation
des librairies, chaque librairie supporte toutes les fonctions de callback natives et les options.
Enveloppement de Callback Par dfaut, toutes les options de callback sont enveloppes dans une
fonction anonyme avec les bons arguments. Vous pouvez dsactiver ce comportement en fournissant
wrapCallbacks = false dans votre tableau doptions.
Travailler avec des scripts bufferiss Un inconvnient la prcdente implmentation des fonctionnalits de type dAJAX tait la dispersion des balises de script partout dans le document , et limpossibilit
de bufferiser les scripts ajouts par les lments dans la mise en page. Le nouveau Helper Js si il est utilis
correctement vite ces deux questions. Il est recommand de placer $this->Js->writeBuffer()
la fin du fichier layout au dessus la balise </body>. Ceci permettra tous les scripts gnrs dans les
lments du layout dtre ressortis (output) un endroit. Il doit tre not que les scripts bufferiss sont grs
sparment des scripts de fichiers inclus.
JsHelper::writeBuffer($options = array())
crit tous le codes Javascript gnrs jusquici dans un bloc de code ou les met en mmoire cache dans un
fichier et retourne un script li.
Options
inline - Dfini true pour avoir la sortie des scripts dans un bloc de script inline. si cache est aussi
true, une balise de lien de script sera gnre (par dfaut true)
cache - Dfini true pour avoir les scripts dans un fichier de la mmoire cache et sy reli (false par
dfaut)
clear - Dfini false pour viter au fichier de cache dtre effac (true par dfaut)
onDomReady - enveloppe les scripts en mmoire cache dans un evnement domready (par dfaut true)
155
safe - si un block inline est gnr il sera envelopp dans < ![CDATA[ ... ]]> (true par dfaut)
La cration dun fichier de cache avec writeBuffer() ncessite que webroot/js soit accessible en
criture et permette au navigateur de placer dans le cache les ressources de script gnr pour la page.
JsHelper::buffer($content)
Ajoute $content au buffer de script interne.
JsHelper::getBuffer($clear = true)
Rcupre le contenu du buffer courant. Passe false pour ne pas effacer le buffer en mme temps.
Bufferiser des mthodes qui ne sont normalement pas bufferise
Quelques mthodes dans le Helper sont bufferise par dfaut. Le moteur bufferise les mthodes suivantes
par dfaut :
event
sortable
drag
drop
slider
De plus vous pouvez forcer une autre mthode du Helper Js utiliser la mise en mmoire cache. En ajoutant
un boolen la fin des arguments vous pouvez forcer dautres mthodes daller en mmoire cache. Par
exemple la mthode each() qui nest normalement pas bufferise :
$this->Js->each('alert("sapristi!");', true);
Ce qui est ci-dessus va forcer la mthode each() utiliser le buffer. En revanche si vous souhaitez quune
mthode bufferise ne bufferise plus, vous pouvez passer un false comme le dernier argument :
$this->Js->event('click', 'alert("sapristi!");', false);
Ceci forcera la fonction event qui est normalement mis en mmoire cache retourner son rsultat.
Dautres Mthodes
Les moteurs Javascript du noyau fournissent les mmes fonctionnalits dfinies a travers les autres librairies,
il y a aussi un sous-ensemble doptions communes qui sont traduites dans les options spcifiques des librairies. Tout cela pour fournir au dveloppeurs finaux une Api unifie autant que possible. La liste suivante
de mthodes est supporte par tous les moteurs inclus dans le noyau CakePHP. Chaque fois que vous voyez
une liste spare pour les Options et les Event Options Les deux ensembles de paramtres sont fournis dans le tableau $options pour la mthode.
JsHelper::object($data, $options = array())
Srialise $data vers JSON. Cette mthode est un proxy pour json_encode() avec quelques
fonctionnalits supplmentaires ajoute avec le paramtre $options.
Options :
prefix - Chane ajoute en dbut des donnes retournes.
postfix - Chane ajoute aux donne retourne.
Exemple dutilisation :
156
$json = $this->Js->object($data);
JsHelper::sortable($options = array())
Sortable gnre un extrait de code pour fabriquer un ensemble dlments (souvent une liste) drag and
drop triable.
Les options normalises sont :
Options
containment - Conteneur de laction de dplacement.
handle - Selecteur de llment. Seul cet lment commencera laction de tri.
revert - Sil faut ou pas utiliser un effet pour dplacer llment triable dans sa position finale.
opacity - Opacit de lespace rserv.
distance - Distance a laquelle llment triable doit tre dragg avant que le tri nopre.
Event Options
start - vnement lanc quand le tri commence.
sort - vnement lanc quand le tri est en cours.
complete - vnement lanc quand le tri est termin.
Dautres options sont supportes par chacune des librairies Javascript, et vous pouvez obtenir dans
leurs documentation respective des informations plus dtailles sur les options et les paramtres.
Exemple dutilisation :
$this->Js->get('#ma-liste');
$this->Js->sortable(array(
'distance' => 5,
'containment' => 'parent',
'start' => 'onStart',
'complete' => 'onStop',
'sort' => 'onSort',
'wrapCallbacks' => false
));
En imaginant que vous tiez en train dutiliser le moteur Jquery, vous devriez avoir le code suivant
dans votre block Javascript gnr.
$("#myList").sortable({
containment:"parent",
distance:5,
sort:onSort,
start:onStart,
stop:onStop
});
157
JsHelper::get($selector)
Dfinit la slection interne dans un slecteur CSS. La slection active est utilise dans les oprations
ultrieures jusqu ce quune nouvelle soit faite.
$this->Js->get('#element');
Le JsHelper fait maintenant rfrence toutes les mthodes de la slection bases sur #element.
Pour changer la slection active appelez get() nouveau avec un nouvel lment.
JsHelper::set(mixed $one, mixed $two = null)
Passe des variables dans JavaScript. Vous permet de dfinir des variables qui seront retournes quand
le buffer est extrait avec Helper Js::getBuffer() ou Helper Js::writeBuffer().
La variable Javascript utilise pour retourner les variables peut tre controlle avec Helper
Js::$setVariable.
JsHelper::drag($options = array())
Rend un lment draggable.
Options
handle - selecteur de llment.
snapGrid - La grille de pixel qui dclenche les mouvements, un tableau(x, y)
container - Llment qui agit comme un rectangle de selection pour llment
draggable.
Options dvnements
start - vnement lanc quand le drag dmarre.
drag - vnement lanc chaque tape du drag.
stop - vnement lanc quand le drag sarrte. (souris relche)
Exemple dutilisation :
$this->Js->get('#element');
$this->Js->drag(array(
'container' => '#content',
'start' => 'onStart',
'drag' => 'onDrag',
158
Si vous utilisiez le moteur Jquery le code suivant devrait tre ajout au buffer
$("#element").draggable({
containment:"#content",
drag:onDrag,
grid:[10,10],
start:onStart,
stop:onStop
});
JsHelper::drop($options = array())
Fabrique un lment accepte des lments dragguables et agit comme dropzone pour les lments
draggs.
Options
accept - Slecteur des lments que ce droppable acceptera.
hoverclass - Classe pour ajouter droppable quand un draggable est termin.
Event Options
drop - vnement lanc quand un lment est dropp dans la drop zone.
hover - vnement lanc quand un drag entre dans une drop zone.
leave - vnement lanc quand un drag est retir depuis une drop zone sans tre dropp.
Exemple dutilisation :
$this->Js->get('#element');
$this->Js->drop(array(
'accept' => '.items',
'hover' => 'onHover',
'leave' => 'onExit',
'drop' => 'onDrop',
'wrapCallbacks' => false
));
Si vous utilisiez le moteur jQuery le code suivant devrait tre ajout au buffer.
$("#element").droppable({
accept:".items",
drop:onDrop,
out:onExit,
over:onHover
});
Note : Les lments Droppables dans Mootools fonctionnent diffremment des autres librairies. Les
Droppables sont implments comme une extension de Drag. Donc pour faire une selection get() pour
llment droppable. Vous devez aussi fournir une rgle de selecteur llment draggable. De plus,
les droppables Mootools hritent de toutes les option de Drag.
159
JsHelper::slider($options = array())
Cr un morceau de code Javascript qui converti un lment dans un morceau de code slider ui. Voir les
implmentations des diffrentes librairies pour des utilisations supplmentaires et les fonctionnalits.
Options
handle - l id de llment utilis dans le sliding.
direction - La direction du slider soit vertical ou horizontal.
min - La valeur minimale pour le slider.
max - La valeur maximale pour le slider.
step - Le nombre dtapes que le curseur aura.
value - Le dcalage initial du slider.
Events
change - Lanc quand la valeur du slider est actualis.
complete - Lanc quand un utilisateur arrte de slider le gestionnaire.
Exemple dutilisation :
$this->Js->get('#element');
$this->Js->slider(array(
'complete' => 'onComplete',
'change' => 'onChange',
'min' => 0,
'max' => 10,
'value' => 2,
'direction' => 'vertical',
'wrapCallbacks' => false
));
Si vous utilisiez le moteur jQuery le code suivant devrait tre ajout au buffer.
$("#element").slider({
change:onChange,
max:10,
min:0,
orientation:"vertical",
stop:onComplete,
value:2
});
160
Exemple dutilisation
Si vous utilisez le moteur jQuery :
$this->Js->get('#element');
$result = $this->Js->effect('fadeIn');
// $result contient $("#foo").fadeIn();
Si vous employiez la librairie jQuery vous devriez avoir le code Javascript suivant ajout au buffer.
Notez que lvnement du navigateur par dfaut nest pas annul :
$('#some-link').bind('click', function (event) {
alert('hey you!');
});
JsHelper::domReady($callback)
Cr lvnement spcial DOM ready. JsHelper::writeBuffer() enveloppe automatiquement les scripts bufferiss dans une mthode domReady.
JsHelper::each($callback)
Cr un morceau de code qui effectue une itration sur les lments slectionns, et insre
$callback.
Exemple :
En savoir plus sur les vues
161
$this->Js->get('div.message');
$this->Js->each('$(this).css({color: "red"});');
JsHelper::alert($message)
Cr un extrait de code JavaScript contenant un alert(). Par dfaut, alert ne bufferise pas, et
retourne le morceau de script suivant.
$alert = $this->Js->alert('Zogotunga!');
JsHelper::confirm($message)
Cr un bout de code contenant confirm(). Par dfaut, confirm ne bufferise pas, et retourne le
morceau de script suivant.
$alert = $this->Js->confirm('Vraiment certain?');
JsHelper::prompt($message, $default)
Cr un bout de code Javascript contenant prompt(). Par dfaut, prompt ne bufferise pas, et
retourne le morceau de code suivant.
$prompt = $this->Js->prompt('C'est quoi ta couleur prfre?', 'bleu');
Va cr un bouton submit et un vnement onclick attach. Lvnement click sera bufferis par
dfaut.
echo $this->Js->submit('Save', array(
'update' => '#content',
'div' => false,
'type' => 'json',
'async' => false
));
162
JsHelper::serializeForm($options = array())
Srialise le formulaire attach au $selector. Passe true pour $isForm si la selection courante est
un lment de formulaire. Converti le formulaire ou llment de formulaire attach la slection
courante dans un objet chane/json (dpendant de limplmentation de la librairie) pour utilisation
avec les oprations XHR.
Options
isForm - est ce que la slection courante est un formulaire ou un input ? (par dfaut false)
inline - est ce que le traitement du rendu sera utilis dans un autre traitement JS ? (par dfaut
false)
En dfinissant inline == false vous permet de retirer la bordure ;. Ceci est utile quand vous avez besoin
de srialiser un lment de formulaire comme faisant parti dune autre opration Javascript ou utilisez
la mthode de srialisation dans un Objet littral.
JsHelper::redirect($url)
Redirige la page vers $url en utilisant window.location.
En savoir plus sur les vues
163
JsHelper::value($value)
Convertit une variable native PHP dun type dans une reprsentation JSON quivalente. chappe une
valeur de chane dans une chane compatible JSON. Les caractre UTF-8 seront chapps .
La Pagination AJAX
Bien mieux quavec la pagination AJAX de la 1.2, vous pouvez utiliser le Helper JS pour grer les liens de
pagination AJAX au lieu de liens HTML.
Fabriquer les liens AJAX Avant de pouvoir crer les liens ajax vous devez inclure la librairie Javascript
qui correspond ladaptateur que vous utilisez avec le Helper JS. Par dfaut le Helper Js utilise
jQuery. Donc dans votre layout incluez jQuery (ou la librairie que vous utilisez). Assurez vous galement
dinclure RequestHandlerComponent dans votre behavior. Ajoutez ce qui suit dans votre controller :
public $components = array('RequestHandler');
public $helpers = array('Js');
Ce qui suit relie la librairie Javascript que vous voulez utiliser. Pour cet exemple nous utiliserons jQuery :
echo $this->Html->script('jquery');
De mme quavec la 1.2 vous devez dire au PaginatorHelper que vous voulez faire des liens Javascript
avancs au lieu des plain HTML. Pour faire cela utilisez options() :
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true
));
La classe PaginatorHelper sait maintenant quil faut crer des liens Javascript tendus, et que ces liens
devront mettre jour le contenu #content de llment. Bien sr cet lment doit exister, et la plupart
du temps vous voulez envelopper le $content_for_layout par une div qui correspond lid utilise
dans loption update. Vous devez galement dfinir evalScripts true si vous utilisez des adaptateurs
Mootools ou Prototype, sans evalScripts ces librairies seront incapables de relier les requtes entrent
elles. Loption indicator nest pas supporte par le Helper JS et sera ignore.
Vous venez donc de crer tous les liens demands pour le fonctionnement de la pagination. Puisque le
Helper Js bufferise automatiquement tous les contenus de scripts pour rduire les balises <script>
dans vos codes sources vous devez appeler la restitution du buffer. A la fin de votre fichier de vue. Vrifiez
linclusion de :
echo $this->Js->writeBuffer();
Si vous oubliez cela vous ne pourrez pas enchaner les liens de pagination AJAX. Quand vous crivez le
buffer, cela lefface galement , et vous navez donc pas vous inquiter de doublon de code Javascript.
164
Ajouter des effets et des transitions Depuis que indicator nest plus support, vous devez ajouter les
effets dindicator vous mme. :
<!DOCTYPE html>
<html>
<head>
<?php echo $this->Html->script('jquery'); ?>
//more stuff here.
</head>
<body>
<div id="content">
<?php echo $this->fetch('content'); ?>
</div>
<?php
echo $this->Html->image(
'indicator.gif',
array('id' => 'busy-indicator')
);
?>
</body>
</html>
Rappelez vous de placer le fichier indicator.gif dans le rpertoire app/webroot/img. Vous devriez voir une
situation o indicator.gif saffiche immdiatement au chargement de la page. Vous avez besoin dinsrer cet
indicateur #busy-indicator { display:none; } dans votre fichier CSS principal.
Avec le layout ci-dessus, nous avons inclus un indicateur, qui affichera une animation occup que nous
aurons montrer et cacher avec le Helper Js. Pour faire cela, nous avons besoin de mettre jour notre
fonction options() :
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true,
'before' => $this->Js->get('#busy-indicator')->effect(
'fadeIn',
array('buffer' => false)
),
'complete' => $this->Js->get('#busy-indicator')->effect(
'fadeOut',
array('buffer' => false)
),
));
Ceci montrera/cachera llment indicateur occup avant et aprs que le contenu de la balise #content
soit mis jour. Bien que indicator ait t enlev, les nouvelles fonctionnalits du JsHelper permettent
la cration de plus de contrle et deffets plus complexes.
NumberHelper
class NumberHelper(View $view, array $settings = array())
165
Le helper Number contient des mthodes pratiques qui permettent laffichage des nombres dans divers
formats communs dans vos vues. Ces mthodes contiennent des moyens pour formater les devises, pourcentages, taille des donnes, le format des nombres avec prcisions et aussi de vous donner davantage de
souplesse en matire de formatage des nombres.
Modifi dans la version 2.1 : NumberHelper a t remani dans une classe CakeNumber pour permettre
une utilisation plus facile a lextrieur de la couche View. Dans une vue, ces mthodes sont accessibles
via la classe NumberHelper et vous pouvez lappeler comme vous pourriez appeler une mthode de helper
normale : $this->Number->method($args);.
Toutes ces fonctions retournent le nombre format ; Elles naffichent pas automatiqement la sortie dans la
vue.
NumberHelper::currency(float $number, string $currency = USD, array $options = array())
Paramtres
$number (float) La valeur convertir.
$currency (string) Le format de monnaie connu utiliser.
$options (array) Options, voir ci-dessous.
Cette mthode est utilise pour afficher un nombre dans des formats de monnaie courante
(EUR,GBP,USD). Lutilisation dans une vue ressemble ceci :
// Appel avec NumberHelper
echo $this->Number->currency($number, $currency);
// Appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency($number, $currency);
Le premier paramtre $number, doit tre un nombre virgule qui reprsente le montant dargent
que vous dsirez. Le second paramtre est utilis pour choisir un schma de formatage de monnaie
courante :
$currency 1234.56, format par le type courant
EUR
C1.234,56
GBP
1,234.56
USD
$1,234.56
Le troisime paramtre est un tableau doptions pour dfinir la sortie. Les options suivantes sont
disponibles :
166
Option
before
after
zero
Description
Le symbole de la monnaie placer avant les nombres ex : $
Le symbole de la monnaie placer aprs les nombres dcimaux ex : c. Dfinit le
boolen false pour utiliser aucun symbole dcimal ex : 0.35 => $0.35.
Le texte utiliser pour des valeurs zro, peut tre une chane de caractres ou un
nombre. ex : 0, Free !
Nombre de dcimales utiliser. ex : 2
Sparateur des milliers ex : ,
places
thousands
decimals Symbole de Sparateur des dcimales. ex : .
negative
Symbole pour les nombres ngatifs. Si gal (), le nombre sera entour avec ( et )
escape
La sortie doit-elle tre chappe de htmlentity ? Par dfaut dfini true
wholeSym- La chane de caractres utiliser pour les tous nombres. ex : dollars
bol
wholePo- Soit before soit after pour placer le symbole entier
sition
fractionChane de caractres utiliser pour les nombres en fraction. ex : cents
Symbol
fractionSoit before soit after pour placer le symbole de fraction
Position
fractionFraction exponent de cette monnaie spcifique. Par dfaut 2.
Exponent
Si une valeur $currency non reconnue est fournie, elle est prfixe par un nombre format en USD.
Par exemple :
// Appel avec NumberHelper
echo $this->Number->currency('1234.56', 'FOO');
// Sortie
FOO 1,234.56
// Appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency('1234.56', 'FOO');
NumberHelper::defaultCurrency(string $currency)
Paramtres
$currency
(string)
Dfini
CakeNumber::currency().
une
monnaie
connu
pour
Setter/getter pour la monnaie par dfaut. Ceci retire la ncessit de toujours passer la monnaie
CakeNumber::currency() et change toutes les sorties de monnaie en dfinissant les autres par
dfaut.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.
NumberHelper::addFormat(string $formatName, array $options)
Paramtres
$formatName (string) Le nom du format utiliser dans le futur.
$options (array) Le tableau doptions pour ce format. Utilise les mmes cls
$options comme CakeNumber::currency().
En savoir plus sur les vues
167
Vous pouvez maintenant utiliser BRL de manire courte quand vous formatez les montants de monnaie :
// appel par NumberHelper
echo $this->Number->currency($value, 'BRL');
// appel par CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency($value, 'BRL');
Les formats ajouts sont fusionns avec les formats par dfaut suivants :
array(
'wholeSymbol'
'wholePosition'
'fractionSymbol'
'fractionPosition'
'zero'
'places'
'thousands'
'decimals'
'negative'
'escape'
'fractionExponent'
)
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
'',
'before',
false,
'after',
0,
2,
',',
'.',
'()',
true,
2
Introduit dans la version 2.4 : Largument $options avec loption multiply a t ajout.
NumberHelper::fromReadableSize(string $size, $default)
Paramtres
$size (string) La valeur formate lisible par un humain.
Cette mthode enlve le format dun nombre partir dune taille de byte lisible par un humain en un
nombre entier de bytes.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3
NumberHelper::toReadableSize(string $dataSize)
En savoir plus sur les vues
169
Paramtres
$data_size (string) Le nombre de bytes pour le rendre lisible.
Cette mthode formate les tailles de donnes dans des formes lisibles pour lhomme. Elle fournit une
manire raccourcie de convertir les en KB, MB, GB, et TB. La taille est affiche avec un niveau de
prcision deux chiffres, selon la taille de donnes fournie (ex : les tailles suprieurs sont exprimes
dans des termes plus larges) :
// appel avec NumberHelper
echo $this->Number->toReadableSize(0); // 0 Bytes
echo $this->Number->toReadableSize(1024); // 1 KB
echo $this->Number->toReadableSize(1321205.76); // 1.26 MB
echo $this->Number->toReadableSize(5368709120); // 5.00 GB
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::toReadableSize(0); // 0 Bytes
echo CakeNumber::toReadableSize(1024); // 1 KB
echo CakeNumber::toReadableSize(1321205.76); // 1.26 MB
echo CakeNumber::toReadableSize(5368709120); // 5.00 GB
Le paramtre $number est le nombre que vous souhaitez formater pour la sortie. Avec aucun $options
fourni, le nombre 1236.334 sortirait comme ceci : 1,236. Notez que la prcision par dfaut est daucun
chiffre aprs la virgule.
Le paramtre $options est l o rside la relle magie de cette mthode.
Si vous passez un entier alors celui-ci devient le montant de prcision pour la fonction.
Si vous passez un tableau associatif, vous pouvez utiliser les cls suivantes :
places (integer) : le montant de prcision dsir.
before (string) : mettre avant le nombre sortir.
escape (boolean) : si vous voulez la valeur avant dtre chappe.
decimals (string) : utilis pour dlimiter les places des dcimales dans le nombre.
thousands (string) : utilis pour marquer les milliers, millions, . . .
Exemple :
// appel avec NumberHelper
echo $this->Number->format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
170
));
// sortie ' 123,456.79'
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
));
// sortie ' 123,456.79'
Le paramtre $number est le nombre que vous planifiez sur le formatage de sortie. Avec aucun $options fourni, le nombre 1236.334 sortirait 1,236. Notez que la valeur de prcision par dfaut est aucune
dcimale.
Le paramtre $options prend les mmes cls que CakeNumber::format() lui-mme :
places (integer) : le montant de precision souhait.
before (string) : mettre avant le nombre sorti.
after (string) : mettre aprs le nombre sorti.
decimals (string) : utilis pour dlimiter les places de la dcimal dans un nombre.
thousands (string) : utilis pour marquer les places des centaines, millions, . . .
Exemple :
// appel avec NumberHelper
echo $this->Number->formatDelta('123456.7890', array(
'places' => 2,
'decimals' => '.',
'thousands' => ','
));
// sortie '+123,456.79'
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::formatDelta('123456.7890', array(
'places' => 2,
'decimals' => '.',
'thousands' => ','
));
// sortie '+123,456.79'
171
Avertissement : Depuis 2.4 les symboles sont maintenant en UTF-8. Merci de regarder le guide de
migration pour plus de dtails si vous lancez une application non-UTF-8.
Paginator
class PaginatorHelper(View $view, array $settings = array())
Le Helper Paginator est utilis pour prsenter des contrles de pagination comme les numros de pages et
les liens suivant/prcdent. Il travaille en tandem avec PaginatorComponent.
Voir aussi Pagination pour des informations sur la faon de crer des jeux de donnes pagins et faire des
requtes pagines.
Cration de liens tris
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">User Id</a>
Vous pouvez utiliser le paramtre title pour crer des textes personnaliss pour votre lien :
echo $this->Paginator->sort('user_id', 'User account');
Sortie :
172
Si vous utilisez de lHTML comme des images dans vos liens rappelez-vous de paramtrer lchappement :
echo $this->Paginator->sort(
'user_id',
'<em>User account</em>',
array('escape' => false)
);
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">
<em>User account</em>
</a>
Loption de direction peut tre utilise pour paramtrer la direction par dfaut pour un lien. Une fois quun
lien est activ, il changera automatiquement de direction comme habituellement :
echo $this->Paginator->sort('user_id', null, array('direction' => 'desc'));
Sortie
<a href="/posts/index/page:1/sort:user_id/direction:desc/">User Id</a>
Loption lock peut tre utilise pour verrouiller le tri dans la direction spcifie :
echo $this->Paginator->sort('user_id', null, array('direction' => 'asc', 'lock' => true));
PaginatorHelper::numbers($options = array())
Retourne un ensemble de nombres pour le jeu de rsultat pagin. Utilise un modulo pour dcider combien
de nombres prsenter de chaque cot de la page courante. Par dfaut 8 liens de chaque cot de la page
courante seront crs si cette page existe. Les liens ne seront pas gnrs pour les pages qui nexistent pas.
La page courante nest pas un lien galement.
Les options supportes sont :
before Contenu a insrer avant les nombres.
after Contenu a insrer aprs les nombres.
model Model pour lequel crer des nombres, par dfaut PaginatorHelper::defaultModel().
modulus combien de nombres inclure sur chacun des cots de la page courante, par dfaut 8.
separator Sparateur, par dfaut |
tag La balise dans laquelle envelopper les liens, par dfaut span.
173
last Si vous voulez que les derniers liens soit gnrs, dfinit un entier pour dfinir le nombre de
dernier liens gnrer. Par dfaut false. Suit la mme logique que loption first. il y a mthode
last() utiliser sparment si vous le voulez.
ellipsis Contenu des suspensions, par dfaut ...
La balise currentTag utiliser pour le nombre de page courant, par dfaut null. Cela vous autorise
gnrer par exemple le Bootstrap Twitter comme les liens avec le nombre de page courant enroul dans
les balises a ou span supplmentaires.
Bien que cette mthode permette beaucoup de customisation pour ses sorties. Elle est aussi prte pour tre
appele sans aucun paramtres.
echo $this->Paginator->numbers();
En utilisant les options first et last vous pouvez crer des liens pour le dbut et la fin du jeu de page. Le code
suivant pourrait crer un jeu de liens de page qui inclut les liens des deux premiers et deux derniers rsultats
de pages :
echo $this->Paginator->numbers(array('first' => 2, 'last' => 2));
Modifi dans la version 2.1 : Loption currentClass t ajoute dans la version 2.1.
Introduit dans la version 2.3 : Loption currentTag a t ajoute dans 2.3.
Cration de liens de sauts
En plus de gnrer des liens qui vont directement sur des numros de pages spcifiques, vous voudrez
souvent des liens qui amnent vers le lien prcdent ou suivant, premire et dernire pages dans le jeu de
donnes pagines.
PaginatorHelper::prev($title = << Previous, $options = array(), $disabledTitle = null,
$disabledOptions = array())
Paramtres
$title (string) Titre du lien.
$options (mixed) Options pour le lien de pagination.
$disabledTitle (string) Titre quand le lien est dsactiv, comme quand vous tes
dj sur la premire page, sans page prcdente o aller.
$disabledOptions (mixed) Options pour le lien de pagination dsactiv.
Gnre un lien vers la page prcdente dans un jeu denregistrements pagins.
$options et $disabledOptions supportent les cls suivantes :
tag La balise enveloppante que vous voulez utiliser, span par dfaut.
escape Si vous voulez que le contenu soit encod en HTML, par dfaut true.
model Le model utiliser, par dfaut PaginatorHelper : :defaultModel()
174
Si vous tiez actuellement sur la secondes pages des posts (articles), vous obtenez le rsultat suivant :
<span class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
<< previous
</a>
</span>
Sortie :
<li class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
</li>
Output :
<a class="prev" rel="prev"
href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
175
Ceci cr un simple lien pour la premire page. Ne retournera rien si vous tes sur la premire page.
Vous pouvez aussi utiliser un nombre entier pour indiquer combien de premier liens pagins vous
voulez gnrer :
echo $this->Paginator->first(3);
Ceci crera des liens pour les 3 premires pages, une fois la troisime page ou plus atteinte. Avant
cela rien ne sera retourn.
Les paramtres doption acceptent ce qui suit :
tag La balise tag enveloppante que vous voulez utiliser, par dfaut span.
after Contenu insrer aprs le lien/tag.
model Le model utiliser par dfaut PaginatorHelper : :defaultModel().
separator Contenu entre les liens gnrs, par dfaut | .
ellipsis Contenu pour les suspensions, par dfaut ....
PaginatorHelper::last($last = last >>, $options = array())
Cette mthode fonctionne trs bien comme la mthode first(). Elle a quelques diffrences cependant. Elle ne gnrera pas de lien si vous tes sur la dernire page avec la valeur chane $last. Pour
une valeur entire de $last aucun lien ne sera gnr une fois que lutilisateur sera dans la zone des
dernires pages.
PaginatorHelper::current(string $model = null)
rcupre la page actuelle pour le jeu denregistrement du model donn :
// Ou l'URL est: http://example.com/comments/view/page:3
echo $this->Paginator->current('Comment');
// la sortie est 3
PaginatorHelper::counter($options = array())
Retourne une chane compteur pour le jeu de rsultat pagin. En Utilisant une chane formate fournie et un
nombre doptions vous pouvez crer des indicateurs et des lments spcifiques de lapplication indiquant
ou lutilisateur se trouve dans lensemble de donnes pagines.
Il y a un certain nombre doptions supportes pour counter(). celles supportes sont :
176
format Format du compteur. Les formats supports sont range, pages et custom. Par dfaut pages
qui pourrait ressortir comme 1 of 10. Dans le mode custom la chane fournie est analyse (parse) et les
jetons sont remplaces par des valeurs relles. Les jetons autoriss sont :
{:page} - la page courante affiche.
{:pages} - le nombre total de pages.
{:current} - le nombre actuel denregistrements affichs.
{:count} - le nombre total denregistrements dans le jeu de rsultat.
{:start} - le nombre de premier enregistrement affichs.
{:end} - le nombre de dernier enregistrements affichs.
{:model} - La forme plurielle du nom de model. Si votre model tait RecettePage, {:model}
devrait tre recipe pages. cette option a t ajoute dans la 2.0.
Vous pouvez aussi fournir simplement une chane la mthode counter en utilisant les jetons autoriss.
Par exemple :
echo $this->Paginator->counter(
'Page {:page} of {:pages}, showing {:current} records out of
{:count} total, starting on record {:start}, ending on {:end}'
);
separator Le sparateur entre la page actuelle et le nombre de pages. Par dfaut of . Ceci est utilis
en conjonction avec format =pages qui la valeur par dfaut de format :
echo $this->Paginator->counter(array(
'separator' => ' sur un total de '
));
model
Le
nom
du
model
en
cours
de
pagination,
par
dfaut
PaginatorHelper::defaultModel(). Ceci est utilis en conjonction avec la chane personnalise de loption format.
Modification des options que le Helper Paginator utilise
PaginatorHelper::options($options = array())
Paramtres
$options (mixed) Options par dfaut pour les liens de pagination. Si une chane
est fournie - elle est utilise comme id de llment DOM actualiser.
Dfinit toutes les options pour le Helper Paginator Helper. Les options supportes sont :
url LURL de laction de pagination. url comporte quelques sous options telles que :
sort La cl qui dcrit la faon de trier les enregistrements.
direction La direction du tri. Par dfaut ASC.
page Le numro de page afficher.
Les options mentionnes ci-dessus peuvent tre utilises pour forcer des pages/directions particulires.
Vous pouvez aussi ajouter des contenu dURL supplmentaires dans toutes les URLs gnres dans le
helper :
En savoir plus sur les vues
177
$this->Paginator->options(array(
'url' => array(
'sort' => 'email', 'direction' => 'desc', 'page' => 6,
'lang' => 'en'
)
));
Ce qui se trouve ci-dessus ajoutera en comme paramtre de route pour chacun des liens que le helper va
gnrer. Il crera galement des liens avec des tris, direction et valeurs de page spcifiques. Par dfaut
PaginatorHelper fusionnera cela dans tous les paramtres passs et nomms. Ainsi vous naurez pas le
faire dans chacun des fichiers de vue.
escape Dfinit si le champ titre des liens doit tre chapp HTML. Par dfaut true.
update Le selecteur CSS de llment actualiser avec le rsultat de lappel de pagination AJAX. Si
cela nest pas spcifi, des liens rguliers seront crs :
$this->Paginator->options(array('update' => '#content'));
Ceci est utile lors de lutilisation de la pagination AJAX La Pagination AJAX. Gardez lesprit que la
valeur actualise peut tre un selecteur CSS valide, mais il est souvent plus simple dutiliser un selecteur
id.
model
Le
nom
du
model
en
cours
de
pagination,
par
dfaut
PaginatorHelper::defaultModel().
Utilisation de paramtres GET pour la pagination Normalement la Pagination dans CakePHP utilise
Paramtres Nomms. Il y a des fois ou vous souhaiterez utilisez des paramtres GET la place. Alors que la
principale option de configuration pour cette fonctionnalit est dans PaginatorComponent, vous avez
des contrles supplmentaires dans les vues. Vous pouvez utiliser options() pour indiquer que vous voulez
la conversion dautres paramtres nomms :
$this->Paginator->options(array(
'convertKeys' => array('your', 'keys', 'here')
));
Configurer le Helper Paginator pour utiliser le Helper Javascript Par dfaut le Helper
Paginator utilise JsHelper pour effectuer les fonctionnalits AJAX. Toutefois, si vous ne voulez
pas cela et que vous voulez utiliser un Helper personnalis pour les liens AJAX, vous pouvez le faire en
changeant le tableau $helpers dans votre controller. Aprs avoir lanc paginate() fates ce qui suit :
// Dans l'action de votre controller.
$this->set('posts', $this->paginate());
$this->helpers['Paginator'] = array('ajax' => 'CustomJs');
Changera le Helper Paginator pour utiliser CustomJs pour les oprations AJAX. Vous pourriez
aussi dfinir la cl AJAX pour tre un Helper, tant que la classe implmente la mthode link() qui se
comporte comme HtmlHelper::link().
178
Cest vous de dcider comment afficher les enregistrements lutilisateur, mais la plupart des fois, ce sera
fait lintrieur des tables HTML. Lexemple ci-dessous suppose une prsentation tabulaire, mais le Helper
Paginator disponible dans les vues Na pas toujours besoin dtre limit en tant que tel.
Voir les dtails sur PaginatorHelper 4 dans l API. Comme mentionn prcdemment, le Helper Paginator
offre galement des fonctionnalits de tri qui peuvent tre facilement intgrs dans vos en-ttes de colonne
de table :
// app/View/Posts/index.ctp
<table>
<tr>
<th><?php echo $this->Paginator->sort('id', 'ID'); ?></th>
<th><?php echo $this->Paginator->sort('title', 'Title'); ?></th>
</tr>
<?php foreach ($data as $recipe): ?>
<tr>
<td><?php echo $recipe['Recipe']['id']; ?> </td>
<td><?php echo h($recipe['Recipe']['title']); ?> </td>
</tr>
<?php endforeach; ?>
</table>
Lingrdient final pour laffichage de la pagination dans les vues est laddition de pages de navigation, aussi
fournies par le Helper de Pagination :
// Montre les numros de page
echo $this->Paginator->numbers();
// Montre les liens prcdent et suivant
echo $this->Paginator->prev(' Previous', null, null, array('class' => 'disabled'));
echo $this->Paginator->next('Next ', null, null, array('class' => 'disabled'));
4. http ://api.cakephp.org/2.4/class-PaginatorHelper.html
179
Le texte de sortie de la mthode counter() peut galement tre personnalis en utilisant des marqueurs
spciaux :
echo $this->Paginator->counter(array(
'format' => 'Page {:page} of {:pages}, showing {:current} records out of
{:count} total, starting on record {:start}, ending on {:end}'
));
Dautres Mthodes
cela
crerait
un
lien
pointant
vers
PaginatorHelper::defaultModel()
Retourne le model par dfaut du jeu de pagination ou null si la pagination nest pas initialise.
PaginatorHelper::params(string $model = null)
Retourne les paramtres courants de la pagination du jeu de rsultat dun model donn :
180
debug($this->Paginator->params());
/*
Array
(
[page] => 2
[current] => 2
[count] => 43
[prevPage] => 1
[nextPage] => 3
[pageCount] => 3
[order] =>
[limit] => 20
[options] => Array
(
[page] => 2
[conditions] => Array
(
)
)
[paramType] => named
)
*/
181
Le Helper RSS permet de gnrer facilement des XML pour les flux RSS.
Crer un flux RSS avec RssHelper
Cet exemple suppose que vous ayez un Controller Posts et un Model Post dj crs et que vous vouliez
crer une vue alternative pour les flux RSS.
Crer une version xml/rss de posts/index est vraiment simple avec CakePHP. Aprs quelques tapes faciles,
vous pouvez tout simplement ajouter lextension .rss demande posts/index pour en faire votre URL
posts/index.rss. Avant daller plus loin en essayant dinitialiser et de lancer notre service Web, nous
avons besoin de faire un certain nombre de choses. Premirement, le parsing dextensions doit tre activ
dans app/config/routes.php :
Router::parseExtensions('rss');
Dans lappel ci-dessus, nous avons activ lextension .rss. Quand vous utilisez
Router::parseExtensions(), vous pouvez passer autant darguments ou dextensions que
vous le souhaitez. Cela activera le content-type de chaque extension utilise dans votre application.
Maintenant, quand ladresse posts/index.rss est demande, vous obtiendrez une version XML de
votre posts/index. Cependant, nous avons dabord besoin dditer le controller pour y ajouter le code
rss-spcifique.
Code du Controller Cest une bonne ide dajouter RequestHandler au tableau $components de votre
controller Posts. Cela permettra beaucoup dautomagie de se produire :
public $components = array('RequestHandler');
Notre vue utilise aussi TextHelper pour le formatage, ainsi il doit aussi tre ajout au controller :
public $helpers = array('Text');
Avant que nous puissions faire une version RSS de notre posts/index, nous avons besoin de mettre certaines
choses en ordre. Il pourrait tre tentant de mettre le canal des mtadonnes dans laction du controller et
de le passer votre vue en utilisant la mthode Controller::set(), mais ceci est inappropri. Cette
information pourrait galement aller dans la vue. Cela arrivera sans doute plus tard, mais pour linstant,
si vous avez un ensemble de logique diffrent entre les donnes utilises pour crer le flux RSS et les
donnes pour la page HTML, vous pouvez utiliser la mthode RequestHandler::isRss(), sinon
votre controller pourrait rester le mme :
// Modifie l'action du Controller Posts correspondant
// l'action qui dlivre le flux rss, laquelle est
// l'action index dans notre exemple
public function index() {
if ($this->RequestHandler->isRss() ) {
$posts = $this->Post->find(
'all',
array('limit' => 20, 'order' => 'Post.created DESC')
);
182
return $this->set(compact('posts'));
}
// ceci n'est pas une requte RSS
// donc on retourne les donnes utilises par l'interface du site web
$this->paginate['Post'] = array(
'order' => 'Post.created DESC',
'limit' => 10
);
$posts = $this->paginate();
$this->set(compact('posts'));
}
Maintenant que toutes ces variables de Vue sont dfinies, nous avons besoin de crer un layout rss.
Layout Un
layout
Rss
est
trs
simple,
app/View/Layouts/rss/default.ctp :
mettez
les
contenus
suivants
dans
if (!isset($documentData)) {
$documentData = array();
}
if (!isset($channelData)) {
$channelData = array();
}
if (!isset($channelData['title'])) {
$channelData['title'] = $this->fetch('title');
}
$channel = $this->Rss->channel(array(), $channelData, $this->fetch('content'));
echo $this->Rss->document($documentData, $channel);
Il ne ressemble pas plus mais grce la puissance du RssHelper il fait beaucoup pour amliorer le visuel
pour nous. Nous navons pas dfini $documentData ou $channelData dans le controller, cependant
dans CakePHP vos vues peuvent retourner les variables au layout. Ce qui est lendroit o notre tableau
$channelData va venir dfinir toutes les donnes meta pour notre flux.
Ensuite il y a le fichier de vue pour mes posts/index. Un peu comme le fichier de layout que nous avons cr,
nous avons besoin de crer un rpertoire View/Posts/rss/ et un nouveau index.ctp lintrieur de
ce rpertoire. Les contenus du fichier sont ci-dessous.
View Notre vue, localise dans app/View/Posts/rss/index.ctp, commence par dfinir les variables $documentData et $channelData pour le layout, celles-ci contiennent toutes les metadonnes
pour notre flux RSS. Cest fait en utilisant la mthode View::set() qui est analogue la mthode
View::set(). Ici nous passons les canaux de donnes en retour au layout :
$this->set('channelData', array(
'title' => __("Most Recent Posts"),
'link' => $this->Html->url('/', true),
'description' => __("Most recent posts."),
'language' => 'en-us'));
183
La seconde partie de la vue gnre les lments pour les enregistrements actuels du flux. Ceci est accompli en bouclant sur les donnes qui ont t passes la vue ($items) et en utilisant la mthode
RssHelper::item(). Lautre mthode que vous pouvez utiliser RssHelper::items() qui prend
un callback et un tableau des items pour le flux. (La mthode que jai vu utilise pour le callback a toujours
t appele transformRss(). Il y a un problme pour cette mthode, qui est quelle nutilise aucune des
classes de helper pour prparer vos donnes lintrieur de la mthode de callback parce que la porte
lintrieur de la mthode ninclut pas tout ce qui nest pas pass lintrieur, ainsi ne donne pas accs au
TimeHelper ou tout autre helper dont vous auriez besoin. RssHelper::item() transforme le tableau
associatif en un lment pour chaque pair de valeur de cl.
Note : Vous devrez modifier la variable $postLink comme il se doit pour votre application.
foreach ($posts as $post) {
$postTime = strtotime($post['Post']['created']);
$postLink = array(
'controller' => 'posts',
'action' => 'view',
'year' => date('Y', $postTime),
'month' => date('m', $postTime),
'day' => date('d', $postTime),
$post['Post']['slug']
);
// Retire & chappe tout HTML pour tre sr que le contenu va tre valid.
$bodyText = h(strip_tags($post['Post']['body']));
$bodyText = $this->Text->truncate($bodyText, 400, array(
'ending' => '...',
'exact' => true,
'html'
=> true,
));
echo
$this->Rss->item(array(), array(
'title' => $post['Post']['title'],
'link' => $postLink,
'guid' => array('url' => $postLink, 'isPermaLink' => 'true'),
'description' => $bodyText,
'pubDate' => $post['Post']['created']
));
}
Vous pouvez voir ci-dessus que nous pouvons utiliser la boucle pour prparer les donnes devant tre transformes en lments XML. Il est important de filtrer tout texte de caractres non brute en-dehors de la
description, spcialement si vous utilisez un diteur de texte riche pour le corps de votre blog. Dans le
code ci-dessus nous utilisons strip_tags() et h() pour retirer/chapper tout caractre spcial XML du
contenu, puisquils peuvent entraner des erreurs de validation. Une fois que nous avons dfini les donnes
pour le feed, nous pouvons ensuite utiliser la mthode RssHelper::item() pour crer le XML dans le
format RSS. Une fois que vous avez toutes ces configurations, vous pouvez tester votre feed RSS en allant
votre /posts/index.rss et que vous verrez votre nouveau feed. Il est toujours important que vous
validiez votre feed RSS avant de le mettre en live. Ceci peut tre fait en visitant les sites qui valident le XML
comme Le Validateur de Feed ou le site de w3c http ://validator.w3.org/feed/.
184
Note : Vous aurez besoin de dfinir la valeur de debug dans votre configuration du coeur 1 ou 0 pour
obtenir un flux valide, cause des diffrentes informations de debug ajoutes automatiquement sous des
paramtres de debug plus haut qui cassent la syntaxe XML ou les rgles de validation du flux.
property RssHelper::$action
Action courante
property RssHelper::$base
Base URL
property RssHelper::$data
donne du model POSTe
property RssHelper::$field
Nom du champ courant
property RssHelper::$helpers
Helpers utiliss par le Helper RSS
property RssHelper::$here
URL de laction courante
property RssHelper::$model
Nom du model courant
property RssHelper::$params
Paramtre tableau
property RssHelper::$version
Version de spec par dfaut de la gnration de RSS.
RssHelper::channel(array $attrib = array (), array $elements = array (), mixed $content =
null)
Type retourn string
Retourne un lment RSS <channel />.
RssHelper::document(array $attrib = array (), string $content = null)
Type retourn string
Retourne un document RSS entour de tags <rss />.
RssHelper::elem(string $name, array $attrib = array (), mixed $content = null, boolean $endTag = true)
Type retourn string
Gnre un lment XML.
RssHelper::item(array $att = array (), array $elements = array ())
Type retourn string
Convertit un tableau en un lment <item /> et ses contenus.
En savoir plus sur les vues
185
tant donn ce tableau, le nud sera accessible par User.username, le point indiquant le tableau imbriqu. Cette notation est utilise pour toutes les mthodes du helper Session o une variable $key est
utilise.
SessionHelper::read(string $key)
Type retourn mixed
Lire partir de la Session. Retourne une chane de caractre ou un tableau dpendant des contenus de
la session.
SessionHelper::consume($name)
Type retourn mixed
Lit et supprime une valeur de Session. Cest utile quand vous voulez combiner la lecture et la suppression de valeurs en une seule opration.
SessionHelper::check(string $key)
Type retourn boolean
Vrifie si une cl est dans la Session. Retourne un bolen sur lexistence dun cl.
SessionHelper::error()
Type retourn string
Retourne la dernire erreur encourue dans une session.
186
SessionHelper::valid()
Type retourn boolean
Utilise pour vrifier si une session est valide dans une vue.
Affichage de notifications ou de messages flash
Comme pour la mthode du component, vous pouvez dfinir des proprits supplmentaires et personnaliser quel lment est utilis. Dans le controller, vous pouvez avoir du code comme :
// dans un controller
$this->Session->setFlash('Le user n'a pu tre supprim.');
Quand le message sort, vous pouvez choisir llment utilis pour afficher ce message :
// dans un layout.
echo $this->Session->flash('flash', array('element' => 'failure'));
Vous pouvez aussi passer des paramtres supplmentaires dans la mthode flash(), ce qui vous
permet de gnrer des messages personnaliss :
// Dans le controller
$this->Session->setFlash('Thanks for your payment %s');
// Dans le layout.
echo $this->Session->flash('flash', array(
'params' => array('name' => $user['User']['name'])
'element' => 'payment'
));
187
// View/Elements/payment.ctp
<div class="flash payment">
<?php printf($message, h($name)); ?>
</div>
TextHelper
class TextHelper(View $view, array $settings = array())
TextHelper possde des mthodes pour rendre le texte plus utilisable et sympa dans vos vues. Il aide activer
les liens, formater les URLs, crer des extraits de texte autour des mots ou des phrases choisies, mettant
en vidence des mots cls dans des blocs de texte et tronquer lgamment de longues tendues de texte.
Modifi dans la version 2.1 : Plusieurs des mthodes de TextHelper ont t dplaces dans la classe
String pour permettre une utilisation plus facile de la couche View. Dans une vue, ces mthodes sont
accessibles avec la classe TextHelper et vous pouvez lappeler comme vous appelleriez une mthode normale
de helper : $this->Text->method($args);.
TextHelper::autoLinkEmails(string $text, array $options=array())
Paramtres
$text (string) Le texte convertir.
$options (array) Un tableau d attributs HTML pour gnrer les liens.
Ajoute les liens aux adresses email bien formes dans $text, selon toute les options dfinies dans
$options (regardez HtmlHelper::link()).
$myText = 'Pour plus d'informations sur nos ptes et desserts fameux,
contactez info@example.com';
$linkedText = $this->Text->autoLinkEmails($myText);
Sortie :
Pour plus d'informations sur nos ptes et desserts fameux,
contactez <a href="mailto:info@example.com">info@example.com</a>
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement ces inputs. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoLinkUrls(string $text, array $options=array())
Paramtres
$text (string) Le texte convertir.
$options (array) Un tableau d attributs HTML pour la gnration de liens.
De mme que dans autoLinkEmails(), seule cette mthode cherche les chanes de caractre qui
commence par https, http, ftp, ou nntp et les liens de manire approprie.
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement son input. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoLink(string $text, array $options=array())
Paramtres
$text (string) Le texte lier automatiquement.
$htmlOptions (array) Un tableau d attributs HTML pour gnrer les liens.
188
Output :
<p>Pour plus d\'information<br />
selon nos clbres ptes et desserts.<p>
<p>contact info@example.com</p>
189
Sortie :
Highlights $needle in $haystack <span class="highlight">using</span>
the $options['format'] string specified or a default string.
TextHelper::stripLinks($text)
Enlve le $text fourni de tout lien HTML.
TextHelper::truncate(string $text, int $length=100, array $options)
Paramtres
$text (string) Le texte tronquer.
$length (int) La longueur en caractres pour laquelle le texte doit tre tronqu.
$options (array) Un tableau doptions utiliser.
Si $text est plus long que $length, cette mthode le tronque la longueur $length et ajoute un
prefix ellipsis, si dfini. Si exact est pass false, le truchement va se faire au premier
espace aprs le point o $length a dpass. Si html est pass true, les balises html seront
respectes et ne seront pas coupes.
$options est utilis pour passer tous les paramtres supplmentaires, et a les cls suivantes possibles par dfaut, celles-ci tant toutes optionnelles :
array(
'ellipsis' => '...',
'exact' => true,
'html' => false
)
Exemple :
// appel avec TextHelper
echo $this->Text->truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
Sortie :
The killer crept...
190
Modifi dans la version 2.3 : ending a t remplac par ellipsis. ending est toujours utilis dans
2.2.1.
TextHelper::tail(string $text, int $length=100, array $options)
Paramtres
$text (string) The text tronquer.
$length (int) La longueur en caractres pour laquelle le texte doit tre tronqu.
$options (array) Un tableau doptions utiliser.
Si $text est plus long que $length, cette mthode retire une sous-chane initiale avec la longueur
de la diffrence et ajoute un suffixe ellipsis, si il est dfini. Si exact est pass false,
le truchement va se faire au premier espace avant le moment o le truchement aurait t fait.
$options est utilis pour passer tous les paramtres supplmentaires, et a les cls possibles suivantes par dfaut, toutes sont optionnelles :
array(
'ellipsis' => '...',
'exact' => true
)
Sortie :
...a TV, a C# program that can divide by zero, death metal t-shirts
191
Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...
Sortie :
red, orange, yellow, green, blue, indigo et violet
TimeHelper
class TimeHelper(View $view, array $settings = array())
Le Helper Time vous permet, comme il lindique de gagner du temps. Il permet le traitement rapide des
informations se rapportant au temps. Le Helper Time a deux tches principales quil peut accomplir :
1. Il peut formater les chanes de temps.
2. Il peut tester le temps (mais ne peut pas le courber, dsol).
Modifi dans la version 2.1 : TimeHelper a t reconstruit dans la classe CakeTime pour faciliter lutilisation en-dehors de la couche View. Dans une vue, ces mthodes sont accessibles via la
classe TimeHelper et vous pouvez lappeler comme vous appelleriez une mthode normale de helper :
$this->Time->method($args);.
192
Utiliser le Helper
Une utilisation courante de Time Helper est de compenser la date et le time pour correspondre au
time zone de lutilisateur. Utilisons un exemple de forum. Votre forum a plusieurs utilisateurs qui
peuvent poster des messages depuis nimporte quelle partie du monde. Une faon facile de grer le
temps est de sauvegarder toutes les dates et les times GMT+0 or UTC. Dcommenter la ligne
date_default_timezone_set(UTC); dans app/Config/core.php pour sassurer que le
time zone de votre aplication est dfini GMT+0.
Ensuite, ajoutez un time zone votre table users et fates les modifications ncessaires pour permettre vos
utilisateurs de dfinir leur time zone. Maintenant que nous connaissons le time zone de lutilisateur connect,
nous pouvons corriger la date et le temps de nos posts en utilisant le Helper Time :
echo $this->Time->format(
'F jS, Y h:i A',
$post['Post']['created'],
null,
$user['User']['time_zone']
);
// Affichera August 22nd, 2011 11:53 PM pour un utilisateur dans GMT+0
// August 22nd, 2011 03:53 PM pour un utilisateur dans GMT-8
// et August 23rd, 2011 09:53 AM GMT+10
La plupart des mthodes du Helper Time contiennent un paramtre $timezone. Le paramtre $timezone
accepte une chane identifiante de timezone valide ou une instance de la classe DateTimeZone.
Formatage
193
Modifi dans la version 2.2 : Le paramtre $timezone remplace $userOffset utilis dans 2.1 et
suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::format($date, $format = NULL, $default = false, $timezone = NULL)
Type retourn string
Va retourner une chane formate avec le format donn en utilisant les options de formatage de la
fonction PHP strftime() 5 :
// appel via TimeHelper
echo $this->Time->format('2011-08-22 11:53:00', '%B %e, %Y %H:%M %p');
// August 22nd, 2011 11:53 AM
echo $this->Time->format('%r', '+2 days');
// 2 days from now formatted as Sun, 13 Nov 2011 03:36:10 AM EET
5. http ://www.php.net/manual/en/function.strftime.php
194
Vous pouvez aussi fournir la date/time en premier argument. En faisant cela vous devrez utiliser le
format strftime compatible. Cette signature dappel vous permet de tirer parti du format de date
de la locale ce qui nest pas possible en utilisant le format de date() compatible :
// appel avec TimeHelper
echo $this->Time->format('2012-01-13', '%d-%m-%Y', 'invalid');
// appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2011-08-22', '%d-%m-%Y');
Modifi dans la version 2.2 : Les paramtres $format et $date sont en ordre oppos par rapport ce qui se faisait dans 2.1 et suivants. Le paramtre $timezone remplace le paramtre
$userOffset utilis dans 2.1 et suivants. Le paramtre $default remplace le paramtre
$invalid utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $date accepte aussi maintenant un objet DateTime.
TimeHelper::fromString($dateString, $timezone = NULL)
Type retourn string
Prend une chane et utilise strtotime 6 pour la convertir en une date integer :
// Appel avec TimeHelper
echo $this->Time->fromString('Aug 22, 2011');
// 1313971200
echo $this->Time->fromString('+1 days');
// 1321074066 (+1 day from current date)
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::fromString('Aug 22, 2011');
echo CakeTime::fromString('+1 days');
195
Prendra une chane datetime (tout ce qui est parsable par la fonction strtotime() de PHP ou le format
de datetime de MySQL) et la convertit en un format de texte comme, 3 weeks, 3 days ago :
// Appel avec TimeHelper
echo $this->Time->timeAgoInWords('Aug 22, 2011');
// on 22/8/11
// on August 22nd, 2011
echo $this->Time->timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y')
);
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::timeAgoInWords('Aug 22, 2011');
echo CakeTime::timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y')
);
Utilisez loption end pour dterminer le point de cutoff pour ne plus utiliser de mots ; par dfaut
+1 month :
// Appel avec TimeHelper
echo $this->Time->timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
// On Nov 10th, 2011 it would display: 2 months, 2 weeks, 6 days ago
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
Utilisez loption accuracy pour dterminer la prcision de la sortie. Vous pouvez utiliser ceci pour
limiter la sortie :
// Si $timestamp est il y a 1 month, 1 week, 5 days et 6 hours
echo CakeTime::timeAgoInWords($timestamp, array(
'accuracy' => array('month' => 'month'),
'end' => '1 year'
));
// Sort '1 month ago'
197
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
Introduit dans la version 2.4 : Les nouveaux paramtres doption relativeString (par dfaut
%s ago) et absoluteString (par dfaut on %s) pour permettre la personnalisation de la
chane de sortie rsultante sont maintenant disponibles.
TimeHelper::toRSS($dateString, $timezone = NULL)
Type retourn string
Va retourner une chane de date au format RSS Sat, 12 Jan 2008 00 :00 :00 -0500
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toUnix($dateString, $timezone = NULL)
Type retourn integer
Un enrouleur pour fromString.
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
198
199
wasWithinLast prend un intervalle de time qui est une chane au format 3 months et accepte un
intervalle de time en secondes, minutes, heures, jours, semaines, mois et annes (pluriels ou non). Si
un intervalle de time nest pas reconnu (par exemple, si il y a une faute de frappe) ensuite ce sera par
dfaut days.
Utiliser et configurer les Helpers
Vous activez les helpers dans CakePHP, en faisant prendre conscience un controller quils existent.
Chaque controller a une proprit $helpers, qui liste les helpers disponibles dans la vue. Pour activer un
helper dans votre vue, ajoutez son nom au tableau $helpers du controller :
class BakeriesController extends AppController {
public $helpers = array('Form', 'Html', 'Js', 'Time');
}
Lajout des helpers depuis les plugins utilise la syntaxe de plugin utilise partout ailleurs dans CakePHP :
class BakeriesController extends AppController {
public $helpers = array('Blog.Comment');
}
Vous pouvez aussi ajouter les helpers depuis une action, dans ce cas, ils seront uniquement accessibles pour
cette action et dans aucune autre action du controller. Ceci conomise de la puissance de calcul pour les
autres actions qui nutilisent pas le helper, tout en permettant de conserver le controller mieux organis :
class BakeriesController extends AppController {
public function bake() {
$this->helpers[] = 'Time';
}
public function mix() {
// Le Helper Time n'est pas charg ici et n'est par consquent
// pas disponible
}
}
Si vous avez besoin dactiver un helper pour tous les controllers, ajoutez son nom dans le tableau $helpers
du fichier /app/Controller/AppController.php ( crer si pas prsent). Noubliez pas dinclure
les helpers par dfaut Html et Form :
class AppController extends Controller {
public $helpers = array('Form', 'Html', 'Js', 'Time');
}
Vous pouvez passer des options dans les helpers. Ces options peuvent tre utilises pour dfinir les valeurs
dattributs ou modifier le comportement du helper :
class AwesomeHelper extends AppHelper {
public function __construct(View $view, $settings = array()) {
parent::__construct($view, $settings);
debug($options);
}
200
}
class AwesomeController extends AppController {
public $helpers = array('Awesome' => array('option1' => 'valeur1'));
}
Depuis 2.3 les options sont fusionnes avec la proprit Helper::$settings du helper.
Une configuration courante est dutiliser loption className, qui vous permet de crer des alias de helper
dans vos vues. Cette fonctionnalit est utile quand vous voulez remplacer $this->Html ou tout autre
Helper de rfrence avec une mise en oeuvre personnalise :
// app/Controller/PostsController.php
class PostsController extends AppController {
public $helpers = array(
'Html' => array(
'className' => 'MyHtml'
)
);
}
// app/View/Helper/MyHtmlHelper.php
App::uses('HtmlHelper', 'View/Helper');
class MyHtmlHelper extends HtmlHelper {
// Ajouter votre code pour craser le HtmlHelper du coeur
}
Ce qui est au-dessus fera un alias de MyHtmlHelper vers $this->Html dans vos vues.
Note : Faire un alias dun helper remplace cette instance partout o le helper est utilis, y compris dans les
autres Helpers.
Lutilisation des configurations du helper vous permet de configurer de manire dclarative vos helpers et de
garder la logique de configuration de vos actions des controllers. Si vous avez des options de configuration
qui ne peuvent pas tre inclues comme des parties de dclaration de classe, vous pouvez les dfinir dans le
callback beforeRender de votre controller :
class PostsController extends AppController {
public function beforeRender() {
parent::beforeRender();
$this->helpers['CustomStuff'] = $this->_getCustomStuffSettings();
}
}
201
echo $this->Html->css('styles');
Ce qui est au-dessus appelera la mthode css du HtmlHelper. Vous pouvez accder nimporte quel helper
charg en utilisant $this->{$helperName}. Il peut venir un temps o vous aurez besoin de charger
dynamiquement un helper partir dune vue. Vous pouvez utiliser la vue du HelperCollection pour
le faire :
$mediaHelper = $this->Helpers->load('Media', $mediaSettings);
Le HelperCollection est une collection et supporte lAPI collection utilise partout ailleurs dans CakePHP.
Mthodes de Callback
Les Helpers disposent de plusieurs callbacks qui vous permettent daugmenter le processus de rendu de vue.
Allez voir la documentation de API de Helper et Collections pour plus dinformations.
Crer des Helpers
Si un helper du coeur (ou lun prsent sur github ou dans la Boulangerie) ne correspond pas vos besoins,
les helpers sont faciles crer.
Mettons que nous voulions crer un helper, qui pourra tre utilis pour produire un lien CSS, faonn
spcialement selon vos besoins, diffrents endroits de votre application. Afin de trouver une place
votre logique dans la structure de helper existante dans CakePHP, vous devrez crer une nouvelle classe
dans /app/View/Helper. Appelons notre helper LienHelper. Le fichier de la classe PHP ressemblera
quelque chose comme ceci :
/* /app/View/Helper/LienHelper.php */
App::uses('AppHelper', 'View/Helper');
class LienHelper extends AppHelper {
public function lancerEdition($titre, $url) {
// La logique pour crer le lien spcialement format se place
ici...
}
}
Note : Les Helpers doivent tendre soit AppHelper soit Helper ou implmenter tous les callbacks dans
lAPI de Helper.
Vous souhaitez peut-tre utiliser quelques fonctionnalits dj existantes dans un autre helper. Pour faire
cela, vous pouvez spcifier les helpers que vous souhaitez utiliser avec un tableau $helpers, format
comme vous le feriez dans un controller :
202
Une fois que vous avez crez votre helper et lavez plac dans /app/View/Helper/, vous serez capable
de linclure dans vos controllers en utilisant la variable spciale $helpers :
class PostsController extends AppController {
public $helpers = array('Lien');
}
Une fois que votre controller est au courant de cette nouvelle classe, vous pouvez lutiliser dans vos vues en
accdant un objet nomm daprs le helper :
<!-- fait un lien en utilisant le nouveau helper -->
<?php echo $this->Lien->lancerEdition('Changer cette recette', '/recipes/edit/5'); ?>
API de Helper
class Helper
La classe de base pour les Helpers. Elle fournit un nombre de mthodes utiles et des fonctionnalits
pour le chargement dautres helpers.
En savoir plus sur les vues
203
Helper::webroot($file)
Dcide du nom de fichier du webroot de lapplication. Si un thme est actif et que le fichier existe
dans le webroot du thme courant, le chemin du fichier du thme sera retourn.
Helper::url($url, $full = false)
Gnre une URL chappe de HTML, qui dlgue Router::url().
Helper::value($options = array(), $field = null, $key = value)
Rcupre la valeur pour un nom dinput donn.
Helper::domId($options = null, $id = id)
Gnre une valeur id en CamelCase pour le champ slectionn courant. Ecraser cette mthode dans
votre AppHelper vous permettra de changer la faon dont CakePHP gnre les attributs ID.
Callbacks
Helper::beforeRenderFile($viewFile)
Est appel avant que tout fichier de vue soit rendu. Cela inclut les elements, les vues, les vues parentes
et les layouts.
Helper::afterRenderFile($viewFile, $content)
Est appel aprs que tout fichier de vue est rendu. Cela inclut les elements, les vues, les vues parentes
et les layouts. Un callback peut modifier et retourner $content pour changer la manire dont le
contenu rendu est affich dans le navigateur.
Helper::beforeRender($viewFile)
La mthode beforeRender est appel aprs la mthode beforeRender du controller, mais avant les
rendus du controller de la vue et du layout Reoit le fichier rendre en argument.
Helper::afterRender($viewFile)
Est appel aprs que la vue est rendu, mais avant que le rendu du layout ait commenc.
Helper::beforeLayout($layoutFile)
Est appel avant que le rendu du layout commence. Reoit le nom du fichier layout en argument.
Helper::afterLayout($layoutFile)
Est appel aprs que le rendu du layout est fini. Reoit le nom du fichier layout en argument.
204
CHAPITRE 6
Models (Modles)
Les Models sont les classes qui reprsentent la couche de logique dans votre application. Ils sont responsables de la gestion de presque tout ce qui concerne les donnes, leur validit, les interactions et lvolution
du flux dinformations dans votre domaine de travail.
Habituellement, les classes de model reprsentent les donnes et sont utilises dans les applications
CakePHP pour laccs aux donnes, plus spcifiquement elles reprsentent une table de la base de donnes, mais elles ne sont pas limites cela et peuvent tre utilises pour accder tout ce qui manipule des
donnes comme des fichiers, des services web externes, des vnements iCal.
Un model peut tre associ avec dautres models. Par exemple, une Recette peut tre associe avec lAuteur
de la recette ainsi qu un Ingredient.
Cette section vous expliquera quelles fonctionnalits du model peuvent tre automatises, comment outrepasser ces fonctionnalits, et quelles mthodes et proprits un model peut avoir. Elle expliquera les diffrentes faons dassocier vos donnes. Elle dcrira comment trouver, sauvegarder, et effacer des donnes.
Au final, elle sintressera aux sources de donnes.
Avec juste cette simple dclaration, le model Ingredient est dot de toutes les fonctionnalits dont vous
avez besoin pour crer des requtes, ainsi que sauvegarder et supprimer des donnes. Ces mthodes
205
magiques proviennent de la classe Model de CakePHP, grce la magie de lhritage. Le model Ingredient tend le model de lapplication AppModel, lequel tend la classe Model interne de CakePHP.
Cest cette classe Model du cur qui fournit les fonctionnalits lintrieur de votre model Ingredient.
App::uses(AppModel, Model) sassure que le model est charg sans effort quand cela est
ncessaire.
La classe intermdiaire AppModel est vide. Si vous navez pas cr la vtre, elle provient du rpertoire du
coeur de cakePHP. Ecraser AppModel vous permet de dfinir des fonctionnalits qui doivent tre rendues
disponibles pour tous les models de votre application. Pour faire cela, vous avez besoin de crer votre
propre fichier AppModel.php qui se loge dans le dossier Model, comme tous les autres models de votre
application. la cration dun projet en utilisant Bake, ce fichier sera automatiquement cr pour vous.
Voir aussi Behaviors pour plus dinformations sur la faon dappliquer la mme logique pour de multiples
models.
Revenons-en notre model Ingredient. Pour que cela fonctionne, crez le fichier PHP dans le repertoire
/app/Model/. Par convention, il devra avoir le mme nom que la classe ce qui pour lexemple sera
Ingredient.php.
Note : CakePHP crera dynamiquement un objet model pour vous si il ne peut pas trouver un fichier
correspondant dans /app/Model. Cela veut galement dire que si votre fichier de model nest pas nomm
correctement (par ex si il est nomm ingredient.php ou Ingredients.php plutt que Ingredient.php) CakePHP
utilisera une instance de AppModel, plutt que votre fichier de model (qui sera manquant pour CakePHP).
Si vous essayez dutiliser une mthode que vous avez dfinie dans votre model ou dans un comportement
attach votre model et que vous obtenez des erreurs SQL qui indiquent le nom de la mthode que vous
appelez, cest une indication certaine que CakePHP ne peut pas trouver votre model et que vous devez
vrifier les noms de fichier, nettoyer les fichiers temporaires ou les deux.
Note : Certains noms de classe ne sont pas utilisables pour les noms de model. Par exemple, File ne peut
pas tre utilis puisque File est une classe existant dj dans le coeur de CakePHP.
Une fois que votre model est dfini, il est accessible depuis vos Controllers. CakePHP rend automatiquement
un model disponible en accs, ds lors que son nom correspond celui du controller. Par exemple, un
controller nomm IngredientsController initialisera automatiquement le model Ingredient et y accdera par
$this->Ingredient :
class IngredientsController extends AppController {
public function index() {
// Rcupre tous les ingrdients et les transmet la vue :
$ingredients = $this->Ingredient->find('all');
$this->set('ingredients', $ingredients);
}
}
Les models associs sont accessibles travers le model principal. Dans lexemple suivant, Recette a une
association avec le model Ingredient :
class Recette extends AppModel {
public function steakRecipes() {
206
$ingredient = $this->Ingredient->findByName('Steak');
return $this->findAllByMainIngredient($ingredient['Ingredient']['id']);
}
}
Cela montre comment utiliser les models qui sont dj lis. Pour comprendre comment les associations sont
dfinies, allez voir la Section des associations.
Type dAssociation
hasOne
hasMany
belongsTo
hasAndBelongsToMany
Exemple
Un user a un profile.
Un user peut avoir plusieurs recipes.
Plusieurs recipes appartiennent un user.
Les recipes ont, et appartiennent plusieurs
ingrdients.
Pour clarifier davantage la dfinition des associations dans les modles : Si la table dun model contient
la cl trangre (other_model_id), le type de relation dans ce model est toujours un Model belongsTo
OtherModel.
Les associations se dfinissent en crant une variable de classe nomme comme lassociation que vous
souhaitez dfinir. La variable de classe peut quelquefois se limiter une chane de caractre, mais peut
207
galement tre aussi complte quun tableau multi-dimensionnel utilis pour dfinir les spcificits de lassociation.
class User extends AppModel {
public $hasOne = 'Profile';
public $hasMany = array(
'Recipe' => array(
'className' => 'Recipe',
'conditions' => array('Recipe.approved' => '1'),
'order' => 'Recipe.created DESC'
)
);
}
Dans lexemple ci-dessus, la premire occurrence du mot Recipe est ce que lon appelle un Alias. Cest
un identifiant pour la relation et cela peut tre ce que vous souhaitez. En rgle gnrale, on choisit le mme
nom que la classe quil rfrence. Toutefois, les alias pour chaque model doivent tre uniques dans une
app entire. Par exemple, il est appropri davoir :
class User extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'MemberOf' => array(
'className' => 'Group',
)
);
}
class Group extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'Member' => array(
'className' => 'User',
)
);
}
208
parce que ici nous avons lalias Member se rfrant aux deux models User (dans Group) et Group (dans
User) dans les associations HABTM. Choisir des noms non-uniques pour les alias de models travers les
models peut entraner un comportement inattendu.
CakePHP va crer automatiquement des liens entre les objets model associs. Ainsi par exemple dans votre
model User, vous pouvez accder au model Recipe comme ceci :
$this->Recipe->someFunction();
De mme dans votre controller, vous pouvez accder un model associ simplement en poursuivant les
associations de votre model :
$this->User->Recipe->someFunction();
Note : Rappelez-vous que les associations sont dfinies dans un sens. Si vous dfinissez User hasMany
Recipe, cela na aucun effet sur le model Recipe. Vous avez besoin de dfinir Recipe belongsTo User pour
pouvoir accder au model User partir du model Recipe.
hasOne
Mettons en place un model User avec une relation de type hasOne vers un model Profile.
Tout dabord, les tables de votre base de donnes doivent tre saisies correctement. Pour quune relation
de type hasOne fonctionne, une table doit contenir une cl trangre qui pointe vers un enregistrement de
lautre. Dans notre cas la table profiles contiendra un champ nomm user_id. Le motif de base est :
hasOne :, lautre model contient la cl trangre.
209
Relation
Apple hasOne Banana
User hasOne Profile
Doctor hasOne Mentor
Schema
bananas.apple_id
profiles.user_id
mentors.doctor_id
Note : Il nest pas obligatoire de suivre les conventions de CakePHP, vous pouvez facilement outrepasser
lutilisation de toute cl trangre dans les dfinitions de vos associations. Nanmoins, coller aux conventions donnera un code moins rptitif, plus facile lire et maintenir.
Le fichier model User sera sauvegard dans /app/Model/User.php. Pour dfinir lassociation User hasOne Profile, ajoutez la proprit $hasOne la classe de model. Pensez avoir un model Profile dans
/app/Model/Profile.php, ou bien lassociation ne marchera pas :
class User extends AppModel {
public $hasOne = 'Profile';
}
Il y a deux faons de dcrire cette relation dans vos fichiers de model. La mthode la plus simple est de
dfinir lattribut $hasOne pour une chane de caractre contenant le className du model associ, comme
nous lavons fait au-dessus.
Si vous avez besoin de plus de contrle, vous pouvez dfinir vos associations en utilisant la syntaxe des
tableaux. Par exemple, vous voudrez peut-tre limiter lassociation pour inclure seulement certains enregistrements.
class User extends AppModel {
public $hasOne = array(
'Profile' => array(
'className' => 'Profile',
'conditions' => array('Profile.published' => '1'),
'dependent' => true
)
);
}
210
supprims. Dans ce cas nous avons fix la valeur true de manire ce que la suppression dun User
supprime galement le Profile associ.
Une fois que cette association a t dfinie, les oprations de recherche sur le model User rcuprent galement les enregistrements Profile lis sil en existe :
//Exemple de rsultats d'un appel $this->User->find().
Array
(
[User] => Array
(
[id] => 121
[name] => Gwoo the Kungwoo
[created] => 2007-05-01 10:31:01
)
[Profile] => Array
(
[id] => 12
[user_id] => 121
[skill] => Baking Cakes
[created] => 2007-05-01 10:31:01
)
)
belongsTo
Maintenant que nous avons accs aux donnes du Profile depuis le model User, dfinissons une association
belongsTo (appartient a) dans le model Profile afin de pouvoir accder aux donnes User lies. Lassociation
belongsTo est un complment naturel aux associations hasOne et hasMany : elle permet de voir les donnes
dans le sens inverse.
Lorsque vous dfinissez les cls de votre base de donnes pour une relation de type belongsTo, suivez cette
convention :
belongsTo : le model courant contient la cl trangre.
Relation
Banana belongsTo Apple
Profile belongsTo User
Mentor belongsTo Doctor
Schema
bananas.apple_id
profiles.user_id
mentors.doctor_id
Astuce : Si un model (table) contient une cl trangre, elle appartient (belongsTo) lautre model (table).
Nous pouvons dfinir lassociation belongsTo dans notre model Profile dans /app/Model/Profile.php en utilisant la syntaxe de chane de caractre comme ce qui suit :
class Profile extends AppModel {
public $belongsTo = 'User';
}
Nous pouvons aussi dfinir une relation plus spcifique en utilisant une syntaxe de tableau :
211
212
Disons que vous avez un model appel ImageComment et un model appel Image, vous ajouteriez un
nouveau champ numrique (INT) la table images et lappelleriez image_comment_count.
Ici vous trouverez quelques exemples supplmentaires :
Model
User
Image
BlogEntry
Associated Model
Image
ImageComment
BlogEntryComment
Example
users.image_count
images.image_comment_count
blog_entries.blog_entry_comment_count
Une fois que vous avez ajout le champ counter, cest tout bon. Activez counter-cache dans votre association
en ajoutant une cl counterCache et configurez la valeur true :
class ImageComment extends AppModel {
public $belongsTo = array(
'Image' => array(
'counterCache' => true,
)
);
}
A partir de maintenant, chaque fois que vous ajoutez ou retirez un ImageComment associ Image, le
nombre dans image_comment_count est ajust automatiquement.
counterScope
Vous pouvez aussi spcifier counterScope. Cela vous permet de spcifier une condition simple qui dit
au model quand mettre jour (ou quand ne pas le faire, selon la faon dont on le conoit) la valeur counter.
En utilisant notre exemple de model Image, nous pouvons le spcifier comme cela :
class ImageComment extends AppModel {
public $belongsTo = array(
'Image' => array(
'counterCache' => true,
// compte seulement si "ImageComment" est active = 1
'counterScope' => array(
213
'ImageComment.active' => 1
)
)
);
}
Multiple counterCache
Depuis la 2.0, CakePHP supporte les multiples counterCache dans une seule relation de model. Il est
aussi possible de dfinir un counterScope pour chaque counterCache. En assumant que vous avez un
model User et un model Message et que vous souhaitez tre capable de compter le montant de messages
lus et non lus pour chaque utilisateur.
Model
User
User
Message
Field
users.messages_read
users.messages_unread
messages.is_read
Description
Compte les Message lus
Compte les Message non lus
Dtermines si un Message est lu ou non.
hasMany
Prochaine tape : dfinir une association User hasMany Comment. Une association hasMany nous permettra de rcuprer les comments dun user lors de la rcupration dun enregistrement User.
Lorsque vous dfinissez les cls de votre base de donnes pour une relation de type hasMany, suivez cette
convention :
hasMany : lautre model contient la cl trangre.
Relation
User hasMany Comment
Cake hasMany Virtue
Product hasMany Option
Schema
Comment.user_id
Virtue.cake_id
Option.product_id
On peut dfinir lassociation hasMany dans notre model User (/app/Model/User.php) en utilisant une chane
de caractres de cette manire :
214
Nous pouvons galement dfinir une relation plus spcifique en utilisant un tableau :
class User extends AppModel {
public $hasMany = array(
'Comment' => array(
'className' => 'Comment',
'foreignKey' => 'user_id',
'conditions' => array('Comment.status' => '1'),
'order' => 'Comment.created DESC',
'limit' => '5',
'dependent' => true
)
);
}
215
(
[User] => Array
(
[id] => 121
[name] => Gwoo the Kungwoo
[created] => 2007-05-01 10:31:01
)
[Comment] => Array
(
[0] => Array
(
[id] => 123
[user_id] => 121
[title] => On Gwoo the Kungwoo
[body] => The Kungwooness is not so Gwooish
[created] => 2006-05-01 10:31:01
)
[1] => Array
(
[id] => 124
[user_id] => 121
[title] => More on Gwoo
[body] => But what of the Nut?
[created] => 2006-05-01 10:41:01
)
)
)
Une chose dont il faut se rappeler est que vous aurez besoin dune association Comment belongsTo User
en complment, afin de pouvoir rcuprer les donnes dans les deux sens. Ce que nous avons dfini dans cette
section vous donne la possibilit dobtenir les donnes de Comment depuis lUser. En ajoutant lassociation
Comment belongsTo User dans le model Comment, vous aurez la possibilit de connatre les donnes de
lUser depuis le model Comment - cela complte la connexion entre eux et permet un flot dinformations
depuis nimporte lequel des deux models.
hasAndBelongsToMany (HABTM)
Trs bien. A ce niveau, vous pouvez dj vous considrer comme un professionnel des associations de
models CakePHP. Vous tes dj assez comptent dans les 3 types dassociations afin de pouvoir effectuer
la plus grande partie des relations entre les objets.
Abordons maintenant le dernier type de relation : hasAndBelongsToMany (a et appartient plusieurs),
ou HABTM. Cette association est utilise lorsque vous avez deux models qui ont besoin dtre relis, de
manire rpte, plusieurs fois, de plusieurs faons diffrentes.
La principale diffrence entre les relations hasMany et HABTM est que le lien entre les models nest pas
exclusif dans le cadre dune relation HABTM. Par exemple, relions notre model Recipe avec un model
Ingredient en utilisant HABTM. Le fait dutiliser les tomates en Ingredient pour la recipe de Spaghettis de
ma grand-mre ne consomme pas lIngredient. Je peux aussi utiliser mes tomates pour une Recipe Salade.
Les liens entre des objets lis par une association hasMany sont exclusifs. Si mon User hasMany Com-
216
ment, un commentaire ne sera li qu un user spcifique. Il ne sera plus disponible pour dautres.
Continuons. Nous aurons besoin de mettre en place une table supplmentaire dans la base de donnes qui
contiendra les associations HABTM. Le nom de cette nouvelle table de jointure doit inclure les noms des
deux models concerns, dans lordre alphabtique, et spars par un underscore ( _ ). La table doit contenir
au minimum deux champs, chacune des cls trangres (qui devraient tre des entiers) pointant sur les
deux cls primaires des models concerns. Pour viter tous problmes, ne dfinissez pas une premire cl
compose de ces deux champs, si votre application le ncessite vous pourrez dfinir un index unique. Si
vous prvoyez dajouter de quelconques informations supplmentaires cette table, cest une bonne ide
que dajouter un champ supplmentaire comme cl primaire (par convention id) pour rendre les actions
sur la table aussi simple que pour tout autre model.
HABTM a besoin dune table de jointure spare qui contient les deux noms de models.
Relations
Recipe HABTM
Ingredient
Cake HABTM Fan
Foo HABTM Bar
Note : Le nom des tables est par convention dans lordre alphabtique. Il est possible de dfinir un nom de
table personnalis dans la dfinition de lassociation.
Assurez-vous que les cls primaires dans les tables cakes et recipes ont un champ id comme assum par
convention. Si ils sont diffrents de ceux anticips, il faut le changer dans la primaryKey du model.
Une fois que cette nouvelle table a t cre, on peut dfinir lassociation HABTM dans les fichiers de
model. Cette fois-ci, nous allons directement voir la syntaxe en tableau :
class Recipe extends AppModel {
public $hasAndBelongsToMany = array(
'Ingredient' =>
array(
'className' => 'Ingredient',
'joinTable' => 'ingredients_recipes',
'foreignKey' => 'recipe_id',
'associationForeignKey' => 'ingredient_id',
'unique' => true,
'conditions' => '',
'fields' => '',
'order' => '',
'limit' => '',
'offset' => '',
'finderQuery' => '',
'with' => ''
)
);
}
Les cls possibles pour un tableau dfinissant une association HABTM sont :
className : Le nom de la classe du model que lon souhaite associer au model actuel. Si lon souhaite
dfinir la relation Recipe HABTM Ingredient, la valeur associe la clef className devra tre Ingredient.
Pour en savoir plus sur les Models
217
joinTable : Le nom de la table de jointure utilise dans cette association (si la table ne colle pas la
convention de nommage des tables de jointure HABTM).
with : Dfinit le nom du model pour la table de jointure. Par dfaut CakePHP crera automatiquement
un model pour vous. Dans lexemple ci-dessus la valeur aurait t RecipesTag. En utilisant cette cl vous
pouvez surcharger ce nom par dfaut. Le model de la table de jointure peut tre utilis comme tout autre
model classique pour accder directement la table de jointure. En crant une classe model avec un tel
nom et un nom de fichier, vous pouvez ajouter tout behavior personnalis pour les recherches de la table
jointe, comme ajouter plus dinformations/colonnes celle-ci.
foreignKey : Le nom de la cl trangre que lon trouve dans le model actuel. Ceci sera particulirement
pratique si vous avez besoin de dfinir des relations HABTM multiples. La valeur par dfaut de cette cl
est le nom du model actuel (avec des underscores) suffix avec _id.
associationForeignKey : Le nom de la cl trangre que lon trouve dans lautre model. Ceci sera particulirement pratique si vous avez besoin de dfinir des relations HABTM multiples. La valeur par dfaut
de cette cl est le nom de lautre model (avec des underscores) suffix avec _id.
unique : Un bolen ou une chane de caractres keepExisting.
Si true (valeur par dfaut) CakePHP supprimera dabord les enregistrements des relations existantes dans la table des cls trangres avant den insrer de nouvelles. Les associations existantes
devront tre passes encore une fois lors dune mise jour.
Si false, CakePHP va insrer les nouveaux enregistrements de liaison spcifis et ne laissait
aucun enregistrement de liaison existant, provenant par exemple denregistrements dupliqus de
liaison.
Si keepExisting est dfinie, le behavior est similaire true, mais avec une vrification supplmentaire afin que si un enregistrement ajouter est en doublon dun enregistrement de liaison
existant, lenregistrement de liaison existant nest pas supprim et le doublon est ignor. Ceci peut
tre utile par exemple, la table de jointure a des donnes supplmentaires en lui qui doivent tre
gardes.
conditions : un tableau de conditions compatibles avec find() ou des chanes SQL. Si vous avez des
conditions sur la table associe, vous devez utiliser un model with, et dfinir les associations belongsTo
ncessaires sur lui.
fields : Une liste des champs rcuprer lorsque les donnes du model associ sont parcourues. Par dfaut,
cela retourne tous les champs.
order : un tableau de clauses order compatibles avec find() ou avec des chanes SQL.
limit : Le nombre maximum de lignes associes que vous voulez retourner.
offset : Le nombre de lignes associes enlever (tant donns les conditions et lorder courant) avant la
rcupration et lassociation.
finderQuery : Une requte SQL complte que CakePHP peut utiliser pour rcuprer les enregistrements
du model associ. Ceci doit tre utilis dans les situations qui ncessitent des rsultats trs personnaliss.
Une fois que cette association a t dfinie, les oprations de recherche sur le model Recipe rcupreront
galement les Ingredients lis si ils existent :
// Exemple de rsultats d'un appel a $this->Recipe->find().
Array
(
[Recipe] => Array
(
[id] => 2745
[name] => Chocolate Frosted Sugar Bombs
[created] => 2007-05-01 10:31:01
218
Noubliez pas de dfinir une association HABTM dans le model Ingredient si vous souhaitez retrouver les
donnes de Recipe lorsque vous manipulez le model Ingredient.
Note : Les donnes HABTM sont traites comme un ensemble complet, chaque fois quune nouvelle
association de donnes est ajoute, lensemble complet de lignes associes dans la base de donnes est
enlev et recre, ainsi vous devrez toujours passer lensemble des donnes dfinies pour sauvegarder. Pour
avoir une alternative lutilisation de HABTM, regardez hasMany through (Le Model Join)
Astuce : Pour plus dinformations sur la sauvegarde des objets HABTM regardez Sauvegarder les Donnes
de Model Li (HABTM=HasAndBelongsToMany)
Maintenant si nous souhaitions stocker le nombre de jours que les students doivent faire pour leur course et
leur grade final ? La table que nous souhaiterions serait comme ceci :
219
Le problme est que hasAndBelongsToMany ne va pas supporter ce type de scnario parce que quand les
associations hasAndBelongsToMany sont sauvegardes, lassociation est dabord supprime. Vous perdriez
les donnes supplmentaires dans les colonnes qui ne seraient pas remplaces dans le nouvel ajout.
Modifi dans la version 2.1.
Vous pouvez dfinir la configuration de unique keepExisting, contournant la perte de
donnes supplmentaires pendant lopration de sauvegarde. Regardez la cl unique dans
HABTM association arrays.
La faon dimplmenter nos exigences est dutiliser un join model, autrement connu comme une association hasMany through. Cela tant fait, lassociation est elle-mme un model. Ainsi, vous pouvez crer un
nouveau model CourseMembership. Regardez les models suivants.
// Student.php
class Student extends AppModel {
public $hasMany = array(
'CourseMembership'
);
}
// Course.php
class Course extends AppModel {
public $hasMany = array(
'CourseMembership'
);
}
// CourseMembership.php
class CourseMembership extends AppModel {
public $belongsTo = array(
'Student', 'Course'
);
}
Le model join CourseMembership identifie de faon unique une participation dun Student un Course en
plus dajouter des meta-informations.
Les models Join sont des choses particulirement pratiques utiliser et CakePHP facilite cela avec les
associations intgres hasMany et belongsTo et la fonctionnalit de saveAll.
Crer et Dtruire des Associations la Vole
Quelquefois il devient ncessaire de crer et dtruire les associations de models la vole. Cela peut tre le
cas pour un certain nombre de raisons :
Vous voulez rduire la quantit de donnes associes qui seront rcupres, mais toutes vos associations
sont sur le premier niveau de rcursion.
Vous voulez changer la manire dont une association est dfinie afin de classer ou filtrer les donnes
associes.
220
La cration et destruction de ces associations se font en utilisant les mthodes de models CakePHP bindModel() et unbindModel(). (Il existe aussi un behavior trs utile appel Containable, merci de vous rfrer
la section du manuel sur les behaviors intgrs pour plus dinformations). Mettons en place quelques models pour pouvoir ensuite voir comment fonctionnent bindModel() et unbindModel(). Nous commencerons
avec deux models :
class Leader extends AppModel {
public $hasMany = array(
'Follower' => array(
'className' => 'Follower',
'order' => 'Follower.rank'
)
);
}
class Follower extends AppModel {
public $name = 'Follower';
}
Maintenant, dans le controller LeadersController, nous pouvons utiliser la mthode find() du model Leader
pour retrouver un Leader et les Followers associs. Comme vous pouvez le voir ci-dessus, le tableau dassociation dans le model Leader dfinit une relation Leader hasMany (a plusieurs) Followers. Dans un but
dmonstratif, utilisons unbindModel() pour supprimer cette association dans une action du controller :
public function some_action() {
// Ceci rcupre tous les Leaders, ainsi que leurs Followers
$this->Leader->find('all');
// Supprimons la relation hasMany() ...
$this->Leader->unbindModel(
array('hasMany' => array('Follower'))
);
// Dsormais l'utilisation de la fonction find() retournera
// des Leaders, sans aucun Followers
$this->Leader->find('all');
// NOTE : unbindModel n'affecte que la prochaine fonction find.
// Un autre appel find() utilisera les informations d'association
// telles que configure.
// Nous avons dj utilis findAll('all') aprs unbindModel(),
// ainsi cette ligne rcuprera une fois encore les Leaders
// avec leurs Followers ...
$this->Leader->find('all');
}
Note : Enlever ou ajouter des associations en utilisant bindModel() et unbindModel() ne fonctionne que
pour la prochaine opration sur le model, moins que le second paramtre nait t fix false. Si le second
paramtre a t fix false, le lien reste en place pour la suite de la requte.
Voici un exemple basique dutilisation de unbindModel() :
Pour en savoir plus sur les Models
221
$this->Model->unbindModel(
array('associationType' => array('associatedModelClassName'))
);
Maintenant que nous sommes arrivs supprimer une association la vole, ajoutons-en une. Notre Leader
jusqu prsent sans Principles a besoin dtre associ quelques Principles. Le fichier de model pour notre
model Principle est dpouill, il ny a que la ligne var $name. Associons la vole des Principles notre
Leader (mais rappelons-le, seulement pour la prochaine opration find). Cette fonction apparat dans le
controller LeadersController :
public function another_action() {
// Il n'y a pas d'association Leader hasMany Principle
// dans le fichier de model Leader.php, ainsi un find
// situ ici ne rcuprera que les Leaders.
$this->Leader->find('all');
// Utilisons bindModel() pour ajouter une nouvelle association
// au model Leader :
$this->Leader->bindModel(
array('hasMany' => array(
'Principle' => array(
'className' => 'Principle'
)
)
)
);
// Si nous devons garder cette association aprs la rinitialisation du
// model, nous allons passer boolen en deuxime paramtre, comme ceci:
$this->Leader->bindModel(
array('hasMany' => array(
'Principle' => array(
'className' => 'Principle'
)
)
),
false
);
// Maintenant que nous les avons associs correctement,
// nous pouvons utiliser la fonction find une seule fois
// pour rcuprer les Leaders avec leurs Principles associs :
$this->Leader->find('all');
}
a y est, vous y tes. Lutilisation basique de bindModel() est lencapsulation dun tableau dassociation
classique, dans un tableau dont la cl est le nom du type dassociation que vous essayez de crer :
$this->Model->bindModel(
array('associationName' => array(
'associatedModelClassName' => array(
// les cls d'association normale vont ici...
222
)
)
)
);
Bien que le model nouvellement associ nait besoin daucune dfinition dassociation dans son fichier de
model, il devra tout de mme contenir les cls afin que la nouvelle association fonctionne bien.
Plusieurs relations avec le mme model
Il y a des cas o un Model a plus dune relation avec un autre Model. Par exemple, vous pourriez avoir un
model Message qui a deux relations avec le model User. Une relation avec luser qui envoie un message
et une seconde avec luser qui reoit le message. La table messages aura un champ user_id, mais aussi un
champ receveur_id. Maintenant, votre model Message peut ressembler quelque chose comme :
class Message extends AppModel {
public $belongsTo = array(
'Sender' => array(
'className' => 'User',
'foreignKey' => 'user_id'
),
'Recipient' => array(
'className' => 'User',
'foreignKey' => 'recipient_id'
)
);
}
Recipient est un alias pour le model User. Maintenant, voyons quoi devrait ressembler le model User :
class User extends AppModel {
public $hasMany = array(
'MessageSent' => array(
'className' => 'Message',
'foreignKey' => 'user_id'
),
'MessageReceived' => array(
'className' => 'Message',
'foreignKey' => 'recipient_id'
)
);
}
Il est aussi possible de crer des associations sur soi-mme comme montr ci-dessous :
class Post extends AppModel {
public $name = 'Post';
public $belongsTo = array(
'Parent' => array(
'className' => 'Post',
'foreignKey' => 'parent_id'
223
)
);
public $hasMany = array(
'Children' => array(
'className' => 'Post',
'foreignKey' => 'parent_id'
)
);
}
224
Dans lexemple ci-dessus, un model appel Item est joint gauche la table channels. Vous pouvez ajouter
un alias la table, avec le nom du Model, ainsi les donnes retournes se conformeront la structure de
donnes de CakePHP.
table : La table pour la jointure.
alias : un alias vers la table. Le nom du model associ avec la table est le meilleur choix.
type : Le type de jointure : inner, left ou right.
conditions : Les conditions pour raliser la jointure.
Avec joins, vous pourriez ajouter des conditions bases sur les champs du model li :
$options['joins'] = array(
array('table' => 'channels',
'alias' => 'Channel',
'type' => 'LEFT',
'conditions' => array(
'Channel.id = Item.channel_id',
)
)
);
$options['conditions'] = array(
'Channel.private' => 1
);
$privateItems = $Item->find('all', $options);
225
Utiliser joins vous permet davoir un maximum de flexibilit dans la faon dont CakePHP gre les associations et rcupre les donnes, cependant dans la plupart des cas, vous pouvez utiliser dautres outils pour
arriver aux mmes rsultats comme de dfinir correctement les associations, lier les models la vole et
utiliser le behavior Containable. Cette fonctionnalit doit tre utilise avec attention car elle peut conduire,
dans certains cas, quelques erreurs SQL lorsquelle est combine dautres techniques dcrites prcdemment pour les models associs.
Il est galement possible dajouter et dutiliser dautres paramtres, dont il est fait usage dans quelques types
de find, dans des behaviors (comportements) et, bien sr, dans vos propres mthodes de model.
Si votre opration de find narrive pas rcuprer des donnes, vous aurez un tableau vide.
226
find(first)
find(first, $params) retournera UN rsultat, vous devriez utiliser ceci dans tous les cas o vous
attendez un seul rsultat. Ci-dessous, quelques exemples simples (code du controller) :
public function une_fonction() {
// ...
$articleADemiAleatoire = $this->Article->find('first');
$dernierCree = $this->Article->find('first', array(
'order' => array('Article.created' => 'desc')
));
$specifiquementCeluiCi = $this->Article->find('first', array(
'conditions' => array('Article.id' => 1)
));
// ...
}
Dans le premier exemple, aucun paramtre nest pass au find ; par consquent aucune condition ou ordre
de tri ne seront utiliss. Le format retourn par un appel find(first) est de la forme :
Array
(
[NomDuModel] => Array
(
[id] => 83
[champ1] => valeur1
[champ2] => valeur2
[champ3] => valeur3
)
[NomDuModelAssocie]
(
[id] => 1
[champ1] =>
[champ2] =>
[champ3] =>
)
=> Array
valeur1
valeur2
valeur3
find(count)
find(count, $params) retourne une valeur de type entier. Ci-dessous, quelques exemples simples
(code du controller) :
public function une_fonction() {
// ...
$total = $this->Article->find('count');
$en_attente = $this->Article->find('count', array(
'conditions' => array('Article.status' => 'pending')
));
$authors = $this->Article->User->find('count');
$auteursPublies = $this->Article->find('count', array(
227
Note : Ne passez pas fields comme un tableau find(count). Vous devriez avoir besoin de
spcifier seulement des champs pour un count DISTINCT (parce que sinon, le dcompte est toujours le
mme - il est impos par les conditions).
find(all)
find(all, $params) retourne un tableau de rsultats (potentiellement multiples). Cest en fait le
mcanisme utilis par toutes les variantes de find(), ainsi que par paginate. Ci-dessous, quelques
exemples simples (code du controller) :
public function une_fonction() {
// ...
$tousLesArticles = $this->Article->find('all');
$en_attente = $this->Article->find('all', array(
'conditions' => array('Article.status' => 'pending')
));
$tousLesAuteurs = $this->Article->User->find('all');
$tousLesAuteursPublies = $this->Article->User->find('all', array(
'conditions' => array('Article.status !=' => 'pending')
));
// ...
}
Note : Dans lexemple ci-dessus $tousLesAuteurs contiendra chaque user de la table users, il ny aura
pas de condition applique la recherche puisquaucune na t passe.
Les rsultats dun appel find(all) seront de la forme suivante :
Array
(
[0] => Array
(
[NomDuModel] => Array
(
[id] => 83
[champ1] => valeur1
[champ2] => valeur2
[champ3] => valeur3
)
[NomDuModelAssocie] => Array
(
[id] => 1
228
find(list)
find(list, $params) retourne un tableau index, pratique pour tous les cas o vous voudriez
une liste telle que celles remplissant les champs select. Ci-dessous, quelques exemples simples (code du
controller) :
public function une_function() {
// ...
$tousLesArticles = $this->Article->find('list');
$en_attente = $this->Article->find('list', array(
'conditions' => array('Article.status' => 'pending')
));
$tousLesAuteurs = $this->Article->User->find('list');
$tousLesAuteursPublies = $this->Article->find('list', array(
'fields' => array('User.id', 'User.name'),
'conditions' => array('Article.status !=' => 'pending'),
'recursive' => 0
));
// ...
}
Note : Dans lexemple ci-dessus $tousLesAuteurs contiendra chaque user de la table users, il ny aura
pas de condition applique la recherche puisquaucune na t passe.
Le rsultat dun appel find(list) sera de la forme suivante :
Array
(
//[id]
[1] =>
[2] =>
[4] =>
[5] =>
[6] =>
[3] =>
)
=> 'valeurAffichage',
'valeurAffichage1',
'valeurAffichage2',
'valeurAffichage4',
'valeurAffichage5',
'valeurAffichage6',
'valeurAffichage3',
En appelant find(list), les champs (fields) passs sont utiliss pour dterminer ce qui devrait
tre utilis comme cl, valeur du tableau et, optionnellement, par quoi regrouper les rsultats (group by). Par
dfaut la cl primaire du model est utilis comme cl et le champ affich (display field qui peut tre configur
en utilisant lattribut displayField du model) est utilis pour la valeur. Quelques exemples complmentaires
pour clarifier les choses :
Pour en savoir plus sur les Models
229
Avec lexemple de code ci-dessus, les variables rsultantes devraient ressembler quelque chose comme
cela :
$juste_les_usernames = Array
(
//[id] => 'username',
[213] => 'AD7six',
[25] => '_psychic_',
[1] => 'PHPNut',
[2] => 'gwoo',
[400] => 'jperras',
)
$correspondanceUsername = Array
(
//[username] => 'firstname',
['AD7six'] => 'Andy',
['_psychic_'] => 'John',
['PHPNut'] => 'Larry',
['gwoo'] => 'Gwoo',
['jperras'] => 'Jol',
)
$groupesUsername = Array
(
['Utilisateur'] => Array
(
['PHPNut'] => 'Larry',
['gwoo'] => 'Gwoo',
)
['Admin'] => Array
(
['_psychic_'] => 'John',
['AD7six'] => 'Andy',
['jperras'] => 'Jol',
)
)
230
find(threaded)
find(threaded, $params) retourne un tableau imbriqu et est particulirement appropri si vous
voulez utiliser le champ parent_id des donnes de votre model, pour construire les rsultats associs.
Ci-dessous, quelques exemples simples (code du controller) :
public function une_function() {
// ...
$toutesLesCategories = $this->Category->find('threaded');
$quelquesCategories = $this->Comment->find('threaded', array(
'conditions' => array('article_id' => 50)
));
// ...
}
Astuce : Un meilleur moyen de grer les donnes imbriques est dutiliser le behavior Tree
Dans lexemple ci-dessus, $toutesLesCategories contiendra un tableau imbriqu reprsentant la
structure entire de categorie. Le rsultat dun appel find(threaded) sera de la forme suivante :
Array
(
[0] => Array
(
[NomDuModel] =>
(
[id] => 83
[parent_id]
[champ1] =>
[champ2] =>
[champ3] =>
)
Array
=> null
valeur1
valeur2
valeur3
Array
=> 83
valeur1
valeur2
valeur3
231
)
[NomDuModelAssocie] => Array
(
[id] => 2
[champ1] => valeur1
[champ2] => valeur2
[champ3] => valeur3
)
[children] => Array
(
)
)
...
)
)
)
Lordre dans lequel les rsultats apparaissent peut tre modifi, puisquil est influenc par lordre dexcution. Par exemple, si order => name ASC est pass dans les paramtres de
find(threaded), les rsultats apparatront ordonns par nom. De mme que tout ordre peut tre
utilis, il ny a pas de condition intrinsque cette mthode pour que le meilleur rsultat soit retourn en
premier.
Avertissement : Si vous spcifiez fields, vous aurez besoin de toujours inclure id & parent_id (ou
leurs alias courants) :
public function some_function() {
$categories = $this->Category->find('threaded', array(
'fields' => array('id', 'name', 'parent_id')
));
}
find(neighbors)
find(neighbors, $params) excutera un find similaire first, mais retournera les lignes prcdentes et suivantes celle que vous requtez. Ci-dessous, un exemple simple (code du controller) :
public function some_function() {
$neighbors = $this->Article->find(
'neighbors',
array('field' => 'id', 'value' => 3)
);
}
Vous pouvez voir dans cet exemple, les deux lments requis par le tableau $params : field et value.
Les autres lments sont toujours autoriss, comme dans tout autre find (Ex : si votre model agit comme
232
un containable, alors vous pouvez spcifier contain dans $params). Le format retourn par un appel
find(neighbors) est de la forme :
Array
(
[prev] => Array
(
[NomDuModel] => Array
(
[id] => 2
[champ1] => valeur1
[champ2] => valeur2
...
)
[NomDuModelAssocie] => Array
(
[id] => 151
[champ1] => valeur1
[champ2] => valeur2
...
)
)
[next] => Array
(
[NomDuModel] => Array
(
[id] => 4
[champ1] => valeur1
[champ2] => valeur2
...
)
[NomDuModelAssocie] => Array
(
[id] => 122
[champ1] => valeur1
[champ2] => valeur2
...
)
)
)
Note : Notez que le rsultat contient toujours seulement deux lments de premier niveau : prev et next.
Cette fonction ne possde pas de variable rcursive par dfaut dun model. Le paramtre rcursif doit tre
pass dans les paramtres de chaque appel.
233
Un type de recherche Model est un raccourci pour les options de recherche. Par exemple, les deux finds
suivants sont quivalents
$this->User->find('first');
$this->User->find('all', array('limit' => 1));
true);
Au fond, cela dit juste CakePHP daccepter la valeur available pour premier argument de la fonction
find. Prochaine tape est lintgration de la fonction _findAvailable. Cela est fait par convention,
si vous voulez intgrer un finder appel maSuperRecherche ensuite la mthode intgrer sappellera
_findMaSuperRecherche.
class Article extends AppModel {
public $findMethods = array('available' =>
true);
234
Les mthodes spciales _find[Type] reoivent 3 arguments comme montr ci-dessus. Le premier signifie
que ltat de lexcution de la requte, qui peut tre soit before ou after. Cela est fait de cette faon
parce que cette fonction est juste une sorte de fonction callback qui a la capacit de modifier la requte avant
quelle se fasse, ou de modifier les rsultats aprs quils sont rcuprs.
Typiquement, la premire chose vrifier dans notre fonction find est ltat de la requte. Ltat before
est le moment de modifier la requte, de former les nouvelles associations, dappliquer plus de behaviors,
et dinterprter toute cl spciale qui est pass dans le deuxime argument de find. Cet tat ncessite que
vous retourniez largument $query (modifi ou non).
Ltat after est lendroit parfait pour inspecter les rsultats, injecter de nouvelles donnes, le traiter pour
retourner dans un autre format, ou faire ce que vous voulez sur les donnes fraichement rcupres. Cet tat
ncessite que vous retourniez le tableau $results (modifi ou non).
Vous pouvez crer autant de finders personnaliss que vous souhaitez, et ils sont une bonne faon de rutiliser
du code dans votre application travers les models.
Il est aussi possible de paginer grce un find personnalis en utilisant loption findType comme suit :
class ArticlesController extends AppController {
// Va paginer tous les articles publis
public function index() {
$this->paginate = array('findType' => 'available');
$articles = $this->paginate();
$this->set(compact('articles'));
}
}
Configurer la proprit $this->paginate comme ci-dessus dans le controller fera que le type de find
deviendra available, et vous permettra aussi de continuer modifier les rsultats trouvs.
Pour simplement retourner le nombre dun type find personnalis, appelez count comme vous le feriez
habituellement, mais passez le type de find dans un tableau dans le second argument.
class ArticlesController extends AppController {
// Va rcuprer le nombre d'articles publis (en utilisant le find available dfini cipublic function index() {
$count = $this->Article->find('count', array(
'type' => 'available'
));
}
}
Si le compte de votre page de pagination devient fausse, il peut tre ncessaire dajouter le code suivant
votre AppModel, ce qui devrait rgler le compte de pagination :
class AppModel extends Model {
/**
* Removes 'fields' key from count query on custom finds when it is an array,
* as it will completely break the Model::_findCount() call
235
*
* @param string $state Either "before" or "after"
* @param array $query
* @param array $results
* @return int The number of records found, or false
* @access protected
* @see Model::find()
*/
protected function _findCount($state, $query, $results = array()) {
if ($state === 'before') {
if (isset($query['type']) &&
isset($this->findMethods[$query['type']])) {
$query = $this->{
'_find' . ucfirst($query['type'])
}('before', $query);
if (!empty($query['fields']) && is_array($query['fields'])) {
if (!preg_match('/^count/i', current($query['fields']))) {
unset($query['fields']);
}
}
}
}
return parent::_findCount($state, $query, $results);
}
}
?>
236
Depuis 2.8, vous pouvez utiliser une mthode finder personnalise avec linterface de la mthode magique.
Par exemple, si votre model implmente un finder published, vous pouvez utiliser ces finders avec la
mthode magique findBy :
$results = $this->Article->findPublishedByAuthorId(5);
// Est quivalent
$this->Article->find('published', array(
'conditions' => array('Article.author_id' => 5)
));
Introduit dans la version 2.8.0 : Les finders magiques personnaliss ont t ajouts dans 2.8.0.
findBy
findBy<fieldName>(string $value);
Pour en savoir plus sur les Models
237
pourrait retourner :
Array
(
[0] => Array
(
[pictures] => Array
(
[id] => 1304
[user_id] => 759
)
)
[1] => Array
(
[pictures] => Array
238
(
[id] => 1305
[user_id] => 759
)
)
)
Pour utiliser le nom du model comme cl du tableau et obtenir un rsultat cohrent avec ce qui est retourn
par les mthodes Find, la requte doit tre rcrite :
$this->Picture->query("SELECT * FROM pictures AS Picture LIMIT 2;");
ce qui retourne :
Array
(
[0] => Array
(
[Picture] => Array
(
[id] => 1304
[user_id] => 759
)
)
[1] => Array
(
[Picture] => Array
(
[id] => 1305
[user_id] => 759
)
)
)
Note : Cette syntaxe et la structure de tableau correspondante est valide seulement pour MySQL. CakePHP
ne fournit pas de donnes dabstraction quand les requtes sont lances manuellement, donc les rsultats
exacts vont varier entre les bases de donnes.
Model::field()
field(string $name, array $conditions = null, string $order = null)
Retourne la valeur dun champ unique, spcifi par $name, du premier enregistrement correspondant aux
$conditions ordonnes par $order. Si aucune condition nest passe et que lid du model est fix, la fonction
retournera la valeur du champ pour le rsultat de lenregistrement actuel. Si aucun enregistrement correspondant nest trouv cela retournera false.
$this->Post->id = 22;
echo $this->Post->field('name'); // affiche le nom pour la ligne avec l'id 22
239
Model::read()
read($fields, $id)
read() est une mthode utilise pour rcuprer les donnes du model courant (Model::$data) - comme
lors des mises jour - mais elle peut aussi tre utilise dans dautres circonstances, pour rcuprer un seul
enregistrement depuis la base de donnes.
$fields est utilise pour passer un seul nom de champ sous forme de chane ou un tableau de noms de
champs ; si laisse vide, tous les champs seront retourns.
$id prcise lID de lenregistrement lire. Par dfaut, lenregistrement actuellement slectionn, tel que
spcifi par Model::$id, est utilis. Passer une valeur diffrente pour $id fera que lenregistrement
correspondant sera slectionn.
read() retourne toujours un tableau (mme si seulement un nom de champ unique est requis). Utilisez
field pour retourner la valeur dun seul champ.
Avertissement : Puisque la mthode read crase toute information stocke dans les proprits data
et id du model, vous devez faire trs attention quand vous utilisez cete fonction en gnral, spcialement
en lutilisant dans les fonctions de callbacks du model comme beforeValidate et beforeSave.
Gnralement la fonction find est une faon de faire plus robuste et facile utiliser avec lAPI que la
mthode read.
240
La structure ici est assez significative : elle va trouver tous les posts o le titre pour valeur This is a post
et o lid de lauteur est gal 1. Nous aurions pu uniquement utiliser title comme nom de champ,
mais lorsque lon construit des requtes, il vaut mieux toujours spcifier le nom du model. Cela amliore la
clart du code, et vite des collisions futures, dans le cas o vous devriez changer votre schma.
Quen est-il des autres types de correspondances ? Elles sont aussi simples. Disons que nous voulons trouver
tous les posts dont le titre nest pas Ceci est un post :
array("Post.titre !=" => "Il y a un post")
Notez le != qui prcde lexpression. CakePHP peut parser tout oprateur de comparaison valide de SQL,
mme les expressions de correspondance utilisant LIKE, BETWEEN, ou REGEX, tant que vous laissez un espace entre loprateur et la valeur. Les seules exceptions ceci sont les correspondances du genre IN(...).
Admettons que vous vouliez trouver les posts dont le titre appartient un ensemble de valeurs donnes :
array(
"Post.titre" => array("Premier post", "Deuxime post", "Troisime post")
)
Faire un NOT IN(...) correspond trouver les posts dont le titre nest pas dans le jeu de donnes pass :
array(
"NOT" => array(
"Post.titre" => array("First post", "Second post", "Third post")
)
)
Ajouter des filtres supplmentaires aux conditions est aussi simple que dajouter des paires cl/valeur au
tableau :
array (
"Post.titre" => array("Premier post", "Deuxime post", "Troisime post"),
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
)
Vous pouvez galement crer des recherches qui comparent deux champs de la base de donnes :
array("Post.created = Post.modified")
Lexemple ci-dessus retournera les posts o la date de cration est gale la date de modification (par ex les
posts qui nont jamais t modifis sont retourns).
Souvenez-vous que si vous vous trouvez dans lincapacit de formuler une clause WHERE par cette mthode
(ex. oprations boolennes), il vous est toujours possible de la spcifier sous forme de chane comme ceci :
array(
'Model.champ & 8 = 1',
// autres conditions habituellement utilises
)
241
Par dfaut, CakePHP fournit les conditions multiples avec loprateur boolen AND, ce qui signifie que le
bout de code ci-dessous correspondra uniquement aux posts qui ont t crs durant les deux dernires
semaines, et qui ont un titre correspondant ceux donns. Cependant, nous pouvons simplement trouver les
posts qui correspondent lune ou lautre des conditions :
array("OR" => array(
"Post.titre" => array("Premier post", "Deuxime post", "Troisime post"),
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
))
CakePHP accepte toute opration boolenne SQL valide, telles que AND, OR, NOT, XOR, etc., et elles peuvent
tre en majuscule comme en minuscule, comme vous prfrez. Ces conditions sont galement infiniment
IMBRIQUABLES. Admettons que vous ayez une relation hasMany/belongsTo entre Posts et Auteurs, ce
qui reviendrait un LEFT JOIN. Admettons aussi que vous vouliez trouver tous les posts qui contiennent
un certain mot-cl magique ou qui a t cr au cours des deux dernires semaines, mais que vous voulez
restreindre votre recherche aux posts crits par Bob :
array(
"Auteur.nom" => "Bob",
"OR" => array(
"Post.titre LIKE" => "%magic%",
"Post.created >" => date('Y-m-d', strtotime("-2 weeks"))
)
)
Si vous avez besoin de mettre plusieurs conditions sur le mme champ, comme quand vous voulez faire une
recherche LIKE avec des termes multiples, vous pouvez faire ceci en utilisant des conditions identiques :
array('OR' => array(
array('Post.titre LIKE' => '%one%'),
array('Post.titre LIKE' => '%two%')
))
Les oprateurs wildcard ILIKE et RLIKE (RLIKE depuis la version 2.6) sont aussi disponible.
CakePHP peut aussi vrifier les champs null. Dans cet exemple, la requte retournera les enregistrements o
le titre du post nest pas null :
array("NOT" => array(
"Post.titre" => null
)
)
Note : CakePHP quotera les valeurs numriques selon le type du champ dans votre base de donnes.
Quen est-il de GROUP BY ? :
242
array(
'fields' => array(
'Produit.type',
'MIN(Produit.prix) as prix'
),
'group' => 'Produit.type'
)
Un exemple rapide pour faire une requte DISTINCT. Vous pouvez utiliser dautres oprateurs, comme
MIN(), MAX(), etc..., dune manire analogue :
array(
'fields' => array('DISTINCT (User.nom) AS nom_de_ma_colonne'),
'order' =>array('User.id DESC')
)
Vous pouvez crer des conditions trs complexes, en regroupant des tableaux de conditions multiples :
array(
'OR' => array(
array('Entreprise.nom' => 'Futurs Gains'),
array('Entreprise.ville' => 'CA')
),
'AND' => array(
array(
'OR' => array(
array('Entreprise.status' => 'active'),
'NOT' => array(
array('Entreprise.status' => array('inactive', 'suspendue'))
)
)
)
)
)
243
Sous requtes
Par exemple, imaginons que nous ayons une table users avec id, nom et statuts. Le statuts peut tre
A, B ou C. Et nous voulons rcuprer tous les users qui ont un statut diffrent de B en utilisant une
sous requte.
Pour pouvoir effectuer cela, nous allons appeler la source de donnes du model et lui demander de construire
la requte comme si nous appelions une mthode find, mais elle retournera uniquement la commande SQL.
Aprs cela, nous construisons une expression et lajoutons au tableau des conditions :
$conditionsSubQuery['"User2"."status"'] = 'B';
$db = $this->Utilisateur->getDataSource();
$subQuery = $db->buildStatement(
array(
'fields'
=> array('"User2"."id"'),
'table'
=> $db->fullTableName($this->User),
'alias'
=> 'User2',
'limit'
=> null,
'offset'
=> null,
'joins'
=> array(),
'conditions' => $conditionsSubQuery,
'order'
=> null,
'group'
=> null
),
$this->User
);
$subQuery = ' "User"."id" NOT IN (' . $subQuery . ') ';
$subQueryExpression = $db->expression($subQuery);
$conditions[] = $subQueryExpression;
$this->User->find('all', compact('conditions'));
244
SELECT
"User"."id" AS "User__id",
"User"."name" AS "User__nom",
"User"."status" AS "User__status"
FROM
"users" AS "User"
WHERE
"User"."id" NOT IN (
SELECT
"User2"."id"
FROM
"users" AS "User2"
WHERE
"User2"."status" = 'B'
)
Aussi, si vous devez passer juste une partie de votre requte en colonne SQL comme ci-dessus, la source de
donnes expressions avec la colonne SQL fonctionne pour toute partie de requte find.
Requtes Prpares
Si vous avez besoin dencore plus de contrle sur vos requtes, vous pouvez utiliser des requtes prpares.
Cela vous permet de parler directement au driver de la base de donnes et denvoyer toute requte personnalise que vous souhaitez :
$db = $this->getDataSource();
$db->fetchAll(
'SELECT * from users where username = ? AND password = ?',
array('jhon', '12345')
);
$db->fetchAll(
'SELECT * from users where username = :username AND password = :password',
array('username' => 'jhon','password' => '12345')
);
245
La plupart du temps vous naurez mme pas vous proccuper de ce format : le FormHelper et les
mthodes de recherche de CakePHP runissent les donnes sous cette forme. Si vous utilisez un de ces
helpers, les donnes sont galement disponibles dans $this->request->data pour un usage rapide et
pratique.
Voici un exemple simple dune action de controller qui utilise un model CakePHP pour sauvegarder les
donnes dans une table de la base de donnes
public function edit($id) {
//Est-ce que des donnes de formulaires ont t POSTes ?
if ($this->request->is('post')) {
//Si les donnes du formulaire peuvent tre valides et sauvegardes ...
if($this->Recipe->save($this->request->data)) {
//On dfinit une message flash en session et on redirige.
$this->Session->setFlash("Recipe sauvegarde !");
return $this->redirect('/recettes');
}
}
//Si aucune donnes de formulaire, on rcupre la recipe diter
//et on la passe la vue
$this->set('recipe', $this->Recipe->findById($id));
}
Quand save() est appele, la donne qui lui est passe en premier paramtre est valide en utilisant
le mcanisme de validation de CakePHP (voir le chapitre Validation des Donnes pour plus dinformations). Si pour une raison quelconque vos donnes ne se sauvegardent pas, pensez regarder si
des rgles de validation ne sont pas insatisfaites. Vous pouvez dbugger cette situation en affichant
Model::$validationErrors :
if ($this->Recipe->save($this->request->data)) {
// Traite le succs.
}
debug($this->Recipe->validationErrors);
Il y a quelques autres mthodes du model lies la sauvegarde que vous trouverez utiles :
Model::set($one, $two = null)
Model::set() peut tre utilis pour dfinir un ou plusieurs champs de donnes du tableau de donns
lintrieur dun Model. Cest utile pour lutilisation de models avec les fonctionnalits ActiveRecord offertes
par le model :
$this->Post->read(null, 1);
$this->Post->set('title', 'Nouveau titre pour l\'article');
$this->Post->save();
Cest un exemple de lutilisation de set() pour mettre jour les champs uniques, dans une approche
ActiveRecord. Vous pouvez aussi utiliser set() pour assigner de nouvelles valeurs aux champs multiples :
246
$this->Post->read(null, 1);
$this->Post->set(array(
'title' => 'Nouveau titre',
'published' => false
));
$this->Post->save();
Ce qui est au-dessus met jour les champs title et published et sauvegarde lenregistrement dans le base de
donnes.
Model::clear()
Cette mthode peut tre utilise pour rinitialiser ltat du model et effacer toutes les donnes non sauvegardes et les erreurs de validation.
Introduit dans la version 2.4.
Model::save(array $data = null, boolean $validate = true, array
$fieldList = array())
La mthode ci-dessus sauvegarde des donnes formates sous forme tabulaire. Le second paramtre vous
permet de mettre de ct la validation, et le troisime vous permet de fournir une liste des champs du model
devant tre sauvegards. Pour une scurit accrue, vous pouvez limiter les champs sauvegards ceux lists
dans $fieldList.
Note : Si $fieldList nest pas fourni, un utilisateur malicieux peut ajouter des champs supplmentaires
dans le formulaire de donnes (si vous nutilisez pas SecurityComponent), et ainsi changer la valeur
de champs qui ntaient pas prvus lorigine.
La mthode save a aussi une syntaxe alternative :
save(array $data = null, array $params = array())
247
$this->Ingredient->save($nouvellesDonnees);
$nouvelIngredientId = $this->Ingredient->id;
La cration ou la mise jour est contrle par le champ id du model. Si $Model->id est dfini, lenregistrement avec cette cl primaire est mis jour. Sinon, un nouvel enregistrement est cr :
// Cration: id n'est pas dfini ou est null
$this->Recipe->create();
$this->Recipe->save($this->request->data);
// Mise jour: id est dfini une valeur numrique
$this->Recipe->id = 2;
$this->Recipe->save($this->request->data);
Astuce : Lors de lappel save() dans une boucle, noubliez pas dappeler clear().
Si vous voulez mettre jour une valeur, plutt quen crer une, assurez-vous que vous avez pass le champ
de la cl primaire dans le tableau data :
$data = array('id' => 10, 'title' => 'Mon Nouveau Titre');
// Cela mettra jour la Recipe avec un id 10
$this->Recipe->save($data);
248
Par exemple, pour mettre jour le titre dun article de blog, lappel depuis un controller saveField
ressemblerait quelque chose comme :
$this->Post->saveField('title', 'Un nouveau titre pour un Nouveau Jour');
Avertissement : Vous ne pouvez pas arrter la mise jour du champ modified avec cette mthode,
vous devrez utiliser la mthode save().
La mthode saveField a aussi une syntaxe alternative :
saveField(string $fieldName, string $fieldValue, array $params = array())
Le tableau $fields accepte des expressions SQL. Les valeurs littrales doivent tre manuellement
quotes en utilisant DboSource::value(). Par exemple, si une de vos mthodes de model appelait
updateAll(), vous feriez ce qui suit :
$db = $this->getDataSource();
$value = $db->value($value, 'string');
$this->updateAll(
array('Baker.status' => $value),
array('Baker.status' => 'old')
);
Note : Mme si le champ modifi existe pour le model qui vient dtre mis jour, il ne sera pas mis
jour automatiquement par lORM. Ajoutez le seulement manuellement au tableau si vous avez besoin de le
mettre jour.
249
Par exemple, pour fermer tous les tickets qui appartiennent un certain client :
$this->Ticket->updateAll(
array('Ticket.status' => "'closed'"),
array('Ticket.client_id' => 453)
);
Par dfaut, updateAll() joindra automatiquement toute association belongsTo pour les bases de donnes qui
suportent la jointure. Pour viter cela, dlier les associations temporairement.
Model::saveMany(array $data = null, array $options = array())
La mthode utilise pour sauvegarder les lignes multiples du mme model en une fois. Les options suivantes
peuvent tre utilises :
validate : Dfinie false pour dsactiver la validation, true pour valider chaque enregistrement avant
la sauvegarde, first pour valider tous les enregistrements avant quun soit sauvegard (par dfaut),
atomic : Si true (par dfaut), essaiera de sauvegarder tous les enregistrements en une seule transaction.
Devrait tre dfinie false si la base de donnes/table ne supporte pas les transactions.
fieldList : Equivalent au paramtre $fieldList dans Model : :save()
deep : (since 2.1) Si dfini true, les donnes associes sont aussi sauvegardes, regardez aussi saveAssociated.
callbacks Dfini false pour dsactiver les callbacks. En utilisant before ou after va activer seulement ces callbacks.
counterCache (depuis 2.4) Boolen pour contrler la mise jour des counter caches (si il y en a).
Pour sauvegarder de multiples enregistrements dun unique model, $data a besoin dtre un tableau denregistrements index numriquement comme ceci :
$data = array(
array('title' => 'titre 1'),
array('title' => 'titre 2'),
)
Note : Notez que nous passons les indices numriques de la variable habituelle $data contenant le cl Article. Quand vous passez plusieurs enregistrements du mme model, les tableaux denregistrements doivent
tre seulement indexs numriquement sans la cl model.
Il est aussi possible davoir les donnes dans le format suivant :
$data = array(
array('Article' => array('title' => 'title 1')),
array('Article' => array('title' => 'title 2')),
)
Pour sauvegarder les donnes associes avec $options[deep] = true (depuis 2.1), les deux exemples ci-dessus ressembleraient cela :
$data = array(
array('title' => 'title 1', 'Assoc' => array('field' => 'value')),
array('title' => 'title 2'),
250
);
$data = array(
array(
'Article' => array('title' => 'title 1'),
'Assoc' => array('field' => 'value')
),
array('Article' => array('title' => 'title 2')),
);
$Model->saveMany($data, array('deep' => true));
Gardez lesprit que si vous souhaitez mettre jour un enregistrement au lieu den crer un nouveau, vous
devez juste ajouter en index la cl primaire la ligne de donne :
array(
// Ceci cre une nouvelle ligne
array('Article' => array('title' => 'New article')),
// Ceci met jour une ligne existante
array('Article' => array('id' => 2, 'title' => 'title 2')),
)
Pour sauvegarder un enregistrement et ses enregistrements lis avec une association hasMany, le tableau de
donnes devra ressembler cela :
$data = array(
'Article' => array('title' => 'My first article'),
'Comment' => array(
array('body' => 'Comment 1', 'user_id' => 1),
array('body' => 'Comment 2', 'user_id' => 12),
array('body' => 'Comment 3', 'user_id' => 40),
251
),
);
Et pour sauvegarder un enregistrement avec ses enregistrements lis par hasMany qui ont plus de deux
niveaux dassociation de profondeur, le tableau de donnes devra tre comme suit :
$data = array(
'User' => array('email' => 'john-doe@cakephp.org'),
'Cart' => array(
array(
'payment_status_id' => 2,
'total_cost' => 250,
'CartItem' => array(
array(
'cart_product_id' => 3,
'quantity' => 1,
'cost' => 100,
),
array(
'cart_product_id' => 5,
'quantity' => 1,
'cost' => 150,
)
)
)
)
);
Note : Si cela russit, la cl trangre du model principal va tre stocke dans le champ id du model li, par
ex : $this->RelatedModel->id.
Avertissement : Attention quand vous vrifiez les appels saveAssociated avec loption atomic dfinie
false. Elle retourne un tableau au lieu dun bolen.
Modifi dans la version 2.1 : Vous pouvez maintenant aussi sauvegarder les donnes associes avec la
configuration $options[deep] = true;.
Pour sauvegarder un enregistrement et ses enregistrements lis avec une association hasMany ainsi que
les donnes associes plus profondment de type Comment belongsTo User, le tableau de donnes devra
ressembler ceci :
$data = array(
'Article' => array('title' => 'My first article'),
'Comment' => array(
array('body' => 'Comment 1', 'user_id' => 1),
array(
'body' => 'Save a new user as well',
'User' => array('first' => 'mad', 'last' => 'coder')
),
),
);
252
Modifi dans la version 2.1 : Model::saveAll() et ses amis supportent maintenant quon leur passe
fieldList pour des models multiples.
Exemple dutilisation de fieldList avec de multiples models :
$this->SomeModel->saveAll($data, array(
'fieldList' => array(
'SomeModel' => array('field_1'),
'AssociatedModel' => array('field_2', 'field_3')
)
));
La fieldList sera un tableau dalias de model en cl et de tableaux avec les champs en valeur. Les noms de
model ne sont pas imbriqus comme dans les donnes sauvegarder.
Model::saveAll(array $data = null, array $options = array())
La fonction saveAll est juste un wrapper autour des mthodes saveMany et saveAssociated. Elle
va inspecter les donnes et dterminer quel type de sauvegarde elle devra effectuer. Si les donnes sont bien
formates en un tableau indic numriquement, saveMany sera appele, sinon saveAssociated sera
utilise.
Cette fonction reoit les mmes options que les deux prcdentes, et est gnralement une fonction rtrocompatible. Il est recommand dutiliser soit saveMany soit saveAssociated selon le cas.
Sauvegarder les Donnes de Models Lis (hasOne, hasMany, belongsTo)
Quand vous travaillez avec des models associs, il est important de raliser que la sauvegarde de donnes
de model devrait toujours tre faite avec le model CakePHP correspondant. Si vous sauvegardez un nouveau Post et ses Comments associs, alors vous devriez utiliser les deux models Post et Comment pendant
lopration de sauvegarde.
Si aucun des enregistrements du model associ nexiste pour linstant dans le systme (par exemple, vous
voulez sauvegarder un nouveau User et ses enregistrements du Profile li en mme temps), vous aurez besoin
de sauvegarder dabord le model principal, ou le model parent.
Pour avoir une bonne ide de la faon de faire, imaginons que nous ayons une action dans notre UsersController qui gre la sauvegarde dun nouveau User et son Profile li. Laction montre en exemple ci-dessous
supposera que vous avez POST assez de donnes (en utilisant FormHelper) pour crer un User unique et
un Profile unique :
public function add() {
if (!empty($this->request->data)) {
// Nous pouvons sauvegarder les donnes de l'User:
// it should be in $this->request->data['User']
$user = $this->User->save($this->request->data);
253
Comme rgle, quand vous travaillez avec des associations hasOne, hasMany, et belongsTo, tout est question
de cl. Lide de base est de rcuprer la cl dun autre model et de la placer dans le champ cl trangre sur
lautre. Parfois, cela pourra gner lutilisation de lattribut $id de la classe model aprs un save(), mais
dautres fois, cela impliquera juste la collecte de lID provenant dun champ cach dun formulaire qui vient
dtre POST dune action dun controller.
Pour complter lapproche fondamentale utilise ci-dessus, CakePHP offre galement une mthode trs
pratique saveAssociated(), qui vous permet de valider et de sauvegarder de multiples models en une
fois. De plus, saveAssociated() fournit un support transactionnel pour sassurer de lintgrit des
donnes dans votre base de donnes (par ex : si un model choue dans la sauvegarde, les autres models ne
seront galement pas sauvegards).
Note : Pour que les transactions fonctionnent correctement dans MySQL, vos tables doivent utiliser le
moteur InnoDB. Souvenez-vous que les tables MyISAM ne supportent pas les transactions.
Voyons comment nous pouvons utiliser saveAssociated() pour sauvegarder les models Company et
Account en mme temps.
Tout dabord, vous avez besoin de construire votre formulaire pour les deux models Company et Account
(nous supposerons que Company hasMany Account) :
echo
echo
echo
echo
Regardez comment nous avons nomm les champs de formulaire pour le model Account. Si Company est
notre model principal, saveAssociated() va sattendre ce que les donnes du model li (Account)
arrivent dans un format spcifique. Et avoir Account.0.fieldName est exactement ce dont nous avons
besoin.
254
Note : Le champ ci-dessus est ncessaire pour une association hasMany. Si lassociation entre les models
est hasOne, vous devrez utiliser la notation ModelName.fieldName pour le model associ.
Maintenant, dans notre CompaniesController nous pouvons crer une action add() :
public function add() {
if (!empty($this->request->data)) {
// Utilisez ce qui suit pour viter les erreurs de validation:
unset($this->Company->Account->validate['company_id']);
$this->Company->saveAssociated($this->request->data);
}
}
Cest tout pour le moment. Maintenant nos models Company et Account seront valids et sauvegards en
mme temps. Par dfaut saveAssociated validera toutes les valeurs passes et ensuite essaiera deffectuer une sauvegarde pour chacun.
Sauvegarder hasMany through data
Regardons comment les donnes stockes dans une table jointe pour deux models sont sauvegardes.
Comme montr dans la section hasMany through (Le Model Join), la table jointe est associe pour chaque
model en utilisant un type de relation hasMany. Notre exemple est une problmatique lance par la Tte de
lEcole CakePHP qui nous demande dcrire une application qui lui permette de connecter la prsence dun
tudiant un cours avec les journes assistes et valides. Jettez un il au code suivant.
// Controller/CourseMembershipController.php
class CourseMembershipsController extends AppController {
public $uses = array('CourseMembership');
public function index() {
$this->set(
'courseMembershipsList',
$this->CourseMembership->find('all')
);
}
public function add() {
if ($this->request->is('post')) {
if ($this->CourseMembership->saveAssociated($this->request->data)) {
return $this->redirect(array('action' => 'index'));
}
}
}
}
// View/CourseMemberships/add.ctp
<?php echo $this->Form->create('CourseMembership'); ?>
<?php echo $this->Form->input('Student.first_name'); ?>
<?php echo $this->Form->input('Student.last_name'); ?>
255
CakePHP va heureusement tre capable de sauvegarder le lot ensemble et dassigner les cls trangres
de Student et de Course dans CourseMembership avec un appel saveAssociated avec cette structure de
donnes. Si nous lanons laction index de notre CourseMembershipsController, la structure de donnes
reue maintenant par un find(all) est :
Array
(
[0] => Array
(
[CourseMembership] => Array
(
[id] => 1
[student_id] => 1
[course_id] => 1
[days_attended] => 5
[grade] => A
)
[Student] => Array
(
[id] => 1
[first_name] => Joe
[last_name] => Bloggs
)
256
Il y a bien sr beaucoup de faons de travailler avec un model joint. La version ci-dessus suppose que
vous voulez sauvegarder tout en une fois. Il y aura des cas o vous voudrez crer les Student et Course
indpendamment et associer les deux ensemble avec CourseMemberShip plus tard. Donc, vous aurez peuttre un formulaire qui permet la slection de students et de courses existants partir dune liste de choix ou
dune entre dun ID et ensuite les deux meta-champs pour CourseMembership, par ex.
// View/CourseMemberships/add.ctp
<?php echo $this->Form->create('CourseMembership'); ?>
<?php
echo $this->Form->input(
'Student.id',
array(
'type' => 'text',
'label' => 'Student ID',
'default' => 1
)
);
?>
<?php
echo $this->Form->input(
'Course.id',
array(
'type' => 'text',
'label' => 'Course ID',
'default' => 1
)
);
?>
<?php echo $this->Form->input('CourseMembership.days_attended'); ?>
<?php echo $this->Form->input('CourseMembership.grade'); ?>
<button type="submit">Save</button>
<?php echo $this->Form->end(); ?>
Et le POST rsultant :
Array
(
[Student] => Array
(
[id] => 1
)
[Course] => Array
257
(
[id] => 1
)
[CourseMembership] => Array
(
[days_attended] => 10
[grade] => 5
)
)
Encore une fois, CakePHP est bon pour nous et envoie les id de Student et de Course dans CourseMembership avec saveAssociated.
Sauvegarder les Donnes de Model Li (HABTM=HasAndBelongsToMany)
Sauvegarder les models qui sont associs avec hasOne, belongsTo, et hasMany est assez simple : vous venez
de remplir le champ de la cl trangre avec lID du model associ. Une fois que cest fait, vous appelez
juste la mthode save() sur un model, et tout se relie correctement. Un exemple du format requis pour le
tableau de donnes pass save() pour le model Tag model est montr ci-dessous :
Array
(
[Recipe] => Array
(
[id] => 42
)
[Tag] => Array
(
[name] => Italian
)
)
Vous pouvez aussi utiliser ce format pour sauvegarder plusieurs enregistrements et leurs associations
HABTM avec saveAll(), en utilisant un tableau comme celui qui suit :
Array
(
[0] => Array
(
[Recipe] => Array
(
[id] => 42
)
[Tag] => Array
(
[name] => Italian
)
)
[1] => Array
(
258
Passer le tableau ci-dessus saveAll() va crer les tags contenus, chacun associ avec leur recipies
respectives.
Un autre exemple utile est lorsque quand vous souhaitez sauver de nombreusex Tags dans un Post. Vous
devez transmettre les donnes HABTM associes dans le format de tableau HABTM suivant. Notez que
vous devez passer uniquement lid du modle HABTM associ mais il doit tre imbriques nouveau :
Array
(
[0] => Array
(
[Post] => Array
(
[title] => 'Saving HABTM arrays'
)
[Tag] => Array
(
[Tag] => Array(1, 2, 5, 9)
)
)
259
Dans cet exemple, vous pouvez voir le champ cach Recipe.id dont la valeur est dfinie selon lID de la
recette que nous voulons lier au tag.
260
Quand la mthode save() est appele dans le controller, elle va automatiquement sauvegarder les donnes
HABTM dans la base de donnes :
public function add() {
// Sauvegarder l'association
if ($this->Tag->save($this->request->data)) {
// faire quelque chose en cas de succs
}
}
Avec le code prcdent, notre Tag nouveau est cre et associ avec un Recipe, dont lID a t dfini dans
$this->request->data[Recipe][id].
Les autres faons possibles pour prsenter nos donnes associes peuvent inclure une liste droulante. Les
donnes peuvent tre envoyes dun model en utilisant la mthode find(list) et assignes une
variable de vue du nom du model. Une entre avec le mme nom va automatiquement envoyer ces donnes
dans un <select> :
// dans le controller:
$this->set('tags', $this->Recipe->Tag->find('list'));
// dans la vue:
$form->input('tags');
Un scnario plus probable avec une relation HABTM incluerait un <select> dfini pour permettre des
slections multiples. Par exemple, un Recipe peut avoir plusieurs Tags lui tant assigns. Dans ce cas, les
donnes du model sont tries de la mme faon, mais lentre du formulaire est dclare lgrement diffremment. Le nom du Tag est dfini en utilisant la convention ModelName :
// dans le controller:
$this->set('tags', $this->Recipe->Tag->find('list'));
// dans la vue:
$this->Form->input('Tag');
En utilisant le code prcdent, un liste droulante est cre, permettant aux multiples choix dtre automatiquement sauvegards au Recipe existant en tant ajout la base de donnes.
Self HABTM Normalement HABTM est utilis pour lier 2 models ensemble mais il peut aussi tre utilis
avec seulement 1 model, mais il ncssite une attention plus grande encore.
La cl est dans la configuration du model className. En ajoutant simplement une relation Project
HABTM Project entraine des problmes lors des enregistrements de donnes. En configurant le
className au nom de models et en utilisant lalias en cl, nous vitons ces problmes.
class Project extends AppModel {
public $hasAndBelongsToMany = array(
'RelatedProject' => array(
'className'
=> 'Project',
'foreignKey'
=> 'projects_a_id',
'associationForeignKey' => 'projects_b_id',
),
261
);
}
Crer des lments de form et sauvegarder les donnes fonctionne de la mme faon quavant mais vous
utilisez lalias la place. Ceci :
$this->set('projects', $this->Project->find('list'));
$this->Form->input('Project');
Devient ceci :
$this->set('relatedProjects', $this->Project->find('list'));
$this->Form->input('RelatedProject');
Que faire quand HABTM devient compliqu ? Par dfaut, quand vous sauvegardez une relation
HasAndBelongsToMany, CakePHP supprime toutes les lignes de la table jointe avant den sauvegarder
de nouvelles. Par exemple, si vous avez un Club qui a 10 Children (Enfant) associs. Vous mettez ensuite
jour le Club avec 2 Children. Le Club aura seulement 2 Children, et pas 12.
Notez aussi que si vous voulez ajouter plus de champs joindre (quand il a t cre ou les meta informations),
cest possible avec les tables jointes HABTM, mais il est important de comprendre que vous avez une option
facile.
HasAndBelongsToMany entre deux models est en ralit un raccourci pour trois models associs travers
les deux associations hasMany et belongsTo.
Etudiez cet exemple :
Child hasAndBelongsToMany Club
Ces deux exemples sont presque les mmes. Ils utilisent le mme nombre de champs nomms dans la base
de donnes et le mme nombre de models. Les diffrences importantes sont que le model join est nomm
diffremment et que son comportement est plus prvisible.
Astuce : Quand votre table jointe contient des champs supplmentaires en plus des deux cls trangres,
vous pouvez viter de perdre les valeurs des champs supplmentaires en dfinissant la cl unique du
tableau keepExisting. Vous pouvez le penser comme quelque chose de similaire unique => true,
mais sans perdre les donnes des champs supplmentaires pendant lopration de sauvegarde. Regardez : les
tablaux des associations HABTM.
Cependant, dans la plupart des cas, il est plus facile de faire un model pour la table jointe et de configurer les
associations hasMany, belongsTo comme montr dans lexemple ci-dessus au lieu dutiliser une association
HABTM.
262
Datatables
Tandis que CakePHP peut avoir des sources de donnes qui ne sont pas des driven de base de donnes, la
plupart du temps, elles le sont. CakePHP est pens pour tre agnostique et va fonctionner avec MySQL,
Microsoft SQL Server, PostgreSQL et autres. Vous pouvez crer vos tables de base de donnes comme
vous lauriez fait normalement. Quand vous crez vos classes Model, elles seront automatiquement lies
aux tables que vous avez cres. Les noms de table sont par convention en minuscules et au pluriel avec
tous les mots de la table spars par des underscores. Par exemple, un nom de model Ingredient sattendra
un nom de table ingredients. Un nom de Model de EventRegistration sattendra un nom de table de
event_registrations. CakePHP va inspecter vos tables pour dterminer le type de donnes de chaque champ
et utiliser cette information pour automatiser plusieurs fonctionnalits comme laffichage des champs de formulaires dans la vue. Les noms de champ sont par convention en minuscules et spars par des underscores.
Utiliser created et modified
En dfinissant un champ created ou modified dans votre table de base de donnes en type datetime (par
dfaut null), CakePHP va reconnatre ces champs et les remplir automatiquement ds quun enregistrement
est cre ou sauvegard dans la base de donnes ( moins que les donnes dj sauvegardes contiennent une
valeur pour ces champs).
Les champs created et modified vont tre dfinis la date et heure courante quand lenregistrement
est ajout pour la premire fois. Le champ modifi sera mis jour avec la date et lheure courante ds que
lenregistrement sera sauvegard.
Si vous avez created ou modified des donnes dans votre $this->data (par ex partir dun Model : :read
ou dun Model : :set) avant un Model : :save(), alors les valeurs seront prises partir de $this->data
et ne seront pas mises jour automagiquement. Si vous ne souhaitez pas cela, vous pouvez utiliser
unset($this->data[Model][modified]), etc... Alternativement vous pouvez surcharger
Model : :save() pour toujours le faire pour vous :
class AppModel extends Model {
public function save($data = null, $validate = true, $fieldList = array()) {
// Nettoie la valeur du champ modified avant chaque sauvegarde
$this->set($data);
if (isset($this->data[$this->alias]['modified'])) {
unset($this->data[$this->alias]['modified']);
}
return parent::save($this->data, $validate, $fieldList);
}
}
Si vous sauvegardez des donnes avec un fieldList et que les champs created et modified ne sont
pas prsents dans la liste blanche, les valeurs pour ces champs vont continuer tre automatiquement remplies. Si les champs created et modified sont dans fieldList, ils fonctionneront comme nimporte
quels autres champs.
263
Vous pouvez brancher une logique personnalise dans le processus de suppression laide des callbacks
beforeDelete et afterDelete prsents dans les deux Models et Behaviors. Allez voir Mthodes
Callback pour plus dinformations.
Note : Si vous supprimez un enregistrement avec des enregistrements dpendants et que lun des callbacks
de suppression, par exemple beforeDelete retourne false, il ne va pas stopper levent de propagation
suivant ni changer la valeur de retour du delete initial.
deleteAll
deleteAll(mixed $conditions, $cascade = true, $callbacks = false)
deleteAll() est identique delete(), sauf que deleteAll() supprimera tous les enregistrements
qui matchent les conditions fournies. Le tableau $conditions doit tre fourni en tant que fragment ou
tableau SQL.
conditions Conditions pour matcher.
cascade Boolen, Mis true pour supprimer les enregistrements qui dpendent de cet enregistrement.
callbacks Boolen, Lance les callbacks
Retourne un boolen true en cas de succs, false en cas dchec.
Exemple :
// Suppression avec un tableau de conditions similaires find()
$this->Comment->deleteAll(array('Comment.spam' => true), false);
264
Si vous supprimez avec soit callbacks et/ou cascade, les lignes seront trouves et ensuite supprimes. Cela
impliquera souvent plus de requtes fates. Les associations vont tre rinitialises avant que les enregistrements correspondants ne soient supprims dans deleteAll(). Si vous utilisez bindModel() ou unbindModel() pour changer les associations, vous devrez dfinir reset false.
Note : deleteAll() retournera true mme si aucun enregistrement nest supprim, puisque les conditions
pour la requte de suppression est un succs et quaucun enregistrement correspondant ne reste.
Dans lexemple ci-dessus, le tableau $validate est ajout au model User, mais ce tableau ne contient pas
de rgles de validation. En supposant que la table users ait les champs login, password, email et
date_de_naissance, lexemple ci-dessous montre quelques rgles simples de validation qui sappliquent
ces champs :
class User extends AppModel {
public $validate = array(
'login' => 'alphaNumeric',
'email' => 'email',
'date_de_naissance' => 'date'
);
}
Ce dernier exemple montre comment des rgles de validation peuvent tre ajoutes aux champs dun model.
Pour le champ login, seules les lettres et les chiffres sont autoriss, lemail doit tre valide et la date de
naissance doit tre une date valide. La dfinition de rgles de validation active laffichage automagique
de messages derreurs dans les formulaires par CakePHP, si les donnes saisies ne respectent pas les rgles
dfinies.
CakePHP a de nombreuses rgles et leur utilisation peut tre trs simple. Certaines de ces rgles intgres
vous permettent de vrifier le format des adresses emails, des URLs, des numros de carte de crdit, etc. mais nous couvrirons cela en dtail plus loin.
265
Voici un autre exemple de validation plus complexe qui tire profit de quelques-unes de ces rgles prdfinies :
class User extends AppModel {
public $validate = array(
'login' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'Chiffres et lettres uniquement !'
),
'between' => array(
'rule' => array('lengthBetween', 5, 15),
'message' => 'Entre 5 et 15 caractres'
)
),
'password' => array(
'rule' => array('minLength', '8'),
'message' => '8 caractres minimum'
),
'email' => 'email',
'date_de_naissance' => array(
'rule' => 'date',
'message' => 'Entrez une date valide',
'allowEmpty' => true
)
);
}
Deux rgles de validation sont dfinies pour le login : il doit contenir des lettres et des chiffres uniquement
et sa longueur doit tre comprise entre 5 et 15. Le mot de passe doit avoir au minimum 8 caractres. Lemail
doit avoir un format correct et la date de naissance tre une date valide. Vous pouvez voir dans cet exemple
comment personnaliser les messages que CakePHP affichera en cas de non respect de ces rgles.
Comme le montre lexemple ci-dessus, un seul champ peut avoir plusieurs rgles de validation. Si les rgles pr-dfinies ne correspondent pas vos critres, vous pouvez toujours ajouter vos propres rgles de
validation, selon vos besoins.
Maintenant que nous avons vu, en gros, comment la validation fonctionne, voyons comment ces rgles
sont dfinies dans le model. Il y a trois manires diffrentes pour dfinir les rgles de validation : tableaux
simples, une rgle par champ et plusieurs rgles par champ.
Rgles simples
Comme le suggre le nom, cest la manire la plus simple de dfinir une rgle de validation. La syntaxe
gnrale pour dfinir des rgles de cette manire est :
public $validate = array('nomChamp' => 'nomRegle');
O nomChamp est le nom du champ pour lequel la rgle est dfinie, et nomRegle est un nom prdfini,
comme alphaNumeric, email ou isUnique.
266
Par exemple, pour sassurer que luser fournit une adresse email correcte, vous pouvez utiliser cette rgle :
public $validate = array('user_email' => 'email');
La cl rule est obligatoire. Si vous dfinissez uniquement required => true, la validation du formulaire ne
fonctionnera pas correctement. Cest cause du fait que required nest pas proprement parl une rgle.
Comme vous pouvez le voir ici, chaque champ (un seul est prsent ci-dessus) est associ un tableau
contenant cinq cls : rule, required, allowEmpty, on et message. Toutes les cls sont optionnelles
sauf rule. Regardons en dtail ces cls.
La cl rule
La cl rule dfinit la mthode de validation et attend soit une valeur simple, soit un tableau. La rgle
spcifie peut-tre le nom dune mthode dans votre model, une mthode de la classe globale Validation
ou une expression rgulire. Pour une liste complte des rgles pr-dfinies, allez voir Rgles de validation
incluses.
Si la rgle ne ncessite pas de paramtre, rule peut-tre une simple valeur, comme :
public $validate = array(
'login' => array(
'rule' => 'alphaNumeric'
)
);
Si la rgle ncessite quelques paramtres (tels que un maximum, un minimum ou une plage de valeurs),
rule doit tre un tableau :
public $validate = array(
'password' => array(
'rule' => array('minLength', 8)
)
);
267
Souvenez-vous, la cl rule est obligatoire pour les dfinitions de rgles sous forme de tableau.
La cl required
Cette cl doit tre dfinie par une valeur boolenne, ou create ou update. Si required est true alors
le champ doit tre prsent dans le tableau de donnes. Tandis que mettre le champ create ou update
rendra le champ ncessaire seulement lors des oprations de cration ou de mise jour. Par exemple, si la
rgle de validation a t dfinie comme suit :
public $validate = array(
'login' => array(
'rule'
=> 'alphaNumeric',
'required' => true
)
);
Les donnes envoyes la mthode save() du model doivent contenir des donnes pour le champ login.
Dans le cas contraire, la validation chouera. La valeur par dfaut de cette cl est le boolen false.
required => true ne signifie pas la mme chose que la rgle de validation notBlank(). required
=> true indique que la cl du tableau doit tre prsente - cela ne veut pas dire quelle doit avoir une
valeur. Par consquent, la validation chouera si le champ nest pas prsent dans le jeu de donnes, mais
pourra russir (en fonction de la rgle) si la valeur soumise est vide ().
Modifi dans la version 2.1 : Le support pour create et update a t ajout.
La Cl allowEmpty
Si dfinie false, la valeur du champ doit tre non vide, ceci tant dtermin par !empty($value) ||
is_numeric($value). La vrification numrique est l pour que CakePHP fasse ce quil faut quand
$valeur vaut zro.
La diffrence entre required et allowEmpty peut tre confuse. required => true signifie que
vous ne pouvez pas sauvegarder le model, si la cl pour ce champ nest pas prsente dans $this->data
(la vrification est ralis avec isset) ; tandis que allowEmpty => false sassure que la valeur du
champ courant est non vide, comme dcrit ci-dessus.
La cl on
La cl on peut prendre lune des valeurs suivantes : update ou create. Ceci fournit un mcanisme qui
permet une rgle donne dtre applique pendant la cration ou la mise jour dun enregistrement.
Si une rgle est dfinie on => create, elle sera seulement applique lors de la cration dun nouvel
enregistrement. Autrement, si elle est dfinie on => update, elle sappliquera uniquement lors de la
mise jour de lenregistrement.
La valeur par dfaut pour on est null. Quand on est null, la rgle sapplique la fois pendant la cration
et la mise jour.
268
La cl message
La cl message vous permet de dfinir un message derreur de validation personnalis pour la rgle :
public $validate = array(
'password' => array(
'rule' => array('minLength', 8),
'message' => 'Le mot de passe doit comporter au moins 8 caractres'
)
);
Note : Quelque soit la rgle, lchec de validation sans un message dfini par dfaut sera This field cannot
be left blank. (Ce champ ne peut tre laiss vide)
Comme vous pouvez le voir, cela ressemble beaucoup ce que nous avons vu dans la section prcdente. Ici pour chaque champ, nous avons uniquement un tableau de paramtres de validation. Dans ce cas,
chaque nomChamp est un tableau de rgles index. Chaque nomRegle contient un tableau indpendant
de paramtres de validation.
Ce sera plus explicite avec un exemple pratique :
public $validate = array(
'login' => array(
'regleLogin-1' => array(
'rule' => 'alphaNumeric',
'message' => 'Lettres et chiffres uniquement',
'last' => true
269
),
'regleLogin-2' => array(
'rule' => array('minLength', 8),
'message' => 'Taille minimum de 8 caractres'
)
)
);
Lexemple ci-dessus dfinit deux rgles pour le champ login : regleLogin-1 et regleLogin-2. Comme
vous pouvez le voir, chaque rgle est identifie avec un nom arbitraire.
Quand vous utilisez des rgles multiples par champ, les cls required et allowEmpty doivent tre utilises
seulement une fois dans la premire rgle.
La cl last
Dans le cas de rgles multiples par champ, si une des rgles choue, le message derreur pour cette rgle va
par dfaut tre retourn et les rgles suivantes pour ce champ ne seront pas testes. Si vous voulez que la
validation continue bien quune rgle ait choue, dfinissez la cl last false pour cette rgle.
Dans lexemple suivant, mme si rule1 choue rule2 va tre teste et les messages derreur pour les
deux rgles ayant chous seront retournes si rule2 choue aussi :
public $validate = array(
'login' => array(
'rule1' => array(
'rule' => 'alphaNumeric',
'message' => 'Only alphabets and numbers allowed',
'last' => false
),
'rule2' => array(
'rule' => array('minLength', 8),
'message' => 'Minimum length of 8 characters'
)
)
);
Quand vous spcifiez des rgles de validation dans ce tableau de formulaire, il est aussi possible dviter de
fournir la cl message. Regardez cette exemple :
public $validate = array(
'login' => array(
'Only alphabets and numbers allowed' => array(
'rule' => 'alphaNumeric',
),
)
);
Si les rgles de alphaNumeric chouent, la cl du tableau pour cette rgle Only alphabets and numbers
allowed sera retourn en message derreur si la cl message nest pas dfinie.
270
Si la technique de validation dont vous avez besoin peut tre complte par lutilisation dune expression
rgulire, vous pouvez dfinir une expression personnalise comme une rgle de validation de champ :
public $validate = array(
'login' => array(
'rule' => '/^[a-z0-9]{3,}$/i',
'message' => 'Seulement des lettres et des entiers, minimum 3 caractres'
)
);
Lexemple ci-dessus vrifie que le login contient seulement des lettres et des entiers et quil a au minimum
trois caractres.
Lexpression rgulire dans rule doit tre dlimite par des slashes (/). Le i final optionnel aprs le dernier
slash signifie que lexpression rgulire est insensible la casse.
Ajouter vos propres mthodes de validation
Parfois, la vrification des donnes par un motif dexpression rgulire ne suffit pas. Par exemple, si vous
voulez vous assurer quun coupon de rduction (code promo) nest pas utilis plus de 25 fois, vous devez
ajouter votre propre mthode de validation, comme indiqu ci-dessous :
class User extends AppModel {
public $validate = array(
'code_promo' => array(
'rule' => array('limiteUtilisations', 25),
'message' => 'Ce code promo a dpass son nombre maximal d\'utilisation.'
)
);
public function limiteUtilisations($check, $limit) {
// $check aura comme valeur : array('code_promo' => 'une valeur')
// $limit aura comme valeur : 25
$compteurCodeActuel = $this->find('count', array(
'conditions' => $check,
'recursive' => -1
));
return $compteurCodeActuel < $limit;
}
}
271
Le champ en cours de validation est pass la fonction comme premier paramtre, sous la forme dun
tableau associatif avec le nom du champ comme cl et les donnes postes comme valeur.
Si vous voulez passer des paramtres supplmentaires votre fonction de validation, ajoutez des lments
dans le tableau rule et manipulez-les comme des paramtres supplmentaires (aprs le paramtre principal
$check) dans votre fonction.
Votre fonction de validation peut tre dans le model (comme dans lexemple) ou dans un behavior (comportement) que votre model implmente. Ceci inclut les mthodes mappes.
Les mthodes des models/behaviors sont vrifies en premier, avant de chercher pour une mthode dans
la classe Validation. Cela veut dire que vous pouvez surcharger les mthodes de validation existantes
(telle que alphaNumeric()) au niveau de lapplication (en ajoutant la mthode dans AppModel) ou au
niveau du model.
Quand vous crivez une rgle de validation qui peut tre utilise par plusieurs champs, prenez soin dextraire
la valeur du champ du tableau $check. Le tableau $check est pass avec le nom du champ comme cl et la
valeur du champ comme valeur. Le champ complet qui doit tre valid est stock dans une variable de
$this->data :
Note : Vos propres mthodes de validation doivent avoir une visibilit public. Les mthodes de Validation
qui sont protected et private ne sont pas supportes.
Cette mthode devrait retourner true si la valeur est valide. Si la validation choue, elle retourne false.
Lautre valeur de retour valide est une chane de caractres qui sera montre en message derreur. Retourner
une chane de caractres signifie que la validation a chou. La chane de caractre va surcharger le message
dfini dans le tableau $validate et sera montr dans le formulaire de vue comme la raison pour laquelle le
champ nest pas valide.
Changer dynamiquement les rgles de validation
Utiliser la proprit $validate pour dclarer les rgles de validation est une bonne faon de dfinir des
rgles statiques pour chaque model. Nanmoins, il y a dautres cas o vous voudrez ajouter, modifier ou
272
Cela va ajouter une rgle simple au champ password dans le model. Vous pouvez chainer plusieurs appels
ajouter pour crer autant de rgles que vous souhaitez :
// Dans une classe de model
$this->validator()
->add('password', 'required', array(
'rule' => 'notBlank',
'required' => 'create'
))
->add('password', 'size', array(
'rule' => array('lengthBetween', 8, 20),
'message' => 'Password should be at least 8 chars long'
));
Il est aussi possible dajouter des rgles multiples en une fois pour un champ unique :
$this->validator()->add('password', array(
'required' => array(
'rule' => 'notBlank',
'required' => 'create'
),
'size' => array(
'rule' => array('lengthBetween', 8, 20),
'message' => 'Password should be at least 8 chars long'
)
));
De faon alternative, vous pouvez utiliser lobjet validator pour dfinir les rgles directement aux champs
en utilisant linterface de tableau :
$validator = $this->validator();
$validator['username'] = array(
'unique' => array(
273
Vous pouvez aussi compltement remplacer toutes les rgles pour un champ en utilisant une mthode similiare :
// Dans une classe de model
$this->validator()->getField('password')->setRules(array(
'required' => array(...),
'otherRule' => array(...)
));
Si vous souhaitez juste modifier une proprit unique dans une rgle, vous pouvez dfinir des proprits
directement dans lobjet CakeValidationRule :
// Dans une classe de model
$this->validator()->getField('password')
->getRule('required')->message = 'This field cannot be left blank';
Les proprits dans toute CakeValidationRule sont nommes selon les cls valides de tableau autorises utiliser quand vous dfinissez des proprits de rgles de comme les cls de tableau message et
allowEmpty par exemple.
Comme avec lajout de nouvelle rgle lensemble, il est aussi possible de modifier les rgles existantes en
utilisant linterface de tableau :
$validator = $this->validator();
$validator['username']['unique'] = array(
'rule' => 'isUnique',
'required' => 'create'
);
274
$validator['username']['unique']->last = true;
$validator['username']['unique']->message = 'Name already taken';
De faon optionnelle, vous pouvez utiliser linterface de tableau pour supprimer les rgles partir dun
ensemble :
$validator = $this->validator();
// Retire compltement toutes les rgles pour un champ
unset($validator['username']);
// Retire la rgle 'required' de password
unset($validator['password']['required']);
275
La longueur des donnes est le nombre doctets dans la reprsentation des donnes sous forme de
chane. Faites attention, car elle peut tre plus grande que le nombre de caractres quand vous manipulez des caractres non-ASCII.
static Validation::blank(mixed $check)
Cette rgle est utilise pour vrifier que le champ est laiss vide ou que seulement des caractres blancs
y sont prsents. Les caractres blancs incluent lespace, la tabulation, le retour chariot et nouvelle
ligne.
public $validate = array(
'id' => array(
'rule' => 'blank',
'on' => 'create'
)
);
static Validation::cc(mixed $check, mixed $type = fast, boolean $deep = false, string $regex
= null)
Cette rgle est utilise pour vrifier si une donne est un numro de carte de crdit valide. Elle prend
trois paramtres : type, deep et regex.
Le paramtre type peut tre assign aux valeurs fast, all ou lune des suivantes :
amex
bankcard
diners
disc
electron
enroute
jcb
maestro
mc
solo
switch
visa
276
voyager
Si type est dfini fast, cela valide les donnes de la majorit des formats numriques de cartes
de crdits. Dfinir type all vrifiera tous les types de cartes de crdits. Vous pouvez aussi dfinir
type comme un tableau des types que vous voulez dtecter.
Le paramtre deep devrait tre dfini comme une valeur boolenne. Sil est dfini true, la validation
vrifiera lalgorithme Luhn de la carte de crdit (http ://en.wikipedia.org/wiki/Luhn_algorithm). Par
dfaut, elle est false.
Le paramtre regex vous permet de passer votre propre expression rgulire, laquelle sera utilise
pour valider le numro de la carte de crdit :
277
dmy, par exemple : 27-12-2006 ou 27-12-06 (les sparateurs peuvent tre lespace, le point, le tiret,
le slash)
mdy, par exemple : 12-27-2006 ou 12-27-06 (les sparateurs peuvent tre lespace, le point, le tiret,
le slash)
ymd, par exemple : 2006-12-27 ou 06-12-27 (les sparateurs peuvent tre lespace, le point, le tiret,
le slash)
dMy, par exemple : 27 Dcembre 2006 ou 27 Dc 2006
Mdy, par exemple : Dcembre 27, 2006 ou Dc 27, 2006 (la virgule est optionnelle)
My, par exemple : (Dcembre 2006 ou Dc 2006)
my, par exemple : 12/2006 ou 12/06 (les sparateurs peuvent tre lespace, le point, le tiret, le
slash)
ym par ex. 2006/12 ou 06/12 (les sparateurs peuvent tre un espace, une priode, un tiret, ou un
slash)
y e.g. 2006 (les sparateurs peuvent tre un espace, une priode, un tiret, ou un slash)
Si aucune cl nest soumise, la cl par dfaut ymd sera utilise :
public $validate = array(
'date_de_naissance' => array(
'rule' => array('date', 'ymd'),
'message' => 'Entrez une date valide au format AA-MM-JJ.',
'allowEmpty' => true
)
);
Etant donn que de nombreux moteurs de stockage rclament un certain format de date, vous devriez
envisager de faire le plus gros du travail en acceptant un large choix de formats et en essayant de les
convertir, plutt que de forcer les gens les soumettre dans un format donn. Le plus de travail vous
ferez pour les users, le mieux ce sera.
Modifi dans la version 2.4 : Les formats ym et y ont t ajouts.
static Validation::datetime(array $check, mixed $dateFormat = ymd, string $regex =
null)
Cette rgle sassure que les donnes sont dans un format datetime valide. Un paramtre (qui peut tre
un tableau) peut tre pass pour spcifier le format de la date. La valeur du paramtre peut tre une ou
plusieurs des valeurs suivantes :
dmy, par exemple : 27-12-2006 or 27-12-06 (les sparateurs peuvent tre lespace, le point, le tiret,
le slash)
mdy, par exemple : 12-27-2006 or 12-27-06 (les sparateurs peuvent tre lespace, le point, le tiret,
le slash)
ymd, par exemple : 2006-12-27 or 06-12-27 (les sparateurs peuvent tre lespace, le point, le tiret,
le slash)
dMy, par exemple : 27 December 2006 or 27 Dec 2006
Mdy, par exemple : December 27, 2006 or Dec 27, 2006 (le point est optionnel)
My, par exemple : (December 2006 or Dec 2006)
my, par exemple : 12/2006 or 12/06 (les sparateurs peuvent tre lespace, le point, le tiret, le slash)
Si aucune cl nest fournie, la cl par dfaut qui sera utilise est ymd :
public $validate = array(
'birthday' => array(
'rule' => array('datetime', 'dmy'),
278
Un second paramtre peut aussi tre pass pour spcifier une expression rguire personnalise. Si un
paramtre est utilis, ce sera la seule validation qui apparaitra.
Notez que au contraire de date(), datetime() validera une date et un time.
static Validation::decimal(string $check, integer $places = null, string $regex = null)
Cette rgle sassure que la donne est un nombre dcimal valide. Un paramtre peut tre pass pour
spcifier le nombre de dcimales requises aprs le point. Si aucun paramtre nest pass, la donne sera
valide comme un nombre scientifique virgule flottante, entranant une erreur si aucune dcimale
nest trouve aprs le point :
public $validate = array(
'prix' => array(
'rule' => array('decimal', 2)
)
);
279
)
);
La comparaison est non sensible la casse par dfaut. Vous pouvez dfinir $caseInsensitive
true si vous avez besoin dune comparaison sensible la casse.
static Validation::ip(string $check, string $type = both)
Cette rgle sassurera quune adresse IPv4 ou IPv6 valide a t soumise. Accepte both en option
(par dfaut), IPv4 ou IPv6.
public $validate = array(
'ip_client' => array(
'rule' => array('ip', 'IPv4'), // ou 'IPv6' ou 'both' (par dfaut)
'message' => 'Merci de soumettre une adresse IP valide.'
)
);
Model::isUnique()
La donne pour le champ doit tre unique, elle ne peut tre utilise par aucune autre ligne :
public $validate = array(
'login' => array(
'rule' => 'isUnique',
280
Vous pouvez valider quun ensemble de champs sont uniques en fournissant plusieurs champs et en
paramtrant $or false :
public $validate = array(
'email' => array(
'rule' => array('isUnique', array('email', 'username'), false),
'message' => 'Cette combinaise nom & email est dj utilise.'
)
);
Assurez-vous dinclure le champ dorigine dans la liste des champs quand vous tablissez une rgle
unique sur plusieurs champs.
Si un champ list nest pas inclut dans les donnes du model, il sera alors trait comme une valeur
null. Vous pouvez envisager de marquer les champs rpertoris comme required.
static Validation::luhn(string|array $check, boolean $deep = false)
Lalgorithme Luhn : Une formule de vrification de somme pour valider un ensemble de nombres
didentification. Regardez http ://en.wikipedia.org/wiki/Luhn_algorithm pour plus dinformations.
static Validation::maxLength(string $check, integer $max)
Cette rgle sassure que la donne respecte la longueur maximale requise.
public $validate = array(
'login' => array(
'rule' => array('maxLength', 15),
'message' => 'Les noms d\'user ne doivent pas dpasser 15 caractres.'
)
);
La longueur ici est le nombre de bytes dans la reprsentation en chane de la donne. Faites attention
car elle pourrait tre plus grande que le nombre de caractres en manipulant des caractres non-ASCII.
static Validation::mimeType(mixed $check, array|string $mimeTypes)
Introduit dans la version 2.2.
Cette rgle vrifie la validit dun mimeType. La comparaison est sensible la casse.
Modifi dans la version 2.5.
Depuis 2.5 $mimeTypes peut tre une chane regex.
public $validate = array(
'image' => array(
'rule' => array('mimeType', array('image/gif')),
'message' => 'Invalid mime type.'
),
'logo' => array(
'rule' => array('mimeType', '#image/.+#'),
'message' => 'Invalid mime type.'
),
);
281
La longueur ici est le nombre de bytes dans la reprsentation des donnes sous forme de chane.
Faites attention car elle pourrait tre plus grande que le nombre de caractres en manipulant des
caractres non-ASCII.
static Validation::money(string $check, string $symbolPosition = left)
Cette rgle sassure que la valeur est une somme montaire valide.
Le second paramtre dfinit o le symbole est situ (gauche/droite).
public $validate = array(
'salaire' => array(
'rule' => array('money', 'left'),
'message' => 'Merci de soumettre une somme montaire valide.'
)
);
La comparaison est sensible la casse par dfaut. Vous pouvez dfinir $caseInsensitive true
si vous avez besoin dune comparaison insensible la casse.
static Validation::notEmpty(mixed $check)
Obsolte depuis la version 2.7.
Utilisez notBlank la place.
static Validation::notBlank(mixed $check)
Introduit dans la version 2.7.
La rgle de base pour sassurer quun champ nest pas vide.
282
Ne lutilisez pas pour un champ select multiple, sinon cela causera une erreur. A la place, utilisez
multiple.
static Validation::numeric(string $check)
Vrifie si la donne passe est un nombre valide.
public $validate = array(
'cars' => array(
'rule' => 'numeric',
'message' => 'Merci de soumettre le nombre de voitures.'
)
);
283
Lexemple ci-dessus acceptera toutes les valeurs qui sont plus grandes que -1 (par ex, -0.99) et plus
petite que 11 (par ex, 10.99).
Note : Les deux extrmits ne sont pas incluses.
static Validation::ssn(mixed $check, string $regex = null, string $country = null)
Ssn valide les numros de scurit sociale des U.S.A. (us), du Danemark (dk) et des Pays-Bas (nl).
Pour les autres formats de numros de scurit sociale, vous devez fournir une expression rgulire.
public $validate = array(
'ssn' => array(
'rule' => array('ssn', null, 'us')
)
);
284
Pour sassurer quun protocole est prsent dans lurl, le mode strict peut tre activ comme ceci :
public $validate = array(
'siteweb' => array(
'rule' => array('url', true)
)
);
Cette mthode de validation utilise une expression rgulire complexe qui peut parfois entraner des
problmes avec Apache2 sur Windows en utilisant mod_php.
static Validation::userDefined(mixed $check, object $object, string $method, array $args
= null)
Lance une validation de dfinition duser.
static Validation::uuid(string $check)
Vrifie que la valeur est une valeur UUID valide : http ://tools.ietf.org/html/rfc4122
Validation localise
Les rgles de validation phone() et postal() vont envoyer les prfixes de pays quelles ne savent pas grer
une autre classe avec le nom affrant. Par exemple si vous vivez aux Pays-Bas, vous pourriez crer une
classe comme :
class NlValidation {
public static function phone($check) {
// ...
}
public static function postal($check) {
// ...
}
}
Quand vos donnes de model sont valides, la Validation va voir quelle ne peut pas grer la locale nl
et va tenter de dlguer NlValidation::postal() et le retour de cette mthode va tre utilise
comme russite/echec pour la validation. Cette approche vous permet de crer des classes qui grent un sousensemble ou groupe de locales, chose quun large switch ne pourrait pas faire. Lutilisation des mthodes de
validation individuelle na pas chang, la possibilit de faire passer un autre validateur a t ajout.
Pour en savoir plus sur les Models
285
Astuce :
Le Plugin Localized contient dj beaucoup de rgles prtes tre utilises :
https ://github.com/cakephp/localized Aussi nhsitez pas contribuer en donnant vos rgles de validation
localises.
Alors que normalement vous nutiliseriez que la mthode save du model, il peut arriver que vous souhaitiez
valider les donnes sans les sauvegarder. Par exemple, vous souhaitez afficher des informations supplmentaires luser avant quil ne sauvegarde les donnes dans la base. Valider les donnes ncessite un processus
lgrement diffrent de la mthode save.
Tout dabord, mettez les donnes dans le model :
$this->ModelName->set($this->request->data);
Ensuite, pour vrifier si les donnes sont valides, utilisez la mthode validates du model, qui va retourner
true si elles sont valides et false si elles ne le sont pas :
if ($this->ModelName->validates()) {
// La logique est valide
} else {
// La logique n'est pas valide
$errors = $this->ModelName->validationErrors;
}
Il peut tre souhait de valider votre model seulement en utilisant un sous-ensemble des validations spcifies dans le model. Par exemple, si vous avez un model User avec les champs prenom, nom, email et
mot_de_passe. Dans ce cas, quand vous crez ou modifiez un user, vous ne voulez pas valider les 4 rgles
des champs. Pourtant quand un user se connecte, vous voulez valider seulement les rgles de lemail et du
mot_de_passe. Pour le faire, vous pouvez passer un tableau doptions spcifiant les champs sur lesquels
vous voulez la validation. Par exemple
if ($this->User->validates(array('fieldList' => array('email', 'mot_de_passe')))) {
// valide
} else {
// invalide
}
La mthode validates invoque la mthode invalidFields qui remplit la proprit validationErrors du model.
La mthode invalidFields retourne aussi cette donne comme rsultat :
La liste des erreurs de validation nest pas supprime entre les diffrents appels invalidFields().
Donc si vous validez dans une boucle et que vous voulez chaque jeu derreurs sparement, nutilisez pas
invalidFields(). Utilisez plutt validates() et accder la proprit validationErrors du
model.
286
Il est important de noter que les donnes doivent tre envoyes au model avant que les donnes soient
valides. Cest diffrent de la mthode save qui autorise aux donnes dtre passes comme paramtre.
Aussi, gardez lesprit quil nest pas ncessaire dappeler validates antrieurement lappel save puisque
save va automatiquement valider les donnes avant lenregistrement effectif.
Pour valider plusieurs models, lapproche suivante devra tre utilise :
if ($this->ModelName->saveAll($this->request->data, array('validate' => 'only'))) {
// valide
} else {
// ne valide pas
}
Si vous avez valid les donnes avant lenregistrement, vous pouvez stopper la validation du save pour viter
un deuxime contrle :
if ($this->ModelName->saveAll($this->request->data, array('validate' => false))) {
// sauvegarder sans validation
}
Mthodes Callback
Si vous voulez glisser un bout de logique applicative juste avant ou aprs une opration dun model
CakePHP, utilisez les callbacks de model. Ces fonctions peuvent tre dfinies dans les classes de model
(cela comprend galement votre classe AppModel). Notez bien les valeurs de retour attendues pour chacune
de ces mthodes spciales.
Lors de lutilisation de mthodes de callback, vous devriez vous rappeler que les callbacks des behaviors
sont lancs avant les callbacks des models.
beforeFind
beforeFind(array $query)
Appele avant toute opration lie la recherche. Les $query passes cette mthode de callback contiennent des informations sur la requte courante : conditions, champs, etc.
Si vous ne souhaitez pas que lopration de recherche commence (par rapport une dcision lie aux options
de $query), retournez false. Autrement, retournez la variable $query ventuellement modifie, ou tout
ce que vous souhaitez voir pass la mthode find() ou ses quivalents.
Vous pouvez utiliser cette mthode de callback pour restreindre les oprations de recherche en se basant sur
le rle de lutilisateur, ou prendre des dcisions sur la politique de mise en cache en fonction de la charge
actuelle.
afterFind
afterFind(array $results, boolean $primary = false)
287
Utilisez cette mthode de callback pour modifier les rsultats qui ont t retourns par une opration de
recherche, ou pour effectuer toute logique post-recherche. Le paramtre $results pass cette mthode
contient les rsultats retourns par lopration find() du model, cd quelque chose comme :
$results = array(
0 => array(
'NomModel' => array(
'champ1' => 'valeur1',
'champ2' => 'valeur2',
),
),
);
La valeur de retour de ce callback doit tre le rsultat de lopration de recherche (potentiellement modifi)
qui a dclench ce callback.
Le paramtre $primary indique si oui ou non le model courant est le model do la requte provient en
tant quassociation ou non. Si un model est requt en tant quassociation, le format de $results peut
diffrer ; la place du rsultat, que vous auriez normalement obtenu partir dune opration find, vous
obtiendriez peut-tre ceci :
$results = array(
'champ1' => 'valeur1',
'champ2' => 'valeur2'
);
Avertissement : Un code ncessitant que $primary soit true aura probablement lerreur fatale Cannot use string offset as an array de la part de PHP si une recherche rcursive est utilise.
Ci-dessous un exemple de la manire dont afterfind peut tre utilise pour formater des dates :
public function afterFind($results, $primary = false) {
foreach ($results as $key => $val) {
if (isset($val['Event']['begindate'])) {
$results[$key]['Event']['begindate'] = $this->dateFormatAfterFind(
$val['Event']['begindate']
);
}
}
return $results;
}
public function dateFormatAfterFind($dateString) {
return date('d-m-Y', strtotime($dateString));
}
beforeValidate
beforeValidate(array $options = array())
288
Utilisez ce rappel pour modifier les donnes du model avant quelles ne soient valides ou pour modifier
les rgles de validation si ncessaire. Cette fonction doit aussi retourner true, sinon lexcution du save()
courant sera annule.
afterValidate
afterValidate()
Appele aprs que la donne a t vrifie pour les erreurs. Utilisez ce callback pour lancer un nettoyage de
donnes ou prparer des donnes si besoin.
beforeSave
beforeSave(array $options = array())
Placez toute logique de pr-enregistrement dans cette fonction. Cette fonction sexcute immdiatement
aprs que les donnes du model ont t valides avec succs, mais juste avant que les donnes ne soient
sauvegardes. Cette fonction devrait toujours retourner true si voulez que lopration denregistrement se
poursuive.
Ce callback est particulirement pratique, pour toute logique de manipulation des donnes qui ncessite
de se produire avant que vos donnes ne soient stockes. Si votre moteur de stockage ncessite un format
spcifique pour les dates, accdez-y par $this->data et modifiez-les.
Ci-dessous un exemple montrant comment beforeSave peut-tre utilise pour la conversion de date. Le code
de lexemple est utilis pour une application qui a une date de dbut, au format YYYY-MM-DD dans la
base de donnes et au format DD-MM-YYYY dans laffichage de lapplication. Bien sr, ceci peut tre trs
facilement modifi. Utilisez le code ci-dessous dans le model appropri.
public function beforeSave($options = array()) {
if (!empty($this->data['Event']['begindate']) &&
!empty($this->data['Event']['enddate'])
) {
$this->data['Event']['begindate'] = $this->dateFormatBeforeSave(
$this->data['Event']['begindate']
);
$this->data['Event']['enddate'] = $this->dateFormatBeforeSave(
$this->data['Event']['enddate']
);
}
return true;
}
public function dateFormatBeforeSave($dateString) {
return date('Y-m-d', strtotime($dateString));
}
Astuce : Assurez-vous que beforeSave() retourne true ou bien votre sauvegarde chouera.
289
afterSave
afterSave(boolean $created, array $options = array())
Si vous avez besoin dexcuter de la logique juste aprs chaque opration de sauvegarde, placez-la dans
cette mthode de rappel. Les donnes sauvegardes seront disponibles dans $this->data.
La valeur de $created sera true si un nouvel objet a t cr (plutt quun objet mis jour).
Le tableau $options est le mme que celui pass dans Model::save().
beforeDelete
beforeDelete(boolean $cascade = true)
Placez dans cette fonction, toute logique de pr-suppression. Cette fonction doit retourner true si vous voulez
que la suppression continue et false si vous voulez lannuler.
La valeur de $cascade sera true, pour que les enregistrements qui dpendent de cet enregistrement
soient aussi supprims.
Astuce : Assurez-vous que beforeDelete() retourne true, ou votre suppression ne va pas marcher.
// en utilisant app/Model/ProduitCategory.php
// Dans l'exemple suivant, ne laissez pas une catgorie tre supprime si
// elle contient des produits. Un appel de $this->Produit->delete($id) de
// ProduitsController.php a dfini $this->id. En admettant que
// 'ProduitCategory hasMany Produit', nous pouvons accder $this->Produit
// dans le model.
public function beforeDelete() {
$count = $this->Product->find("count", array(
"conditions" => array("produit_category_id" => $this->id)
));
if ($count == 0) {
return true;
}
return false;
}
afterDelete
afterDelete()
Placez dans cette mthode de rappel, toute logique que vous souhaitez excuter aprs chaque suppression :
// peut-tre pour supprimer un enregistrement de la base de donnes,
// vous pouvez aussi supprimer un fichier associ
public function afterDelete() {
$file = new File($this->data['SomeModel']['file_path']);
$file->delete();
}
290
onError
onError()
Appele si il se produit quelque problme que ce soit.
Behaviors (Comportements)
Les behaviors (comportements) de Model sont une manire dorganiser certaines des fonctionnalits dfinies
dans les models CakePHP. Ils nous permettent de sparer la logique qui ne doit pas tre directement relie
un model, mais qui ncessite dtre l. En offrant une simple, mais puissante, manire dtendre les models,
les behaviors nous permettent dattacher des fonctionnalits aux models en dfinissant une simple variable
de classe. Cest comme cela que les behaviors permettent de dbarrasser les models de tout le sur-poids
qui ne devrait pas faire partie du contrat mtier quils modlent ou de ce qui est aussi ncessit par diffrents
models et qui peut alors tre extrapol.
Par exemple, considrez un model qui nous donne accs une table qui stocke des informations sur la structure dun arbre hirarchique. Supprimer, ajouter ou dplacer les nuds dans larbre nest pas aussi simple
que deffacer, dinsrer ou dditer les lignes dune table. De nombreux enregistrements peuvent ncessiter
une mise jour suite au dplacement des lments. Plutt que de crer ces mthodes de manipulation darbre
une fois par model de base (pour chaque model ncessitant cette fonctionnalit), nous pourrions simplement
dire notre model dutiliser le behavior TreeBehavior ou, en des termes plus formels, nous dirions
notre model de se comporter comme un Arbre. On appelle cela attacher un behavior un model. Avec
une seule ligne de code, notre model CakePHP disposera dun nouvel ensemble complet de mthodes lui
permettant dinteragir avec la structure sous-jacente.
CakePHP contient dj des behaviors pour les structures en arbre, les contenus traduits, les interactions par
liste de contrle daccs, sans oublier les behaviors des contributeurs de la communaut dj disponibles
dans la Boulangerie (Bakery) CakePHP (http ://bakery.cakephp.org). Dans cette section nous couvrirons
le schma dusage classique pour ajouter des behaviors aux models, lutilisation des behaviors intgrs
CakePHP et la manire de crer nos propres behaviors.
Au final, les Behaviors sont Mixins 1 avec les callbacks.
Il y a un certain nombre de Behaviors inclus dans CakePHP. Pour en savoir plus sur chacun, rfrencez-vous
aux chapitres ci-dessous :
ACL
class AclBehavior
Le behavior Acl fournit une solution pour intgrer sans souci un model dans votre systme ACL. Il peut
crer la fois les AROs et les ACOs de manire transparente.
Pour utiliser le nouveau behavior, vous pouvez lajouter la proprit $actsAs de votre model. Quand vous
lajoutez au tableau actsAs, vous choisissez de crer lentre Acl correspondante comme un ARO ou un
ACO. Par dfaut, cela cre des AROs :
1. http ://en.wikipedia.org/wiki/Mixin
291
Ceci attacherait le behavior Acl en mode ARO. Pour attacher le behavior ACL en mode ACO, utilisez
class Post extends AppModel {
public $actsAs = array('Acl' => array('type' => 'controlled'));
}
Pour les models duser et de group il est frquent davoir la fois les noeuds ACO et ARO, pour permettre
cela utilisez :
class User extends AppModel {
public $actsAs = array('Acl' => array('type' => 'both'));
}
Modifi dans la version 2.1 : Vous pouvez maintenant attacher en toute scurit le behavior Acl (AclBehavior) votre Appmodel. Aco, Aro et Noeud Acl (AclNode) sont dornavant des extensions du Model et
non plus de lAppModel, ceci pouvait causer une boucle infinie. Si pour certaines raisons, votre application
est dpendante de lutilisation des models comme extension de lAppModel, alors copiez Le Noeud Acl
(AclNode) dans votre application et tendez nouveau AppModel.
Utiliser le behavior Acl
La plupart des tches du behavior Acl sont ralises de faon transparente, dans le callback afterSave()
de votre model. Cependant, son utilisation ncessite que votre Model ait une mthode parentNode() dfinie.
Ceci est utilis par le behavior Acl, pour dterminer les relations parent->enfant. Une mthode parentNode()
de model doit retourner null ou une rfrence au Model parent :
public function parentNode() {
return null;
}
Si vous voulez dfinir un nud ACO ou ARO comme parent pour votre Model, parentNode() doit retourner
lalias du nud ACO ou ARO :
public function parentNode() {
return 'root_node';
}
Voici un exemple plus complet. Utilisons un model dexemple User, avec User belongsTo Group :
292
Dans lexemple ci-dessus, le retour est un tableau qui ressemble aux rsultats dun find de model. Il est
important davoir une valeur did dfinie ou bien la relation parentNode chouera. Le behavior Acl utilise
ces donnes pour construire son arborescense.
node()
Le Behavior Acl vous permet aussi de rcuprer le nud Acl associ un enregistrement de model. Aprs
avoir dfini $model->id. Vous pouvez utiliser $model->node() pour rcuprer le nud Acl associ.
Vous pouvez aussi rcuprer le nud Acl de nimporte quelle ligne, en passant un tableau de donnes en
paramtre :
$this->User->id = 1;
$noeud = $this->User->node();
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user);
Containable
class ContainableBehavior
293
Utilisation de Containable
Pour voir comment Containable fonctionne, regardons quelques exemples. Premirement, nous commencerons avec un appel find() sur un model nomm Post. Disons que ce Post a plusieurs (hasMany)
Comment, et Post a et appartient plusieurs (hasAndBelongsToMany) Tag. La quantit de donnes
rcupres par un appel find() normal est assez tendue
debug($this->Post->find('all'));
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[auteur] => Daniel
[email] => dan@example.com
[siteweb] => http://example.com
[commentaire] => Premier commentaire
[created] => 2008-05-18 00:00:00
294
)
[1] => Array
(
[id] => 2
[post_id] => 1
[auteur] => Sam
[email] => sam@example.net
[siteweb] => http://example.net
[commentaire] => Second commentaire
[created] => 2008-05-18 00:00:00
)
)
[Tag] => Array
(
[0] => Array
(
[id] => 1
[name] => A
)
[1] => Array
(
[id] => 2
[name] => B
)
)
)
[1] => Array
(
[Post] => Array
(...
Pour certaines interfaces de votre application, vous pouvez ne pas avoir besoin dautant dinformation depuis
le model Post. Le Behavior containable permet de rduire ce que le find() retourne.
Par exemple, pour ne rcuprer que les informations lies au post vous pouvez faire cela :
$this->Post->contain();
$this->Post->find('all');
Aprs avoir fait cela, vous vous retrouvez avec quelque chose de plus concis :
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
295
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[titre] => Second article
[contenu] => bbb
[created] => 2008-05-19 00:00:00
)
)
Ceci nest pas nouveau : en fait, vous pouvez obtenir le mme rsultat sans le behavior Containable
en faisant quelque chose comme :
$this->Post->recursive = -1;
$this->Post->find('all');
Le behavior Containable simpose vraiment quand vous avez des associations complexes, et que
vous voulez rogner le nombre dinformation au mme niveau. La proprit $recursive des models est utile si
vous voulez viter un niveau de rcursivit entier, mais pas pour choisir ce que vous garder chaque niveau.
Regardons ensemble comment la methode contain() agit.
Le premier argument de la mthode accepte le nom, ou un tableau de noms, des models garder lors du find.
Si nous dsirons aller chercher tous les posts et les tags annexes (sans aucune information de commentaire),
nous devons essayer quelque chose comme
$this->Post->contain('Tag');
$this->Post->find('all');
Sans le behavior Containable, nous finirions par utiliser la mthode unbindModel() du model, plusieurs
fois si nous pluchons plusieurs models. Le behavior Containable fournit un moyen plus propre
pour accomplir cette mme tche.
Des associations plus profondes
Containable permet galement daller un peu plus loin : vous pouvez filtrer les donnes des models associs.
si vous regardez les rsultats dun appel find() classique, notez le champ auteur dans le model Comment.
Si vous tes intresss par les posts et les noms des commentaires des auteurs - et rien dautre - vous devez
faire quelque chose comme :
$this->Post->contain('Comment.auteur');
$this->Post->find('all');
// ou..
$this->Post->find('all', array('contain' => 'Comment.auteur'));
296
ici, nous avons dit au behavior Containable de nous donner les informations du post, et uniquement le champ
auteur du model Comment associ. Le rsultat du find ressemble :
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[auteur] => Daniel
[post_id] => 1
)
[1] => Array
(
[auteur] => Sam
[post_id] => 1
)
)
)
[1] => Array
(...
Comme vous pouvez le voir, les tableaux de Comment ne contiennent uniquement que le champ auteur (avec
le post_id qui est requis par CakePHP pour prsenter le rsultat)
Vous pouvez galement filtrer les donnes associes Comment en spcifiant une condition :
$this->Post->contain('Comment.author = "Daniel"');
$this->Post->find('all');
//ou...
$this->Post->find('all', array('contain' => 'Comment.author = "Daniel"'));
Ceci nous donne comme rsultat les posts et commentaires dont daniel est lauteur :
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => Premier article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
297
Il y a un important gain utiliser Containable quand on filtre sur des associations plus profondes. Dans
lexemple prcdent, imaginez que vous avez 3 posts dans votre base de donnes et que Daniel a comment
sur 2 de ces posts. Lopration $this->Post->find(all, array(contain => Comment.author = Daniel)) ;
retournerait TOUS les 3 posts, pas juste les 3 posts que Daniel a comment. Cela ne va pas retourner tous
les comments cependant, juste les comments de Daniel.
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => First article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[author] => Daniel
[email] => dan@example.com
[website] => http://example.com
[comment] => First comment
[created] => 2008-05-18 00:00:00
)
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[title] => Second article
[content] => bbb
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
298
)
)
[2] => Array
(
[Post] => Array
(
[id] => 3
[title] => Third article
[content] => ccc
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 22
[post_id] => 3
[author] => Daniel
[email] => dan@example.com
[website] => http://example.com
[comment] => Another comment
[created] => 2008-05-18 00:00:00
)
)
)
Si vous voulez filtrer les posts selon les comments, pour que les posts non comments par Daniel ne soient
pas retourns, le plus simple est de trouver tous les comments de Daniel et de faire un contain sur les Posts.
$this->Comment->find('all', array(
'conditions' => 'Comment.author = "Daniel"',
'contain' => 'Post'
));
Des filtres supplmentaires peuvent tre utilises en utilisant les options de recherche standard find :
$this->Post->find('all', array('contain' => array(
'Comment' => array(
'conditions' => array('Comment.author =' => "Daniel"),
'order' => 'Comment.created DESC'
)
)));
Voici un exemple dutilisation de ContainableBehavior quand vous avez des relations profondes et
complexes entre les models.
Examinons les associations des models suivants :
User->Profile
User->Account->AccountSummary
User->Post->PostAttachment->PostAttachmentHistory->HistoryNotes
User->Post->Tag
299
Voici comment nous rcuprons les associations ci-dessus avec le behavior Containable
$this->User->find('all', array(
'contain' => array(
'Profile',
'Account' => array(
'AccountSummary'
),
'Post' => array(
'PostAttachment' => array(
'fields' => array('id', 'name'),
'PostAttachmentHistory' => array(
'HistoryNotes' => array(
'fields' => array('id', 'note')
)
)
),
'Tag' => array(
'conditions' => array('Tag.name LIKE' => '%happy%')
)
)
)
));
Gardez lesprit que la cl contain nest utilise quune seule fois dans le model principal, vous navez
pas besoin dutiliser contain nouveau dans les models lis.
Note : En utilisant les options fields et contain - noubliez pas dinclure toutes les cls trangres que
votre requte requiert directement ou indirectement. Notez galement que pour que le behavior Containable
puisse fonctionner avec le contain pour tous les models, vous devez lattacher votre AppModel.
Le Behavior Containable a plusieurs options qui peuvent tre dfinies quand le behavior est attach
un model. Ces paramtres vous permettent daffiner le behavior de Containable et de travailler plus facilement avec les autres behaviors.
recursive (boolean, optional), dfinir true pour permettre au behavior Containable, de dterminer automatiquement le niveau de rcursivit ncessaire pour rcuprer les models spcifis et pour paramtrer
la rcursivit du model ce niveau. Le dfinir false dsactive cette fonctionnalit. La valeur par dfaut
est true.
notices (boolean, optional), met des alertes E_NOTICES pour les liaisons rfrences dans un appel
containable et qui ne sont pas valides. La valeur par dfaut est true.
autoFields (boolean, optional), ajout automatique des champs ncessaires pour rcuprer les liaisons
requtes. La valeur par dfaut est true.
order : (string, optional) lordre dans lequel les elements contenus sont tris.
A partir de lexemple prcdent, ceci est un exemple de la faon de forcer les Posts tre tris selon la date
de dernire modification :
300
$this->User->find('all', array(
'contain' => array(
'Profile',
'Post' => array(
'order' => 'Post.updated DESC'
)
)
));
Vous pouvez changer les paramtres du Behavior Containable lexcution, en r-attachant le behavior
comme vu au chapitre Behaviors (Comportements) (Utiliser les Behaviors).
Le behavior Containable peut quelque fois causer des problmes avec dautres behaviors ou des requtes
qui utilisent des fonctions dagrgations et/ou des clauses GROUP BY. Si vous obtenez des erreurs SQL
invalides cause du mlange de champs agrgs et non-agrgs, essayer de dsactiver le paramtre
autoFields :
$this->Post->Behaviors->load('Containable', array('autoFields' => false));
Note : Si vous fates un contain des associations travers le model la place, il nhonorera pas loption
rcursive de Containable. Donc si vous dfinissez -1 par exemple pour le model, cela ne marchera pas :
$this->User->recursive = -1;
$this->User->contain(array('Profile', 'Account'));
$users = $this->paginate('User');
Le Behavior Translate
class TranslateBehavior
Le behavior Translate est en fait assez simple paramtrer et faire fonctionner out of the box, le tout avec
trs peu de configuration. Dans cette section, vous apprendrez comment ajouter et configurer ce behavior,
pour lutiliser dans nimporte quel model.
301
Si vous utilisez le behavior Translate en parallle de Containable, assurez-vous de dfinir la cl fields pour
vos requtes. Sinon, vous pourriez vous retrouver avec des fragments SQL gnrs invalides.
Initialisation des tables de la Base de donne i18n
Vous pouvez soit utiliser la console CakePHP, soit les crer manuellement. Il est recommand dutiliser la
console pour cela, parce quil pourrait arriver que le layout change dans les futures versions de CakePHP.
En restant fidle la console, cela garantira que vous ayez le bon layout :
./cake i18n
Slectionner[I], ce qui lancera le script dinitialisation de la base de donnes i18n. Il vous sera demand
si vous voulez supprimer toute table existante et si vous voulez en crer une. Rpondez par oui si vous tes
certain quil ny a pas encore une table i18n et rpondez encore par oui pour crer la table.
Attacher le Behavior Translate vos Models
Ajoutez-le votre model en utilisant la proprit $actsAs comme dans lexemple suivant.
class Post extends AppModel {
public $actsAs = array(
'Translate'
);
}
Ceci ne produira encore rien, parce quil faut un couple doptions avant que cela ne commence fonctionner.
Vous devez dfinir, quels champs du model courant devront tre dtects dans la table de traduction que nous
avons cre prcdemment.
Dfinir les Champs
Vous pouvez dfinir les champs en tendant simplement la valeur Translate avec un autre tableau,
comme
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'fieldOne', 'fieldTwo', 'and_so_on'
)
);
}
Aprs avoir fait cela (par exemple, en prcisant title comme lun des champs), vous avez dj termin
la configuration de base. Super ! Daprs notre exemple courant, le model devrait maintenant ressembler
quelque chose comme cela
302
Quand vous dfinissez vos champs traduire dans le Behavior Translate, assurez-vous domettre les champs
du schma de model traduits. Si vous laissez les champs en place, il peut y avoir un problme de rcupration
de donnes avec les locales.
Note : Si tous les champs dans votre model sont traduits, assurez-vous dajouter les colonnes created
et modified votre table. CakePHP a besoin dau moins un champ diffrent dune cl primaire avant
denregistrer un enregistrement.
Conclusion
A partir de maintenant, chaque mise jour/cration dun enregistrement fera que le Behavior Translate
copiera la valeur de title dans la table de traduction (par dfaut : i18n), avec la locale courante. Une
locale est un identifiant dune langue, pour ainsi dire.
Lire le contenu traduit
Par dfaut, le TranslateBehavior va automatiquement rcuprer et ajouter les donnes bases sur la locale courante. La locale courante est lue partir de Configure::read(Config.language) qui
est assigne par la classe L10n. Vous pouvez surcharger cette valeur par dfaut la vole en utilisant
$Model->locale.
Rcuprer les champs traduits dans une locale spcifique En dfinissant $Model->locale, vous
pouvez lire les traductions pour une locale spcifique :
// Lire les donnes de la locale espagnole.
$this->Post->locale = 'es';
$results = $this->Post->find('first', array(
'conditions' => array('Post.id' => $id)
));
// $results va contenir la traduction espagnole.
Rcuprer tous les enregistrements de traduction pour un champ Si vous voulez avoir tous les enregistrements de traduction attachs lenregistrement de model courant, vous tendez simplement le tableau
champ dans votre paramtrage du behavior, comme montr ci-dessous. Vous tes compltement libre de
choisir le nommage.
303
Note : Lenregistrement du model contient un champ virtuel appel locale. Il indique quelle locale est
utilise dans ce rsultat.
Notez que seuls les champs du model que vous fates avec un find seront traduits. Les Models attachs
via les associations ne seront pas traduits parce que le dclenchement des callbacks sur les models associs
nest actuellement pas support.
304
Utiliser la mthode bindTranslation Vous pouvez aussi rcuprer toutes les traductions seulement quand
vous en avez besoin, en utilisant la mthode bindTranslation.
TranslateBehavior::bindTranslation($fields, $reset)
$fields st un tableau associatif compos du champ et du nom de lassociation, dans lequel la cl est le
champ traduisible et la valeur est le nom fictif de lassociation.
Avec ce paramtrage, le rsultat de votre find() devrait ressembler quelque chose comme ceci
Array
(
[Post] => Array
(
[id] => 1
[title] => Beispiel Eintrag
[body] => lorem ipsum...
[locale] => de_de
)
[titleTranslation] => Array
(
[0] => Array
(
[id] => 1
[locale] => en_us
[model] => Post
[foreign_key] => 1
[field] => title
[content] => Example entry
)
[1] => Array
(
[id] => 2
[locale] => de_de
[model] => Post
[foreign_key] => 1
[field] => title
[content] => Beispiel Eintrag
)
)
)
Vous pouvez forcer le model qui utilise le TranslateBehavior sauvegarder dans une autre langue que celle
dtecte.
305
Pour dire un model dans quelle langue le contenu devra tre sauv, changez simplement la valeur de la
proprit $locale du model, avant que vous ne sauvegardiez les donnes dans la base. Vous pouvez faire cela
dans votre controller ou vous pouvez le dfinir directement dans le model.
Exemple A : Dans votre controller :
class PostsController extends AppController {
public function add() {
if (!empty($this->request->data)) {
$this->Post->locale = 'de_de'; // we are going to save the german version
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->redirect(array('action' => 'index'));
}
}
}
}
Si vous attendez beaucoup dentre, vous vous demandez certainement comment grer tout cela dans une
base de donnes qui grossit rapidement. Il y a deux proprits introduite dans le Behavior Translate qui
permettent de spcifier quel model doit tre reli au model qui contient les traductions.
Ceux-ci sont $translateModel et $translateTable.
Disons que nous voulons sauver nos traductions pour tous les posts dans la table post_i18ns au lieu de la
valeur par dfaut de la table i18n. Pour faire cela vous avez besoin de paramtrer votre model comme cela
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
306
)
);
// Utilise un model diffrent (et table)
public $translateModel = 'PostI18n';
}
Note : Il est important vous mettiez au pluriel la table. Cest maintenant un model habituel et il peut tre
trait en tant que tel avec les conventions qui en dcoulent. Le schma de la table elle-mme doit tre
identique celui gnr par la console CakePHP. Pour vous assurer quil sintgre vous pourriez initialiser
une table i18n vide au travers de la console et renommer la table aprs coup.
Crer le Model de Traduction Pour que cela fonctionne vous devez crer le fichier du model actuel dans
le dossier des models. La raison est quil ny a pas de proprit pour dfinir le displayField directement dans
le model utilisant ce behavior.
Assurez vous de changer le $displayField en field.
class PostI18n extends AppModel {
public $displayField = 'field'; // important
}
// nom de fichier: PostI18n.php
Cest tout ce quil faut. Vous pouvez aussi ajouter toutes les proprits des models comme $useTable. Mais
pour une meilleure cohrence nous pouvons faire cela dans le model qui utilise ce model de traduction. Cest
l que loption $translateTable entre en jeu.
Modification de la Table Si vous voulez changer le nom de la table, il vous suffit simplement de dfinir
$translateTable dans votre model, comme ceci
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Utilise un model diffrent
public $translateModel = 'PostI18n';
// Utilise une table diffrente pour translateModel
public $translateTable = 'post_translations';
}
A noter que vous ne pouvez pas utiliser $translateTable seule. Si vous navez pas lintention dutiliser un
Model de traduction $translateModel personnalis, alors laissez cette proprit inchange. La raison
est quelle casserait votre configuration et vous afficherait un message Missing Table pour le model I18n
par dfaut, lequel est cr lexcution.
307
Tree
class TreeBehavior
Cest assez courant de vouloir stocker ses donnes sous une forme hirarchique dans la table dune base
de donnes. Des exemples de tels besoins pourraient tre des catgories avec un nombre illimit de souscatgories, des donnes en relation avec un systme de menu multi-niveaux ou une reprsentation littrale
dune hirarchie, comme celle qui est utilise pour stocker les objets de contrle daccs avec la logique
ACL.
Pour de petits arbres de donnes et les cas o les donnes nont que quelques niveaux de profondeurs, cest
simple dajouter un champ parent_id votre table et de lutiliser pour savoir quel objet est le parent de quel
autre. En natif avec CakePHP, il existe cependant un moyen puissant davoir les bnfices de la logique
MPTT MPTT logic <http ://www.sitepoint.com/hierarchical-data-database-2/>, sans avoir connatre les
dtails de limplmentation technique - moins que a ne vous intresse ;).
Pr-requis
Pour utiliser le behavior en Arbre (TreeBehavior), votre table ncessite 3 champs tels que lists ci-dessous
(tous sont des entiers) :
parent - le nom du champ par dfaut est parent_id, pour stocker lid de lobjet parent.
left - le nom du champ par dfaut est lft, pour stocker la valeur lft de la ligne courante.
right - le nom du champ par dfaut est rght, pour stocker la valeur rght de la ligne courante.
Si vous tes familier de la logique MPTT vous pouvez vous demander pourquoi un champ parent existe parce quil est tout bonnement plus facile deffectuer certaines tches lusage, si un lien parent direct est
stock en base, comme rechercher les enfants directs.
Note : Le champ parent doit tre capable davoir une valeur NULL ! Cela pourrait sembler fonctionner,
si vous donnez juste une valeur parente de zro aux lments de premier niveau, mais le fait de rordonner
larbre (et sans doute dautres oprations) chouera.
Utilisation Basique
Le behavior Tree possde beaucoup de fonctionnalits, mais commenons avec un exemple simple. Crons
la table suivante :
CREATE TABLE categories (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER(10) DEFAULT NULL,
lft INTEGER(10) DEFAULT NULL,
rght INTEGER(10) DEFAULT NULL,
name VARCHAR(255) DEFAULT '',
PRIMARY KEY (id)
);
INSERT INTO
`categories` (`id`, `name`, `parent_id`, `lft`, `rght`)
VALUES
308
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
309
INSERT INTO
`categories` (`id`, `name`, `parent_id`, `lft`, `rght`)
VALUES
(15, 'International', 13, 26, 27);
Dans le but de vrifier que tout est dfini correctement, nous pouvons crer une mthode de test et afficher
les contenus de notre arbre de catgories, pour voir quoi il ressemble. Avec un simple controller :
class CategoriesController extends AppController {
public function index() {
$data = $this->Category->generateTreeList(
null,
null,
null,
' '
);
debug($data); die;
}
}
Nous pouvons vrifier quoi ressemble les donnes de notre arbre de catgories, en visitant /categories.
Vous devriez voir quelque chose comme :
My Categories
Fun
Sport
Surfing
Extreme knitting
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Ajouter des donnes Dans la section prcdente, nous avons utilis des donnes existantes et nous avons
vrifi quelles semblaient hirarchiques avec la mthode generateTreeList. Toutefois vous devez
ajouter vos donnes de la mme manire que vous le feriez pour nimporte quel model. Par exemple :
310
Lorsque vous utilisez le behavior en arbre il nest pas ncessaire de faire plus que de dfinir lid du parent
(parent_id), le behavior tree prendra soin du reste. Si vous ne dfinissez pas lid du parent (parent_id), Le
behavior Tree additionnera vos nouveaux ajouts au sommet de larbre :
// pseudo code du controller
$data = array();
$data['Category']['name'] = 'Other People\'s Categories';
$this->Category->save($data);
Excuter les extraits de code ci-dessus devrait modifier larbre comme suit :
My Categories
Fun
Sport
Surfing
Extreme knitting
Skating New
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories New
Modification des donnes La modification des donnes est aussi transparente que laddition des donnes.
Si vous modifiez quelque chose, mais ne changez pas le champ de lid du parent (parent_id) - la structure de
vos donnes restera inchange. Par exemple :
// pseudo controller code
$this->Category->id = 5; // id of Extreme knitting
$this->Category->save(array('name' => 'Extreme fishing'));
Le code ci-dessus naffecterait pas le champ de lid du parent (parent_id) - mme si lid du parent (parent_id)
est inclue dans les donnes passes sauvegarder si les donnes ne changent pas, pas plus que la structure
de donnes. Donc larbre de donnes devrait maintenant ressembler :
My Categories
Fun
Sport
Surfing
Extreme fishing Updated
Pour en savoir plus sur les Models
311
Skating
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories
Dplacer les donnes autour de votre arbre est aussi une affaire simple. Supposons que Extreme fishing
nappartienne pas Sport, mais devrait se trouver plutt sous Dautres catgories de gens. Avec le code
suivant :
// pseudo controller code
$this->Category->id = 5; // id of Extreme fishing
$newParentId = $this->Category->field(
'id',
array('name' => 'Other People\'s Categories')
);
$this->Category->save(array('parent_id' => $newParentId));
312
313
Sortie :
array(
[1] =>
[2] =>
[3] =>
[4] =>
[16] =>
[6] =>
[7] =>
[8] =>
314
"My Categories",
"_Fun",
"__Sport",
"___Surfing",
"___Skating",
"__Friends",
"___Gerald",
"___Gwendolyn",
[9] =>
[13] =>
[14] =>
[15] =>
[17] =>
[5] =>
"_Work",
"__Trips",
"___National",
"___International",
"Other People's Categories",
"_Extreme fishing"
formatTreeList($results, $options=array())
Introduit dans la version 2.7.
Paramtres
$results Rsultats de lappel de find(all).
$options Options passer.
Cette mthode va retourner des donnes similaires find(list) mais avec un prfix imbriqu qui est
spcifi dans loption spacer pour montrer la structure de vos donnes.
Les options supportes sont :
keyPath : Un chemin vers la cl, par ex {n}.Post.id.
valuePath : Un chemin vers la valeur, par ex {n}.Post.title.
spacer : Le caractre ou les caractres qui seront rpts.
Un exemple serait :
$results = $this->Category->find('all');
$results = $this->Category->formatTreeList($results, array(
'spacer' => '--'
));
getParentNode()
Cette fonction comme son nom lindique, donne en retour le noeud parent dun nud, ou false si le
noeud na pas de parent (cest le nud racine). Par exemple :
$parent = $this->Category->getParentNode(2); //<- id de fun
// $parent contient toutes les catgories
315
),
[1] => array(
'Category' => array('id' => 9, 'name' => 'Work', ..)
),
[2] => array(
'Category' => array('id' => 13, 'name' => 'Trips', ..)
),
[3] => array(
'Category' => array('id' => 15, 'name' => 'International', ..)
),
)
Utilisation avance
Le behavior Tree ne fonctionne pas uniquement en tche de fond, il y a un certain nombre de mthodes
spcifiques dans le behavior Tree pour rpondre a vos besoins de donnes hierarchiques, et des problmes
inattendus qui pourraient survenir durant le processus.
TreeBehavior::moveDown()
Utilis pour dplacer un seul nud dans larbre. Vous devez fournir l ID de llment dplacer et un
nombre positif de combien de positions le noeud devrait tre dplac vers le bas. Tous les nuds enfants
pour le noeud spcifi seront galement dplacs.
Voici lexemple dune action dun controller (dans un controller nomm Category) qui dplace un noeud
spcifi vers le bas de larbre :
public function movedown($id = null, $delta = null) {
$this->Category->id = $id;
if (!$this->Category->exists()) {
throw new NotFoundException(__('Invalid category'));
}
if ($delta > 0) {
$this->Category->moveDown($this->Category->id, abs($delta));
} else {
$this->Session->setFlash(
'Please provide the number of positions the field should be' .
'moved down.'
);
}
return $this->redirect(array('action' => 'index'));
}
Par exemple, si vous souhaitez dplacer le Sport (id de 3) dune catgorie vers le bas, vous devriez requter : /categories/movedown/3/1.
TreeBehavior::moveUp()
Utilis pour dplacer un seul nud de larbre. Vous devez fournir lID de llment dplacer et un nombre
positif de combien de positions le noeud devrait tre dplac vers le haut. Tous les nuds enfants seront
316
galement dplacs.
Voici un exemple dun controller action (dans un controller categories) dplacant un noeud plus haut dans
un arbre :
public function moveup($id = null, $delta = null) {
$this->Category->id = $id;
if (!$this->Category->exists()) {
throw new NotFoundException(__('Invalid category'));
}
if ($delta > 0) {
$this->Category->moveUp($this->Category->id, abs($delta));
} else {
$this->Session->setFlash(
'Please provide a number of positions the category should' .
'be moved up.'
);
}
return $this->redirect(array('action' => 'index'));
}
Par exemple, si vous souhaitez dplacer la catgory Gwendoline (id de 8) plus haut dune position vous
devriez requter : /categories/moveup/8/1. Maintenant lordre des Amis sera Gwendolyn, Grald.
TreeBehavior::removeFromTree($id = null, $delete = false)
En utilisant cette mthode, un neud sera supprime ou dplace, tout en conservant son sous-arbre, qui sera
apparent un niveau suprieur. Il offre plus de contrle que : ref : model-delete qui, pour un model en
utilisant le behavior tree supprimera le noeud spcifi et tous ses enfants.
Prenons larbre suivant au dbut :
My Categories
Fun
Sport
Surfing
Extreme knitting
Skating
En executant le code suivant avec lid de Sport :
$this->Node->removeFromTree($id);
317
Larbre deviendrait
My Categories
Fun
Surfing
Extreme knitting
Skating
Ceci dmontre lutilisation alternative de removeFromTree, les enfants ont t reparents et Sport a t
effac.
TreeBehavior::reorder(array(id => null, field => $Model->displayField, order =>
ASC, verify => true))
Rordonne les nuds (et nuds enfants) de larbre en fonction du champ et de la direction spcifie dans
les paramtres. Cette mthode ne changera pas le parent dun nud.
$model->reorder(array(
//id de l'enregistrement utiliser comme noeud haut pour rordonner, default: $Model->
'id' => ,
//champ utiliser pour rordonner, par dfaut: $Model->displayField
'field' => ,
//direction de l'ordonnement, par dfaut: 'ASC'
'order' => ,
//vrifier ou pas l'arbre avant de rordonner, par dfaut: true
'verify' =>
));
Note : Si vous avez sauvegard vos donnes ou fait dautres oprations sur le model, vous pouvez dfinir
$model->id = null avant dappeler reorder. Sinon, seuls les enfants du nud actuel et ses enfants
seront rordonns.
En raison de la nature complexe auto-rfrentielle de ces structures de donnes comme les arbres et les listes
chanes, elles peuvent parfois se rompre par un appel ngligent. Rassurez-vous, tout nest pas perdu ! Le
behavior Tree contient plusieurs fonctionnalits prcdemment non-documentes destines se remettre de
telles situations.
TreeBehavior::recover($mode = parent, $missingParentAction = null)
Le paramtre mode est utilis pour spcifier la source de linfo qui est correcte. La source oppose de
donnes sera peuple en fonction de cette source dinformation. Ex : si le champ MPTT est corrompu ou
vide, avec le $mode parent la valeur du champ parent_id sera utilise pour peupler les champs
gauche et droite.
Le paramtre missingParentAction sapplique uniquement aux parent mode et dtermine ce quil
faut faire si le champ parent contient un identifiant qui nest pas prsent.
318
TreeBehavior::reorder($options = array())
Rordonne les nuds (et nuds enfants) de larbre en fonction du champ et de la direction spcifis dans
les paramtres. Cette mthode ne change pas le parent dun nud.
La rorganisation affecte tous les nuds dans larborescence par dfaut, mais les options suivantes peuvent
influer sur le processus :
id - ne rordonne que les noeuds sous ce noeud.
field - champ utiliser pour le tri, par dfaut le displayField du model.
order - ASC pour tri ascendant, DESC pour tri descendant.
verify - avec ou sans vrification avant tri.
$options est utilis pour passer tous les paramtres supplmentaires, et les cls suivantes par dfaut,
toutes sont facultatives :
array(
'id' => null,
'field' => $model->displayField,
'order' => 'ASC',
'verify' => true
)
TreeBehavior::verify()
Retourne True si larbre est valide sinon un tableau derreurs, avec des champs pour le type, lindex, et le
message derreur.
Chaque enregistrement dans le tableau de sortie est un tableau de la forme (type, id,message)
type est soit index ou node
id est lid du noeud erron.
message dpend de lerreur rencontre
Exemple dutilisation :
319
$this->Category->verify();
Exemple de sortie :
Array
(
[0] => Array
(
[0] =>
[1] =>
[2] =>
)
[1] => Array
(
[0] =>
[1] =>
[2] =>
)
[10] => Array
(
[0] =>
[1] =>
[2] =>
)
[99] => Array
(
[0] =>
[1] =>
[2] =>
)
"node"
3
"left and right values identical"
"node"
2
"The parent node 999 doesn't exist"
"index"
123
"missing"
"node"
163
"left greater than right"
TreeBehavior::getLevel($id)
Introduit dans la version 2.7.
Si vous ne mettez pas en cache le niveau des noeuds en utilisant loption level dans les configurations,
vous pouvez utiliser cette mthode pour rcuprer le niveau dun noeud en particulier.
320
Cette exemple montre comme un model Category pourrait tre grer dans une structure en arbre en utilisant
le behavior Tree. Une fois quun behavior a t spcifi, utilisez les mthodes quil ajoute comme si elles
avaient toujours exist et fait partie du model original :
// Dfinir ID
$this->Category->id = 42;
// Utiliser la mthode children() du behavior:
$kids = $this->Category->children();
Quelques behaviors peuvent ncessiter ou permettre des rglages quand ils sont attachs au model. Ici, nous
indiquons notre behavior Tree les noms des champs left et right de la table sous-jacente :
class Category extends AppModel {
public $actsAs = array('Tree' => array(
'left' => 'left_node',
'right' => 'right_node'
));
}
Nous pouvons aussi attacher plusieurs behaviors un model. Il ny aucune raison pour que, par exemple,
notre model Category se comporte seulement comme un arbre, il pourrait aussi supporter linternationalisation :
class Category extends AppModel {
public $actsAs = array(
'Tree' => array(
'left' => 'left_node',
'right' => 'right_node'
),
'Translate'
);
}
Jusqu prsent, nous avons ajouter les behaviors aux models en utilisant une variable de classe. Cela signifie
que nos behaviors seront attachs nos models tout au long de leur dure vie. Pourtant, nous pourrions avoir
besoin de dtacher les behaviors des models lexcution. Considrons que dans notre prcdent model
Category, lequel agit comme un model Tree et Translate, nous ayons besoin pour quelque raison de le forcer
ne plus agir comme un model Translate :
// Dtache un behavior de notre model :
$this->Category->Behaviors->unload('Translate');
321
Cela fera que notre model Category arrtera dornavant de se comporter comme un model Translate. Nous
pourrions avoir besoin, sinon, de dsactiver simplement le behavior Translate pour quil nagisse pas sur
les oprations normales de notre model : nos finds, nos saves, etc. En fait, nous cherchons dsactiver le
behavior qui agit sur nos callbacks de model CakePHP. Au lieu de dtacher le behavior, nous allons dire
notre model darrter dinformer ses callbacks du behavior Translate :
// Empcher le behavior de manipuler nos callbacks de model
$this->Category->Behaviors->disable('Translate');
Nous pourrions galement avoir besoin de chercher si notre behavior manipule ces callbacks de model et si
ce nest pas le cas, alors de restaurer sa capacit ragir avec eux :
// Si notre behavior ne manipule pas nos callbacks de model
if (!$this->Category->Behaviors->enabled('Translate')) {
// Disons lui de le faire maintenant !
$this->Category->Behaviors->enable('Translate');
}
De la mme manire que nous pouvons dtacher compltement un behavior dun model lexcution, nous
pouvons aussi attacher de nouveaux behaviors. Disons que notre model familier Category ncessite de se
comporter comme un model Christmas, mais seulement le jour de Nol :
// Si nous sommes le 25 dc
if (date('m/d') === '12/25') {
// Notre model ncessite de se comporter comme un model Christmas
$this->Category->Behaviors->load('Christmas');
}
Nous pouvons aussi utiliser la mthode attach pour surcharger les rglages du behavior :
// Nous changerons un rglage de notre behavior dj attach
$this->Category->Behaviors->load('Tree', array('left' => 'new_left_node'));
Et en utilisant des alias, nous pouvons personnaliser lalias avec lequel il sera charg, lui permettant aussi
dtre charg plusieurs fois avec diffrentes configurations :
// Le behavior sera disponible en tant que 'MyTree'
$this->Category->Behaviors->load('MyTree', array('className' => 'Tree'));
Il y a aussi une mthode pour obtenir la liste des behaviors qui sont attachs un model. Si nous passons
le nom dun behavior une mthode, elle nous dira si ce behavior est attach au model, sinon elle nous
donnera la liste des behaviors attachs :
// Si le behavior Translate n'est pas attach
if (!$this->Category->Behaviors->attached('Translate')) {
// Obtenir la liste de tous les behaviors qui sont attachs au model
$behaviors = $this->Category->Behaviors->attached();
}
322
Puisque les behaviors sont partags travers toutes les instances de model qui lutilisent, une bonne pratique pour stocker les paramtres par nom dalias/model qui utilise le behavior. La cration des behaviors
entranera lappel de leur mthode setup() :
public function setup(Model $Model, $settings = array()) {
if (!isset($this->settings[$Model->alias])) {
$this->settings[$Model->alias] = array(
'option1_key' => 'option1_default_value',
'option2_key' => 'option2_default_value',
'option3_key' => 'option3_default_value',
);
}
$this->settings[$Model->alias] = array_merge(
$this->settings[$Model->alias], (array)$settings);
}
323
Vous seriez capable dappeler les mthodes de FlyingBehavior comme si elles taient des mthodes du
model Duck. Quand vous crez des mthodes dun behavior, vous obtenez automatiquement une rfrence
du model appel en premier paramtre. Tous les autres paramtres fournis sont dcals dune place vers la
droite. Par exemple :
$this->Duck->fly('toronto', 'montreal');
Bien que cette mthode prenne deux paramtres, la mthode signature ressemblerait cela :
public function fly(Model $Model, $from, $to) {
// Faire quelque chose la vole.
}
Gardez lesprit que les mthodes appeles dans un fashion $this->doIt() partir de lintrieur dune
mthode dun behavior nobtiendra pas le paramtre $model automatiquement annex.
Mthodes mappes
En plus de fournir des mthodes mixin, les behaviors peuvent aussi fournir des mthodes dappariemment
de formes (pattern matching). Les Behaviors peuvent aussi dfinir des mthodes mappes. Les mthodes
mappes utilisent les pattern matching for method invocation. Cela vous permet de crer des mthodes
du type Model::findAllByXXX sur vos behaviors. Les mthodes mappes ont besoin dtre dclares
dans votre tableau $mapMethods de behaviors. La signature de la mthode pour une mthode mappe est
lgrement diffrente de celle dune mthode mixin normal dun behavior :
class MyBehavior extends ModelBehavior {
public $mapMethods = array('/do(\w+)/' => 'doSomething');
public function doSomething($model, $method, $arg1, $arg2) {
debug(func_get_args());
//faire quelque chose
}
}
Ce qui est au-dessus mappera chaque mthode doXXX() apple vers le behavior. Comme vous pouvez
le voir, le model est toujours le premier paramtre, mais le nom de la mthode appele sera le deuxime
paramtre. Cela vous permet de munge le nom de la mthode pour des informations supplmentaires, un
peu comme Model::findAllByXX. Si le behavior du dessus est attach un model, ce qui suit arrivera :
$model->doReleaseTheHounds('karl', 'lenny');
// sortira
'ReleaseTheHounds', 'karl', 'lenny'
Callbacks du Behavior
Les Behaviors dun Model peuvent dfinir un nombre de callbacks qui sont dclenchs avant les callbacks
du model du mme nom. Les callbacks du Behavior vous permettent de capturer des vnements dans les
models attachs et daugmenter les paramtres ou de les accoler dans un behavior supplmentaire.
324
Tous les callbacks des behaviors sont lancs avant les callbacks du model :
beforeFind
afterFind
beforeValidate
afterValidate
beforeSave
afterSave
beforeDelete
afterDelete
Crer un callback du behavior
class ModelBehavior
Les callbacks dun behavior dun model sont dfinis comme de simples mthodes dans votre classe de behavior. Un peu comme les mthodes classiques du behavior, ils reoivent un paramtre $Model en premier
argument. Ce paramtre est le model pour lequel la mthode du behavior a t invoque.
ModelBehavior::setup(Model $Model, array $settings = array())
Appele quand un behavior est attach un model. Les paramtres viennent de la proprit $actsAs
du model attach.
ModelBehavior::cleanup(Model $Model)
Appele quand un behavior est dtach dun model. La mthode de base retire les paramtres du
model bases sur $model->alias. Vous pouvez craser cette mthode et fournir une fonctionnalit
personnalise nettoye.
ModelBehavior::beforeFind(Model $Model, array $query)
Si le beforeFind du behavior retourne false, cela annulera le find(). Retourner un tableau augmentera
les paramtres de requte utiliss pour lopration find.
ModelBehavior::afterFind(Model $Model, mixed $results, boolean $primary = false)
Vous pouvez utiliser le afterFind pour augmenter les rsultats dun find. La valeur retourne sera
passe en rsultats soit au behavior suivant dans la chane, soit au afterFind du model.
ModelBehavior::beforeValidate(Model $Model, array $options = array())
Vous pouvez utiliser beforeValidate pour modifier un tableau de validation de model ou grer tout
autrre logique de pr-validation. Retourner false dun callback beforeValidate annulera la validation
et entranera son echec.
ModelBehavior::afterValidate(Model $Model)
Vous pouvez utiliser afterValidate pour lancer un nettoyage de donnes ou prparer des donnes si
besoin.
ModelBehavior::beforeSave(Model $Model, array $options = array())
Vous pouvez retourner false dun beforeSave dun behavior pour annuler la sauvegarde. Retourner
true pour permettre de continuer.
ModelBehavior::afterSave(Model $Model, boolean $created, array $options = array())
Vous pouvez utiliser afterSave pour effectuer des oprations de nettoyage lies au behavior. $created
sera true quand un enregistrement sera cre, et false quand un enregistrement sera mis jour.
325
326
de donnes pourrait
mthodes habituelles
va accder une API
allons la placer dans
App::uses('HttpSocket', 'Network/Http');
class FarAwaySource extends DataSource {
/**
* Une description optionnelle de votre source de donnes
*/
public $description = 'A far away datasource';
/**
* Nos options de config par dfaut. Ces options seront personnalises dans notre
* ``app/Config/database.php`` et seront fusionnes dans le ``__construct()``.
*/
public $config = array(
'apiKey' => '',
);
/**
* Si nous voulons create() ou update(), nous avons besoin de spcifier la
* disponibilit des champs. Nous utilisons le mme tableau indic comme nous le faisions a
* fixtures et schema de migrations.
*/
protected $_schema = array(
'id' => array(
'type' => 'integer',
'null' => false,
'key' => 'primary',
'length' => 11,
327
),
'name' => array(
'type' => 'string',
'null' => true,
'length' => 255,
),
'message' => array(
'type' => 'text',
'null' => true,
),
);
/**
* Crons notre HttpSocket et grons any config tweaks.
*/
public function __construct($config) {
parent::__construct($config);
$this->Http = new HttpSocket();
}
/**
* Puisque les sources de donnes se connectent normalement une base de donnes
* il y a quelques modifications faire pour les faire marcher sans base de donnes.
*/
/**
* listSources() est pour la mise en cache. Vous voulez implmenter la mise en cache
* de votre faon avec une source de donnes personnalise. Donc juste ``return null``.
*/
public function listSources() {
return null;
}
/**
* describe() dit au model votre schema pour ``Model::save()``.
*
* Vous voulez peut-tre un schema diffrent pour chaque model mais utiliser
* toujours une unique source de donnes. Si c'est votre cas, alors
* dfinissez une proprit ``schema`` dans vos models et retournez
* simplement ``$Model->schema`` ici la place.
*/
public function describe(Model $Model) {
return $this->_schema;
}
/**
* calculate() est pour dterminer la faon dont nous allons compter
* les enregistrements et est requis pour faire fonctionner ``update()``
* et ``delete()``.
*
* Nous ne comptons pas les enregistrements ici mais retournons une chane
* passer
* ``read()`` qui va effectivement faire le comptage. La faon la plus
328
/**
* Implmente le R dans CRUD. Appel ``Model::find()`` se trouve ici.
*/
public function read(Model $model, $queryData = array(), $recursive = null) {
/**
* Ici nous faisons rellement le comptage comme demand par notre
* mthode calculate() ci-dessus. Nous pouvons soit vrifier la
* source du dpt, soit une autre faon pour rcuprer le compte
* de l\'enregistrement. Ici nous allons simplement retourner 1
* ainsi ``update()`` et ``delete()`` vont estimer que l\'enregistrement
* existe.
*/
if ($queryData['fields'] === 'COUNT') {
return array(array(array('count' => 1)));
}
/**
* Maintenant nous rcuprons, dcodons et retournons les donnes du dpt.
*/
$queryData['conditions']['apiKey'] = $this->config['apiKey'];
$json = $this->Http->get('http://example.com/api/list.json', $queryData['conditions
$res = json_decode($json, true);
if (is_null($res)) {
$error = json_last_error();
throw new CakeException($error);
}
return array($Model->alias => $res);
}
/**
* Implmente le C dans CRUD. Appel ``Model::save()`` sans $model->id
* dfini se trouve ici.
*/
public function create(Model $model, $fields = null, $values = null) {
$data = array_combine($fields, $values);
$data['apiKey'] = $this->config['apiKey'];
$json = $this->Http->post('http://example.com/api/set.json', $data);
$res = json_decode($json, true);
if (is_null($res)) {
$error = json_last_error();
throw new CakeException($error);
}
return true;
}
/**
* Implmente le U dans CRUD. Appel ``Model::save()`` avec $Model->id
329
* dfini se trouve ici. Selon la source du dpt, vous pouvez juste appeler
* ``$this->create()``.
*/
public function update(Model $model, $fields = null, $values = null, $conditions = null
return $this->create($model, $fields, $values);
}
/**
* Implmente le D de CRUD. Appel ``Model::delete()`` se trouve ici.
*/
public function delete(Model $model, $id = null) {
$json = $this->Http->get('http://example.com/api/remove.json', array(
'id' => $id[$model->alias . '.id'],
'apiKey' => $this->config['apiKey'],
));
$res = json_decode($json, true);
if (is_null($res)) {
$error = json_last_error();
throw new CakeException($error);
}
return true;
}
}
dans
notre
fichier
Et ensuite utiliser la configuration de notre source de donnes dans nos models comme ceci :
class MyModel extends AppModel {
public $useDbConfig = 'faraway';
}
Nous pouvons prsent rcuprer les donnes depuis notre source distante en utilisant les mthodes familires dans notre model :
// Rcupre tous les messages de 'Some Person'
$messages = $this->MyModel->find('all', array(
'conditions' => array('name' => 'Some Person'),
));
Astuce : Lutilisation dautres types de find que all peut avoir des rsultats inattendus si le rsultat de
votre mthode read nest pas un tableau index numriquement.
De la mme faon, nous pouvons sauvegarder un nouveau message :
330
$this->MyModel->save(array(
'name' => 'Some Person',
'message' => 'New Message',
));
Et supprimer le message :
$this->MyModel->delete(42);
lintrieur
de
Plugin/[YourPlugin]/Model/Datasource/[YourSource].php et faites y rfrence
en utilisant la syntaxe pour les plugins :
public $faraway = array(
'datasource' => 'MyPlugin.FarAwaySource',
'apiKey'
=> 'abcd1234',
);
Vrifiez dabord lextension PHP du Serveur SQL pdo_sqlsrv et le Client Native du Serveur SQL.
331
Attributs de Model
Les attributs de Model vous permettent de configurer les proprits qui peuvent surcharger le behavior du
model par dfaut.
Pour une liste complte dattributs du model et ses descriptions, allez voir lAPI de CakePHP 3 .
useDbConfig
La proprit useDbConfig est une chane de caractre qui spcifie le nom de la connexion la base de
donnes utiliser pour lier votre classe model la table de la base de donnes lie. Vous pouvez la configurer
pour nimporte quelles connexions de base de donnes dfinies dans votre fichier de configuration database.
Le fichier de configuration database est plac dans /app/Config/database.php.
La proprit useDbConfig est par dfaut la connexion la base de donnes default.
Exemple dutilisation :
class Exemple extends AppModel {
public $useDbConfig = 'alternate';
}
useTable
La proprit useTable spcifie le nom de la table de la base de donnes. Par dfaut, le model utilise le
nom de classe du model en minuscule, au pluriel. Configurez cette attribut du nom dune table alternative
ou dfinissez le false si vous souhaitez que le model nutilise aucune table de la base de donnes.
Exemple dutilisation :
class Exemple extends AppModel {
public $useTable = false; // Ce model n'utilise pas une table de la base de donnes
}
Alternative :
class Exemple extends AppModel {
public $useTable = 'exmp'; // Ce model utilise une table 'exmp' de la base de donnes
}
tablePrefix
Le nom du prfixe de la table utilis pour le model. Le prfixe de la table est initialement configur dans le
fichier de connexion la base de donnes dans /app/Config/database.php. Par dfaut il ny a pas de prefix.
Vous pouvez craser la valeur par dfaut en configurant lattribut tablePrefix dans le model.
Exemple dutilisation :
3. http ://api.cakephp.org/2.4/class-Model.html
332
primaryKey
Chaque table a normalement une cl primaire, id. Vous pouvez changer le nom du champ que le model
utilise en cl primaire. Ceci est courant quand on configure CakePHP pour utiliser une table dune base de
donnes existante.
Exemple dutilisation :
displayField
Lattribut displayField spcifie le champ de la base de donnes qui doit tre utilis comme label pour
un enregistrement. Le label est utilis dans le scaffolding et dans les appels avec find(list). Le
model va utiliser name ou title, par dfaut.
Par exemple, pour utiliser le champ username :
class User extends AppModel {
public $displayField = 'username';
}
Les noms de champ multiple ne peuvent pas tre combins en un champ unique daffichage. Par exemple, vous ne pouvez pas spcifier array(first_name, last_name) en champ afficher. A la
place, crez un champ virtuel avec lattribut de Model virtualFields
recursive
La proprit recursive dfinit la profondeur laquelle CakePHP doit aller attraper les models de donnes
associs via les mthodes find(), findAll() et read().
Imaginez que votre application dispose de Groups qui appartiennent un Domain et ont plusieurs (many)
Users qui leur tour ont plusieurs (many) Articles. vous pouvez dfinir $recursive diffrentes valeurs
bases sur la quantit de donnes que vous souhaitez retourner partir dun appel $this->Group->find() :
-1 CakePHP rcupre seulement les donnes de Group, pas de jointures.
0 CakePHP rcupre les donnes de Group et leur Domain.
1 CakePHP rcupre Group, son domaine et ses Users associs.
2 CakePHP rcupre un Group, son domain, ses Users associs, et les Articles associs des Users.
Ne le dfinissez pas plus que vous navez besoin. Faire que CakePHP rcupre des donnes dont vous
naurez pas besoin va ralentir votre application inutilement. Notez aussi que par dfaut le niveau de recursive
est 1.
333
Note : Si vous voulez combiner $recursive avec la fonctionnalit fields, vous devrez ajouter les colonnes
contenant les cls trangres ncessaires au tableau fields manuellement. Dans lexemple ci-dessus, ceci
pourrait signifier dajouter domain_id.
Le niveau de recursive recommand pour votre application devrait tre -1. Cela vite de rcuprer des donnes lies dans les cas o ce nest pas ncessaire ou mme non souhait. Cest le plus souvent le cas pour
la plupart de vos appels find(). Augmenter le seulement quand cela est souhait ou utilisez le behavior
Containable.
Vous pouvez raliser cela en lajoutant AppModel :
public $recursive = -1;
Si vous utilisez les events dans votre systme, utiliser la valeur -1 pour recursive va dsactiver tous les events
du model associ. Ceci se passe car aucune relation nest cre quand la valeur est dfinie -1.
order
Lordre par dfaut des donnes pour toute opration de type find. Les valeurs possibles incluent :
$order
$order
$order
$order
$order
$order
=
=
=
=
=
=
"field"
"Model.field";
"Model.field asc";
"Model.field ASC";
"Model.field DESC";
array("Model.field" => "asc", "Model.field2" => "DESC");
data
Le contenu pour les donnes attrapes pour le model. Alors que les donnes retournes dune classe de
model sont normalement utilises partir dun appel de find(), vous pourriez avoir besoin daccder aux
informations stockes dans $data lintrieur des callbacks du model.
_schema
Contient les metadata dcrivant les champs de la table de la base de donnes du model. Chaque champ est
dcrit par :
name
type
Les types supports par CakePHP sont :
string Gnralement construit en colonnes CHAR ou VARCHAR. Dans SQL Server, les types NCHAR et
NVARCHAR sont utiliss.
text Correspond aux types TEXT et MONEY.
uuid Correspond au type UUID si une base de donnes en fournit un, sinon cela gnrera un champ
CHAR(36).
integer Correspond aux types INTEGER et SMALLINT fournis par la base de donnes.
334
validate
Cet attribut maintient les rgles qui permettent au model de faire des dcisions de validation de donnes
avant la sauvegarde. Les cls nommes selon les champs maintient les valeurs regex autorisant le model
essayer de faire des correspondances.
Note : Il nest pas ncessaire dappeler validate() avant save() puisque save() va automatiquement valider
vos donnes avant deffectivement les sauvegarder.
Pour plus dinformations sur la validation, regardez la section suivante Validation des Donnes du manuel.
335
virtualFields
Tableau de champs virtuels que le model a. Les champs virtuels sont des alias des expressions SQL. Les
champs ajouts cette proprit vont tre lus comme dautres champs dans un model mais ne seront pas
sauvegardables.
Exemple dutilisation pour MySQL :
public $virtualFields = array(
'name' => "CONCAT(User.first_name, ' ', User.last_name)"
);
Dans les oprations ultrieures de find, vos rsultats de User contiendront une cl name avec le rsultat de
la concatnation. Il nest pas conseill de crer des champs virtuels avec les mmes noms comme colonnes
dans la base de donnes, ceci peut causer des erreurs SQL.
Pour plus dinformations sur la proprit virtualFields, son usage propre, ainsi que des limitations,
regardez les Champs virtuels.
name
Nom du model. Si vous ne le spcifiez pas dans votre fichier model, il sera dfini automatiquement selon le
nom de la classe par le constructeur.
Exemple dutilisation :
class Exemple extends AppModel {
public $name = 'Exemple';
}
cacheQueries
Si dfinie true, les donnes rcupres par le model pendant une requte unique sont mises en cache. Cette
mise en cache est seulement en mmoire, et dure seulement le temps de la requte. Toute requte duplique
pour les mmes donnes va tre gre par le cache.
336
);
return $this->find('all', compact('conditions'));
}
}
Model::associations()
Obtenir les associations :
$result = $this->Exemple->associations();
// $result quivaut array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany')
337
Model::getAffectedRows()
Retourne le nombre de lignes affectes par la dernire requte.
Model::getAssociated(string $type = null)
Rcupre tous les models avec lesquels ce model est associ.
Model::getColumnType(string $column)
Retourne le type de colonne dune colonne du model.
Model::getColumnTypes()
Retourne un tableau associatif des noms de champs et des types de colonnes.
Model::getID(integer $list = 0)
Retourne lID de lenregistrement courant.
Model::getInsertID()
Retourne lID du dernier enregistrement que ce model insre.
Model::getLastInsertID()
Alias pour getInsertID().
Champs virtuels
Les champs virtuels vous permettent de crer des expressions SQL arbitraires et de les assigner des champs
dans un Model. Ces champs ne peuvent pas tre sauvegards, mais seront traits comme les autres champs
du model pour les oprations de lecture. Ils seront indexs sous la cl du model travers les autres champs
du model.
Crer des champs virtuels
Crer des champs virtuels est facile. Dans chaque model, vous pouvez dfinir une proprit
$virtualFields qui contient un tableau de champ => expressions. Un exemple dune dfinition de
champ virtuel en utilisant MySQL serait :
338
et avec PostgreSQL :
public $virtualFields = array(
'nom' => 'User.prenom || \' \' || User.nom_famille'
);
Par consquent, avec les oprations find, les rsultats de lUser contiendraient une cl nom avec le rsultat de
la concatnation. Il nest pas conseill de crer des champs virtuels avec les mmes noms que les colonnes
sur la base de donnes, car cela peut provoquer des erreurs SQL.
Il nest pas toujours utile davoir User.prenom compltement qualifi. Si vous ne suivez pas la convention
(ex : vous avez des relations multiples avec dautres tables) cela entrainera une erreur. Dans ce cas, il est
parfois prfrable de juste utiliser prenom || \\ || nom sans le nom du Model.
Utiliser les champs virtuels
Crer des champs virtuels est simple et facile, interagir avec les champs virtuels peut tre fait travers
diverses mthodes.
Model : :hasField()
Model : :hasField() retournera true si le model a un champ concret pass en premier paramtre. En dfinissant le second paramtre de hasField() true, les champs virtuels seront aussi vrifis quand on vrifiera si
le model a un champ. En utilisant le champ exemple ci-dessus :
Model : :isVirtualField()
Cette mthode peut tre utilise pour vrifier si un champ/colonne est un champ virtuel ou un champ concret.
Retournera true si la colonne est virtuelle :
$this->User->isVirtualField('nom'); //true
$this->User->isVirtualField('prenom'); //false
Model : :getVirtualField()
Cette mthode peut tre utilise pour accder aux expressions SQL qui contiennent un champ virtuel. Si
aucun argument nest fourni, il retournera tout champ virtuel dans un Model :
339
Comme crit prcdemment, Model::find() traitera les champs virtuels un peu comme tout autre
champ dans un model. La valeur du champ virtuel sera place sous la cl du model dans lensemble de
rsultats :
$results = $this->User->find('first');
// les rsultats contiennent le tableau suivant
array(
'User' => array(
'prenom' => 'Mark',
'nom_famille' => 'Story',
'nom' => 'Mark Story',
//plus de champs.
)
);
Puisque que les champs virtuels se comportent un peu plus comme des champs rguliers quand on fait des
find, Controller::paginate() sera aussi capable de trier selon les champs virtuels.
Champs virtuels et alias de models
Quand on utilise les champs virtuels et les models avec des alias qui ne sont pas les mmes que leur nom, on
peut se retrouver avec des problmes comme des champs virtuels qui ne se mettent pas jour pour reflter
lalias li. Si vous utilisez les champs virtuels dans les models qui ont plus dun alias, il est mieux de dfinir
les champs virtuels dans le constructeur de votre model :
Cela permet vos champs virtuels de travailler pour nimporte quel alias que vous donnez un model.
Champs virtuels dans les requtes SQL
Utiliser les fonctions dans les requtes SQL directes assureront que les donnes seront retournes dans le
mme tableau que les donnes du model. Par exemple comme ceci :
340
Si nous voulons grouper les TotalHours dans notre tableau de TimeLog, nous devrons spcifier un champ
virtuel pour notre colonne agrge. Nous pouvons ajouter ce nouveau champ virtuel la vole plutt que de
le dclarer de faon permanente dans le model. Nous fournirons une valeur par dfaut 0 au cas o dautres
requtes attendent dutiliser ce champ virtuel. Si cela arrive, 0 sera retourn dans la colonne TotalHours :
$this->Timelog->virtualFields['TotalHours'] = 0;
En plus dajouter le champ virtuel, nous avons aussi besoin de faire un alias de notre colonne en utilisant la
forme MonModel__MonChamp comme ceci :
Lancer la requte de nouveau aprs avoir spcifi le champ virtuel rsultera en un groupement plus propre
des valeurs :
Array
(
[0] => Array
(
[Timelog] => Array
(
[project_id] => 1234
[TotalHours] => 25.5
)
)
)
341
Une solution pour contourner ce problme commun de mise en uvre consiste copier virtualFields
dun model lautre lors de lexcution, lorsque vous avez besoin dy accder :
$this->virtualFields['nom'] = $this->Author->virtualFields['nom'];
ou :
$this->virtualFields += $this->Author->virtualFields;
Transactions
Pour effectuer une transaction, les tables dun model doivent tre dun type qui supporte les transactions.
Toutes les mthodes de transaction doivent tre effectues sur un objet de Source de Donnes. Pour obtenir
le model de Source de Donnes partir du model, utilisez :
$dataSource = $this->getDataSource();
Vous pouvez utiliser la source de donnes pour commencer, committer, ou faire des roll back des transactions.
$dataSource->begin();
// Effectue certaine tche
if (/*all's well*/) {
$dataSource->commit();
} else {
$dataSource->rollback();
}
342
Cela va raliser une relle transaction imbrique si votre base de donnes le supporte et quelle est active
dans la source de donnes. Les mthodes vont toujours retourner true quand on est en mode transaction et
quand limbrication nest pas supporte ou dsactive.
Si vous voulez utiliser plusieurs dmarrages mais ne pas utiliser la transaction imbrique partir de la base
de donnes, dsactivez-la en utilisant $dataSource->useNestedTransactions = false;. Elle
ne va utiliser que la transaction globale.
La transaction relle imbrique est dsactive par
$dataSource->useNestedTransactions = true;.
dfaut.
Activez-la
en
utilisant
343
344
CHAPITRE 7
Librairies du Coeur
CakePHP est fourni avec une plthore de fonctions et de classes intgres. Ces classes et fonctions tentent
de couvrir certaines des fonctionnalits les plus communes requises dans les applications web.
Usage Gnral
Des librairies usage gnral sont disponibles et rutilises dans plusieurs endroits de CakePHP.
Usage Gnral
Constantes globales et Fonctions
Alors que la plupart de vos activits quotidiennes avec CakePHP sera dinitialiser des classes du noyau,
CakePHP dispose dun certain nombre de fonctions globales de confort qui peuvent arriver point nomm.
La plupart de ses fonctions sont utiliser avec les classes cakePHP (classes de chargement ou de component), mais beaucoup dautres rendent le travail avec les tableaux ou les chanes de caractres un peu plus
simple.
Nous allons aussi couvrir une partie des constantes disponibles dans les applications CakePHP. Lutilisation
des constantes disponibles vous aidera faire des mises jour plus lisses, mais sont aussi des moyens
pratiques pour pointer certains fichiers ou rpertoires dans vos applications CakePHP.
Fonctions Globales
Voici les fonctions disponibles dans le monde CakePHP. La plupart sont juste des emballages pratiques pour
dautres fonctionnalits CakePHP, comme le dbogage et la traduction de contenu.
__(string $string_id[, $formatArgs ])
Cette fonction gre la localisation dans les applications CakePHP. $string_id identifie lID
de la traduction. Les chanes utilises pour la traduction sont traites comme chane formates
345
pour sprintf(). Vous pouvez fournir des arguments supplmentaires pour remplacer les espaces
rservs dans votre chane :
__('You have %s unread messages', h($number));
Usage Gnral
347
Communment
utilis
comme
pluginSplit(Users.User);
ceci
list($plugin, $name) =
pr(mixed $var)
Raccourci pratique pour print_r(), avec un ajout de balises <pre> autour de la sortie.
sortByKey(array &$array, string $sortby, string $order = asc, integer $type =
SORT_NUMERIC)
Tris de $array par la cl $sortby.
stripslashes_deep(array $value)
Enlve rcursivement les slashes de la $valeur passe. Renvoie le tableau modifi.
Dfinitions des constantes du noyau
La plupart des constantes suivantes font rfrence aux chemins dans votre application.
constant APP
Chemin absolu de votre rpertoire des applications avec un slash.
constant APP_DIR
La mme chose que app ou le nom du rpertoire de votre application.
constant APPLIBS
Le chemin du rpertoire Lib de votre application.
constant CACHE
Chemin vers le rpertoire de cache. il peut tre partag entre les htes dans une configuration multiserveurs.
constant CAKE
Chemin vers le rpertoire de CAKE.
constant CAKE_CORE_INCLUDE_PATH
Chemin vers la racine du rpertoire lib.
constant CORE_PATH
Chemin vers le rpertoire racine avec un slash la fin.
constant CSS
Chemin vers le rpertoire CSS publique.
Obsolte depuis la version 2.4.
constant CSS_URL
Chemin web vers le rpertoire CSS.
Obsolte depuis la version 2.4 : Utilisez la valeur de config App.cssBaseUrl la place.
constant DS
Raccourci pour la constante PHP DIRECTORY_SEPARATOR, qui est gale / pour Linux et \ pour
Windows.
constant FULL_BASE_URL
Prfix URL complet. Comme https://example.com
348
Obsolte depuis la version 2.4 : Cette constante est dprcie, vous devriez utiliser
Router::fullbaseUrl() la place.
constant IMAGES
Chemin vers le rpertoire images publique.
Obsolte depuis la version 2.4.
constant IMAGES_URL
Chemin web vers le rpertoire image publique.
Obsolte depuis la version 2.4 : Utilisez la valeur de config App.imageBaseUrl la place.
constant JS
Chemin vers le rpertoire Javascript publique.
Obsolte depuis la version 2.4.
constant JS_URL
Chemin web vers le rpertoire Javascript publique.
Obsolte depuis la version 2.4 : Utilisez la valeur de config App.jsBaseUrl la place.
constant LOGS
Chemin du rpertoire des logs.
constant ROOT
Chemin vers le rpertoire racine.
constant TESTS
Chemin vers le rpertoire de test.
constant TMP
Chemin vers le rpertoire des fichiers temporaires.
constant VENDORS
Chemin vers le rpertoire vendors.
constant WEBROOT_DIR
La mme chose que webroot ou le nom du rpertoire webroot.
constant WWW_ROOT
Chemin daccs complet vers la racine web (webroot).
Dfinition de Constantes de Temps
constant TIME_START
timestamp Unix en microseconde au format float du dmarrage de lapplication.
constant SECOND
gale 1
constant MINUTE
gale 60
constant HOUR
gale 3600
Usage Gnral
349
constant DAY
gale 86400
constant WEEK
gale 604800
constant MONTH
gale 2592000
constant YEAR
gale 31536000
Classe App
class App
La classe App est responsable de la gestion des chemins, la classe de localisation et la classe de chargement.
Assurez-vous que vous suivez les Conventions des Fichiers et des Noms de Classe.
Packages
CakePHP est organis autour de lide de packages, chaque classe appartient un package ou dossier o
dautres classes se trouvent. Vous pouvez configurer chaque localisation de package dans votre application en utilisant App::build(APackage/SubPackage, $paths) pour informer le framework
o chaque classe doit tre charge. Presque toute classe dans le framework CakePHP peut tre change
avec une des vtres compatible. Si vous souhaitez utiliser votre propre classe la place des classes que le
framework fournit, ajoutez seulement la classe vos dossiers libs mulant la localisation du rpertoire
partir duquel CakePHP sattend le trouver.
Par exemple, si vous voulez utiliser votre propre classe HttpSocket, mettez la sous :
app/Lib/Network/Http/HttpSocket.php
Une fois ceci fait, cette App va charger votre fichier la place du fichier de lintrieur de CakePHP.
Chargement des classes
Chargement des fichiers partir des plugins Le chargement des classes dans les plugins fonctionne
un peu de la mme faon que le chargement des classes app et des classes du coeur sauf que vous devez
spcifier le plugin partir du quel vous chargez :
// Charge la classe Comment dans app/Plugin/PluginName/Model/Comment.php
App::uses('Comment', 'PluginName.Model');
Ceci peut tre fait pour tous les packages qui font partie de votre application. Vous pouvez aussi
rcuprer des chemins pour un plugin :
// retourne les chemins de component dans DebugKit
App::path('Component', 'DebugKit');
static App::paths()
Type retourn array
Rcupre tous les chemins chargs actuellement partir de App. Utile pour inspecter ou stocker tous
les chemins que App connait. Pour un chemin vers un package spcifique, utilisez App::path().
static App::core(string $package)
Usage Gnral
351
Si reset est dfini true, tous les plugins chargs seront oublis et ils devront tre rechargs.
Exemples :
App::build(array('controllers' => array('/full/path/to/controllers/')))
//devient
App::build(array('Controller' => array('/full/path/to/Controller/')))
App::build(array('helpers' => array('/full/path/to/views/helpers/')))
//devient
App::build(array('View/Helper' => array('/full/path/to/View/Helper/')))
Modifi dans la version 2.0 : App::build() ne va plus fusionner les chemins de app avec les
chemins du coeur.
352
Ajoutez de nouveaux packages vers une application App::build() peut tre utilis pour ajouter
de nouvelles localisations de package. Ceci est utile quand vous voulez ajouter de nouveaux packages de
niveaux suprieurs ou, des sous-packages votre application :
App::build(array(
'Service' => array('%s' . 'Service' . DS)
), App::REGISTER);
Le %s dans les packages nouvellement enregistrs, sera remplac par le chemin APP. Vous devez inclure
un trailing / dans les packages enregistrs. Une fois que les packages sont enregistrs, vous pouvez utiliser
App::build() pour ajouter/prfixer/remettre les chemins comme dans tout autre package.
Modifi dans la version 2.1 : Les packages enregistrs a t ajout dans 2.1
Trouver les objets que CakePHP connat
Vous pouvez aussi chercher seulement dans les objets de plugin en utilisant la syntaxe de plugin avec
les points :
// retourne array('MyPluginPost', 'MyPluginComment');
App::objects('MyPlugin.Model');
Usage Gnral
353
$path = App::pluginPath('DebugKit');
static App::import(mixed $type = null, string $name = null, mixed $parent = true, array $search
= array(), string $file = null, boolean $return = false)
Type retourn boolean
Au premier coup dil, App::import a lair compliqu, cependant pour la plupart des utilisations,
seuls 2 arguments sont ncessaires.
Note : Cette mthode est quivalente faire un require sur le fichier. Il est important de raliser
que la classe doit ensuite tre initialise.
// La mme chose que require('Controller/UsersController.php');
App::import('Controller', 'Users');
// Nous avons besoin de charger la classe
$Users = new UsersController;
// Si nous voulons que les associations de model, les components, etc
soient charges
$Users->constructClasses();
Toutes les classes qui sont charges dans le pass utilisant App : :import(Core, $class) devront
tre charges en utilisant App : :uses() se rfrant au bon package. Ce changement a fourni de
grands gains de performances au framework.
Modifi dans la version 2.0.
Cette mthode ne regarde plus les classes de faon rcursive, elle utilise strictement les valeurs pour
les chemins dfinis dans App::build().
Elle ne sera pas capable de charger App::import(Component, Component), utilisez
App::uses(Component, Controller);.
Utilisez App::import(Lib, CoreClass); pour charger les classes du coeur nest plus
possible.
Importer un fichier non existant, fournir un mauvais type ou un mauvais nom de package, ou des
valeurs null pour les paramtres $name et $file entranera une valeur de retour false.
App::import(Core, CoreClass) nest plus support, utilisez App::uses() la
place et laissez la classe dautochargement faire le reste.
Charger des fichiers de Chargement ne regarde pas de faon rcursive dans le dossier vendors, il ne
convertira plus aussi le fichier avec des underscores comme il le faisait dans le pass.
354
Vous pouvez surcharger presque toute classe dans le framework, les exceptions sont les classes App et
Configure. Quelque soit le moment o vous souhaitez effectuer lcrasement, ajoutez seulement votre
classe dans votre dossier app/Lib en imitant la structure interne du framework. Quelques exemples suivants
Pour craser la classe Dispatcher, crer app/Lib/Routing/Dispatcher.php.
Pour craser la classe CakeRoute, crer app/Lib/Routing/Route/CakeRoute.php.
Pour craser la classe Model, crer app/Lib/Model/Model.php.
Quand vous chargez les fichiers remplacs, les fichiers de app/Lib seront chargs la place des classes
intgres au coeur.
Charger des fichiers Vendor
Vous pouvez utiliser App::uses() pour charger des classes provenant des rpertoires vendors. Elle suit
les mmes conventions que pour le chargement des autres fichiers :
// Charge la classe Geshi dans app/Vendor/Geshi.php
App::uses('Geshi', 'Vendor');
Pour charger les classes se trouvant dans des sous-rpertoires, vous devrez ajouter ces chemins avec
App::build() :
// Charge la classe ClassInSomePackage dans app/Vendor/SomePackage/ClassInSomePackage.php
App::build(array('Vendor' => array(APP . 'Vendor' . DS . 'SomePackage' . DS)));
App::uses('ClassInSomePackage', 'Vendor');
Vos fichiers vendor ne suivent peut-tre pas les conventions, ont une classe qui diffre du nom de fichier ou ne
contiennent pas de classes. Vous pouvez charger ces fichiers en utilisant App::import(). Les exemples
suivants montrent comment charger les fichiers de vendor partir dun certain nombre de structures de
chemin. Ces fichiers vendor pourraient tre localiss dans nimporte quel dossier vendor.
Pour charger app/Vendor/geshi.php :
App::import('Vendor', 'geshi');
Note : Le nom du fichier geshi doit tre en minuscule puisque CakePHP ne le trouvera pas sinon.
Pour charger app/Vendor/flickr/flickr.php :
App::import('Vendor', 'flickr/flickr');
Usage Gnral
355
Cela ne ferait pas de diffrence si vos fichiers vendor taient lintrieur du rpertoire /vendors. CakePHP
le trouvera automatiquement.
Pour charger vendors/vendorName/libFile.php :
static App::init()
Type retourn void
Initialise le cache pour App, enregistre une fonction shutdown (fermeture).
static App::load(string $className)
Type retourn boolean
Mthode pour la gestion automatique des classes. Elle cherchera chaque package de classe dfini
en utilisant App::uses() et avec cette information, elle va transformer le nom du package en un
chemin complet pour charger la classe. Le nom de fichier pour chaque classe devrait suivre le nom
de classe. Par exemple, si une classe est nomme MyCustomClass le nom de fichier devrait tre
MyCustomClass.php.
static App::shutdown()
Type retourn void
Destructeur de lObjet. Ecrit le fichier de cache si les changements ont t faits $_map.
vnements systme
Introduit dans la version 2.1.
La cration dapplications maintenables est la fois une science et un art. Il est connu que la cl pour avoir
des codes de bonne qualit est davoir un couplage plus lche et une cohsion plus leve. La cohsion
signifie que toutes les mthodes et proprits pour une classe sont fortement relis la classe elle mme et
non pas dessayer de faire le travail que dautre objets devraient faire, tandis que un couplage plus lche est
la mesure du degr de resserrement des interconnexions dune classe aux objets externes, et comment cette
classe en dpend.
Tandis que la plupart des structures CakePHP et des librairies par dfaut vous aideront atteindre ce but, il
y a certains cas o vous avez besoin de communiquer proprement avec les autres parties du systme sans
avoir coder en dur ces dpendances, ainsi rduire la cohsion et accrotre le couplage de classe. Un motif
de conception (design pattern) trs russi dans lingnierie software est le modle observateur (Observer
pattern), o les objets peuvent gnrer des vnements et notifier des couteurs (listener) possiblement
anonymes des changements dtats internes.
Les couteurs (listener) dans le modle observateur (Observer pattern) peuvent sabonner de tels vnements et choisir dinteragir sur eux, modifier ltat du sujet ou simplement faire des logs. Si vous avez utilisez
JavaScript dans le pass, vous avez la chance dtre dj familier avec la programmation vnementielle.
356
CakePHP mule plusieurs aspects sur la faon dont les vnements sont dclenchs et manags dans des
frameworks JavaScript comme le populaire jQuery, tout en restant fidle sa conception oriente objet.
Dans cette implmentation, un objet vnement est transport travers tous les couteurs qui dtiennent
linformation et la possibilit darrter la propagation des vnements tout moment. Les couteurs peuvent
senregistrer eux-mmes ou peuvent dlguer cette tche a dautres objets et avoir la chance de modifier
ltat et lvnement lui-mme pour le reste des callbacks.
Le sous-systme devent est au coeur des callbacks de Model, de Behavior, de Controller, de View et de
Helper. Si vous navez jamais utilis aucun deux, vous tes dj quelque part familier avec les events dans
CakePHP.
Exemple dUtilisation dEvent
Supposons que vous codez un Plugin de gestion de panier, et que vous vouliez vous focaliser sur la logique
lors de la commande. Vous ne voulez pas ce moment l inclure la logique pour lexpdition, lemail
ou la dcrmentation du produit dans le stock, mais ce sont des tches importantes pour les personnes
utilisant votre plugin. Si vous nutilisiez pas les vnements vous auriez pu implmenter cela en attachant des
behaviors vos modles ou en ajoutant des composants votre controller. Doing so represents a challenge
most of the time, since you would have to come up with the code for externally loading those behaviors or
attaching hooks to your plugin controllers.
Instead, you can use events to allow you to cleanly separate the concerns of your code and allow additional
concerns to hook into your plugin using events. For example in your Cart plugin you have an Order model
that deals with creating orders. Youd like to notify the rest of the application that an order has been created.
To keep your Order model clean you could use events :
// Cart/Model/Order.php
App::uses('CakeEvent', 'Event');
class Order extends AppModel {
public function place($order) {
if ($this->save($order)) {
$this->Cart->remove($order);
$event = new CakeEvent('Model.Order.afterPlace', $this, array(
'order' => $order
));
$this->getEventManager()->dispatch($event);
return true;
}
return false;
}
}
The above code allows you to easily notify the other parts of the application that an order has been created.
You can then do tasks like send email notifications, update stock, log relevant statistics and other tasks in
separate objects that focus on those concerns.
Usage Gnral
357
In CakePHP events are triggered against event managers. Event managers are available in every Model,
View and Controller using getEventManager() :
$events = $this->getEventManager();
Each model has a separate event manager, while the View and Controller share one. This allows model
events to be self contained, and allow components or controllers to act upon events created in the view if
necessary.
Le gestionnaire dEvent global In addition to instance level event managers, CakePHP provides a global
event manager that allows you to listen to any event fired in an application. This is useful when attaching
listeners to a specific instance might be cumbersome or difficult. The global manager is a singleton instance
of CakeEventManager. When an event is dispatched, it will be dispatched to the both the global and
instance level listeners in priority order. You can access the global manager using a static method :
// Dans n'importe quel fichier de config ou morceau de code qui s'excute avant l'vnement
App::uses('CakeEventManager', 'Event');
CakeEventManager::instance()->attach(
$aCallback,
'Model.Order.afterPlace'
);
Un lment important que vous devriez considrer est quil y a des vnements qui seront dclenchs en
ayant le mme nom mais diffrents sujets, donc les vrifier dans lobjet vnement est gnralement requis
dans chacune des fonctions qui sont attaches globalement pour viter quelques bugs. Souvenez-vous quune
extrme flexibilit implique une extrme complexit.
Modifi dans la version 2.5 : Avant 2.5, les listeners du gestionnaire global taient gards dans une liste
spare et dclenchs avant que les instances de listeners le soient.
Distribution des Events
Une fois obtenue linstance dun gestionnaire dvnement, vous pourrez distribuer les vnements via
dispatch(). Cette mthode prend en argument un instance de la classe CakeEvent. Regardons comment distribuer un vnement :
// Create a new event and dispatch it.
$event = new CakeEvent('Model.Order.afterPlace', $this, array(
'order' => $order
));
$this->getEventManager()->dispatch($event);
CakeEvent reoit 3 arguments dans son constructeur. Le premier est le nom de lvnement, vous devrez essayer de garder ce nom aussi unique que possible, tout en le rendant lisible. Nous vous suggrons
les conventions suivantes : Layer.eventName pour les vnements gnraux qui surviennent un niveau
de couche(ex :Controller.startup,View.beforeRender ) et Layer.Class.eventName pour les vnements qui
358
surviennent dans une classe spcifique sur une couche, par exemple Model.User.afterRegister ou Controller.Courses.invalidAccess.
Le second argument est le sujet subject, ce qui signifie lobjet associ lvnement, habituellement quand
cest la mme classe de dclenchement dvnements que lui mme, $this sera communment utilis. Bien
que Component pourrait lui aussi dclencher les vnements du controller. La classe du sujet est importante parce que les couteurs (listeners) auront des accs immdiats aux proprits des objets et la chance
de les inspecter ou de les changer la vole.
Finalement, le troisime argument est le paramtre dvnement. Ceci peut tre nimporte quelle donne
que vous considrez comme tant utile passer avec laquelle les couteurs peuvent interagir. Mme si cela
peut tre nimporte quel type dargument, nous vous recommandons de passer un tableau associatif, pour
rendre linspection plus facile.
La mthode CakeEventManager::dispatch() accepte les objets vnements comme arguments et
notifie a tous les couteurs et callbacks le passage de cet objet. Ainsi les couteurs greront toute la logique
autour de lvnement afterPlace, vous pouvez enregistrer lheure, envoyer des emails, ventuellement mettre jour les statistiques de lutilisateur dans des objets spars et mme dlguer cela des tches hors-ligne
si vous en avez besoin.
Enregistrer les couteurs Les couteurs (Listeners) sont une alternative, et souvent le moyen le
plus propre denregistrer les callbacks pour un vnement. Ceci est fait en implmentant linterface
CakeEventListener dans chacune de classes ou vous souhaitez enregistrer des callbacks. Les classes
limplmentant doivent fournir la mthode implementedEvents() et retourner un tableau associatif
avec tous les noms dvnements que la classe grera.
Pour en revenir notre exemple prcdent, imaginons que nous avons une classe UserStatistic responsable
du calcul dinformation utiles et de la compilation de statistiques dans le site global. Ce serait naturel de
passer une instance de cette classe comme un callback, au lien dimplmenter une fonction statique personnalis ou la conversion de nimporte quel autre contournement pour dclencher les mthodes de cette classe.
Un couteur (listener) UserStatistics est cr comme ci-dessous
// Dans app/Lib/Event/UserStatistic.php
App::uses('CakeEventListener', 'Event');
class UserStatistic implements CakeEventListener {
public function implementedEvents() {
return array(
'Model.Order.afterPlace' => 'updateBuyStatistic',
);
}
public function updateBuyStatistic($event) {
// Code to update statistics
}
}
// Dans un controller ou n'importe quel endroit o $this->Order est accessible
// Attache l'objet UserStatistic au gestionnaire d'vnement 'Order' (commande)
Usage Gnral
359
Comme vous pouvez le voir dans le code ci-dessus, la fonction attach peut manipuler les instances de linterface CakeEventListener. En interne, le gestionnaire dvnement lira le tableau retourn par la mthode
implementedEvents et relie les callbacks en consquence.
Enregistrer les couteurs Globaux Comme montr dans lexemple ci-dessus, les couteurs dvnement sont placs par convention dans app/Lib/Event. Suivre cette convention vous permet de facilement localiser vos classes dcouteurs. Il est aussi recommand dattacher les couteurs globaux pendant le
processus de bootstrap de votre application :
// Dans app/Config/bootstrap.php
// Charge les couteurs d'vnement globaux.
require_once APP . 'Config' . DS . 'events.php'
Un exemple de fichier de bootstrap dvnement pour notre application de caddie ressemblerait ceci :
// Dans app/Config/events.php
// Charge les couteurs d'vnement
App::uses('UserStatistic', 'Lib/Event');
App::uses('ProductStatistic', 'Lib/Event');
App::uses('CakeEventManager', 'Event');
// Attache les couteurs.
CakeEventManager::instance()->attach(new UserStatistic());
CakeEventManager::instance()->attach(new ProductStatistic());
Enregistrer les couteurs Anonymes Tandis que les objects dcoute dvnements sont gnralement
une meilleure manire dimplmenter les couteurs, vous pouvez aussi attacher nimporte quel callable
comme couteur dvnement. Par exemple, si nous voulions enregistrer chaque commande dans les fichiers
de journalisation, nous utiliserions une simple fonction anonyme pour le faire
// Les fonctions anonymes requirent PHP 5.3+
$this->Order->getEventManager()->attach(function($event) {
CakeLog::write(
'info',
'A new order was placed with id: ' . $event->subject()->id
);
}, 'Model.Order.afterPlace');
En plus des fonctions anonymes, vous pouvez utiliser nimporte quel type de callable support par PHP :
$events = array(
'email-sending' => 'EmailSender::sendBuyEmail',
'inventory' => array($this->InventoryManager, 'decrement'),
);
foreach ($events as $callable) {
360
$eventManager->attach($callable, 'Model.Order.afterPlace');
}
tablir des Priorits Dans certains cas, vous souhaitez excuter un callback et tre sre quil sera excut
avant, ou aprs tous les autres callbacks dj lancs. Par exemple, repensons notre exemple de statistiques
utilisateur. Il serait judicieux de nexcuter cette mthode que si nous sommes srs que lvnement na pas
t annul, quil ny a pas derreur et que les autres callbacks nont pas changs ltat de order lui mme.
Pour ces raisons vous pouvez utiliser les priorits.
Les priorits sont grs en utilisant un nombre associ au callback lui mme. Plus haut est le nombre, plus
tard sera lance la mthode. Les priorits par dfaut des mthodes des callbacks et couteurs sont dfinis
10. Si vous voulez que votre mthode soit lance avant, alors lutilisation de nimporte quelle valeur
plus basse que cette valeur par dfaut vous aidera le faire, mme en mettant la priorit 1 ou une valeur
ngative pourrait fonctionner. Dune autre faon si vous dsirez excuter le callback aprs les autres, lusage
dun nombre au dessus de 10 fonctionnera.
Si deux callbacks se trouvent allous avec le mme niveau de priorit, ils seront excuts avec une rgle
FIFO, la premire mthode dcouteur (listener) attache est appele en premier et ainsi de suite. Vous
dfinissez les priorits en utilisant la mthode attach pour les callbacks, et les dclarer dans une fonction
implementedEvents pour les couteurs dvnements :
Comme vous pouvez le voir, la principale diffrence pour les objets CakeEventListener cest que vous avez
utiliser un tableau pour spcifier les mthodes appelables et les prfrences de priorits. La cl appelable
callable est une entre de tableau spciale que le gestionnaire (manager) lira pour savoir quelle fonction
dans la classe il devrait appeler.
Obtenir des Donnes dEvent comme Paramtres de Fonction Certain dveloppeurs pourraient
prfrer avoir les donnes dvnements passes comme des paramtres de fonctions au lieu de recevoir
lobjet vnement. Bien que ce soit une prfrence trange et que lutilisation dobjet vnement est bien
plus puissant, ceci a t ncessaire pour fournir une compatibilit ascendante avec le prcdent systme
dvnement et pour offrir aux dveloppeurs chevronns une alternative pour ce auquel ils sont habitus.
Afin de changer cette option, vous devez ajouter loption passParams au troisime argument de la mthode
attach, ou le dclarer dans le tableau de retour implementedEvents de la mme faon quavec les priorits :
Usage Gnral
361
Note : Les paramtres ne peuvent tre passs comme arguments de fonction que si la donne dvnement
est un tableau. Nimporte quel autre type de donnes sera converti en paramtre de fonction, ne pas utiliser
cette option est souvent plus adquate.
Stopper des Events Il y a des circonstances ou vous aurez besoin de stopper des vnements de sorte
que lopration commence est annule. Vous voyez un exemple de cela dans les callbacks des models (ex.
beforesave) dans lesquels il est possible de stopper une opration de sauvegarde si le code dtecte quil ne
peut pas aller plus loin.
Afin de stopper les vnements vous pouvez soit retourner false dans vos callbacks ou appeler la mthode
stopPropagation sur lobjet vnement :
public function doSomething($event) {
// ...
return false; // stoppe l'vnement
}
public function updateBuyStatistic($event) {
// ...
$event->stopPropagation();
}
Stopper un vnement peut avoir deux effets diffrents. Le premier peut toujours tre attendu ; nimporte
quel callback aprs lvnement qui t stopp ne sera appel. La seconde consquence est optionnelle et
dpend du code qui dclenche lvnement, par exemple, dans votre exemple afterPlace cela naurait pas
362
de sens dannuler lopration tant que les donnes naurons pas toutes t enregistres et le Caddie vid.
Nanmoins, si nous avons une beforePlace arrtant lvnement cela semble valable.
Pour vrifier quun vnement a t stopp, vous appelez la mthode isStopped() dans lobjet vnement :
public function place($order) {
$event = new CakeEvent('Model.Order.beforePlace', $this, array('order' => $order));
$this->getEventManager()->dispatch($event);
if ($event->isStopped()) {
return false;
}
if ($this->Order->save($order)) {
// ...
}
// ...
}
Dans lexemple prcdent la vente ne serait pas enregistre si lvnement est stopp durant le processus
beforePlace.
Rcuprer les Rsultats dEvent Chacune des fois ou un callback retourne une valeur, celle ci est stocke
dans la proprit $result de lobjet vnement. Cest utile dans certains cas o laisser les callbacks modifier
les paramtres principaux de processus augmente la possibilit de modifier laspect dexcution des processus. Regardons encore notre exemple beforePlace et laissons les callbacks modifier la donne $order
(commande).
Les rsultats dvnement peuvent tre modifis soit en utilisant directement la proprit result de lobjet
event ou en retournant une valeur dans le callback lui mme.
// Un couteur (listener) de callback
public function doSomething($event) {
// ...
$alteredData = $event->data['order']
return $alteredData;
}
+ $moreData;
Usage Gnral
363
// ...
}
Comme vous lavez peut-tre aussi remarqu, il est possible de modifier nimporte quelle proprit dun
objet vnement et dtre sr que ces nouvelles donnes seront passes au prochain callback. Dans la majeur
partie des cas, fournir des objets comme donne vnement ou rsultat et modifier directement les objets est
la meilleur solution puisque la rfrence est maintenue et que les modifications sont partages travers les
appels callbacks.
Retirer des Callbacks et couteurs (listeners) Si pour quelque raison que ce soit, vous
voulez retirer certains callbacks depuis le gestionnaire dvnement, appelez juste la mthode
CakeEventManager::detach() en utilisant comme arguments les deux premiers paramtres que
vous avez utiliss pour les attacher :
// Attacher une fonction
$this->getEventManager()->attach(array($this, 'doSomething'), 'My.event');
// Dtacher la fonction
$this->getEventManager()->detach(array($this, 'doSomething'), 'My.event');
// Attacher une fonction anonyme (PHP 5.3+ seulement);
$myFunction = function($event) { ... };
$this->getEventManager()->attach($myFunction, 'My.event');
// Dtacher la fonction anonyme
$this->getEventManager()->detach($myFunction, 'My.event');
// Attacher un couteur Cake (CakeEventListener)
$listener = new MyEventListener();
$this->getEventManager()->attach($listener);
// Dtacher une simple cl d'vnement depuis un couteur (listener)
$this->getEventManager()->detach($listener, 'My.event');
// Dtacher tous les callbacks implments par un couteur (listener)
$this->getEventManager()->detach($listener);
Conclusion
Les vnements sont une bonne faon de sparer les proccupations dans votre application et rend les classes
a la fois cohrentes et dcouples des autres, nanmoins lutilisation des vnements nest pas la solution
tous les problmes. Les Events peuvent tre utiliss pour dcoupler le code de lapplication et rendre les
plugins extensibles.
Gardez lesprit que beaucoup de pouvoir implique beaucoup de responsabilit. Utiliser trop devents peut
rendre le debug plus difficile et ncessite des tests dintgration supplmentaires.
Lecture Supplmentaire
364
Collections Les Components, les Helpers, les Behaviors et les Tasks partagent tous une structure similaire et des comportements. CakePHP 2.0 fournit maintenant une API unifie pour interagir avec les objets
collections similaires. Lobjet collection dans cakePHP vous donne un moyen uniforme dinteragir avec
diffrentes sortes dobjets dans votre application.
Mme si les exemples ci-dessous utiliseront des Components, le mme comportement peut tre envisag
pour les Helpers, Behaviors, et des Tasks en plus des components.
Charger et Dcharger les objets Le chargement dobjets sur nimporte quelle collection peut tre effectu
en utilisant la mthode load() :
$this->Prg = $this->Components->load('Prg');
$this->Prg->process();
Au chargement du component, si il nest pas charg dans la collection, une nouvelle instance sera cre. Si
le component est dj charg, une autre instance ne sera pas cre. Au chargement des components, vous
pouvez aussi leurs fournir des configurations additionnelles :
$this->Cookie = $this->Components->load('Cookie', array('name' => 'sweet'));
Tout couple cl/valeur fourni sera passe au constructeur de Component. Une exception cette rgle est
className. ClassName est une cl spciale qui est utilise pour crer des alias dobjets dans une collection. Ceci permet davoir des noms de component qui ne refltent pas les noms de classes, ce qui peut tre
utile quand on tend les components du noyau :
$this->Auth = $this->Components->load('Auth', array('className' => 'MyCustomAuth'));
$this->Auth->user(); // Utilise rellement MyCustomAuth::user();
Linverse du chargement dun objet, est son dchargement. Les objets dchargs sont retirs de la mmoire,
et nauront pas de callbacks supplmentaires dclenchs sur eux :
$this->Components->unload('Cookie');
$this->Cookie->read(); // Fatal error.
Dclenchement de callbacks Les callbacks sont supports par les collections dobjets. Quand une collection a un callback dclench, cette mthode sera appele sur tous les objets activs dans la collection. Vous
pouvez passer des paramtres au boucle de callback comme ceci
$this->Behaviors->trigger('afterFind', array($this, $results, $primary));
Ci-dessus $this sera pass comme premier argument toutes les mthodes afterFind des helpers. Il y a
plusieurs options qui peuvent tre utilises pour contrler comment les callbacks sont tus :
breakOn Dfini la valeur ou aux valeurs pour lesquels vous voulez stopper la propagation. Peut tre
une valeur scalaire, ou un tableau de valeur stopper. False par dfaut.
break Dfini true pour valider larrt. Quand un dclencheur est cass, la dernire valeur
sera retourne. Si utilis en combinaison avec collectReturn les rsultats collects
seront retourns. False par dfaut.
collectReturn Dfini true pour collecter le retour de chaque objet dans un tableau. Ce tableau de
donnes retournes sera retourn depuis lappel trigger(). False par dfaut.
Usage Gnral
365
triggerDisabled Dclenchera le callback sur tous les objets dans la collection mme ceux qui sont
non-activs. False par dfaut.
modParams Permet chacun des objets auquel le callback fait des demandes de modifier les
paramtres de lobjet suivant. Paramtrer modParams en valeur entire vous permettra de modifier le
paramtre avec cet index. Nimporte quelle valeur non-nulle modifiera lindex de paramtre indiqu.
False par dfaut.
Effacer des boucles de callback En utilisant les options break et breakOn vous pouvez annuler une
boucle de callback mi-chemin semblable interrompre la propagation vnementielle en JavaScript
$this->Behaviors->trigger(
'beforeFind',
array($this, $query),
array('break' => true, 'breakOn' => false)
);
Dans lexemple ci-dessus, si nimporte quel behavior retourne false depuis sa mthode beforeFind, il ny
aura pas dautres callback appels. Le retour de trigger() sera false.
Activation et dsactivation des objets Une fois quun objet est charg dans une collection vous pourriez
avoir besoin de le dactiver. Dsactiver un objet dans une collection empche aux futurs callbacks dtre
tus sur lobjet moins que loption triggerDisabled soit utilise :
// Dsactive le Helper HTML
$this->Helpers->disable('Html');
// R-active le Helper plus tard
$this->Helpers->enable('Html');
Les objets dsactivs peuvent toujours avoir leur mthodes et proprits normales utilises. La diffrence
majeure entre un objet activ et dsactiv se fait en regard des callbacks. Vous pouvez interroger une collection pour connatre les objets activs, ou vrifier si un objet spcifique est toujours activ en utilisant
enabled() :
// Vrifie si oui ou on un Helper spcifique est activ.
$this->Helpers->enabled('Html');
// $enabled contiendra un tableau des helpers actuellement activs.
$enabled = $this->Helpers->enabled();
Behaviors (Comportements) Les behaviors (comportements) de Model sont une manire dorganiser
certaines des fonctionnalits dfinies dans les models CakePHP. Ils nous permettent de sparer la logique
qui ne doit pas tre directement relie un model, mais qui ncessite dtre l. En offrant une simple, mais
puissante, manire dtendre les models, les behaviors nous permettent dattacher des fonctionnalits aux
models en dfinissant une simple variable de classe. Cest comme cela que les behaviors permettent de
dbarrasser les models de tout le sur-poids qui ne devrait pas faire partie du contrat mtier quils modlent
ou de ce qui est aussi ncessit par diffrents models et qui peut alors tre extrapol.
366
Par exemple, considrez un model qui nous donne accs une table qui stocke des informations sur la structure dun arbre hirarchique. Supprimer, ajouter ou dplacer les nuds dans larbre nest pas aussi simple
que deffacer, dinsrer ou dditer les lignes dune table. De nombreux enregistrements peuvent ncessiter
une mise jour suite au dplacement des lments. Plutt que de crer ces mthodes de manipulation darbre
une fois par model de base (pour chaque model ncessitant cette fonctionnalit), nous pourrions simplement
dire notre model dutiliser le behavior TreeBehavior ou, en des termes plus formels, nous dirions
notre model de se comporter comme un Arbre. On appelle cela attacher un behavior un model. Avec
une seule ligne de code, notre model CakePHP disposera dun nouvel ensemble complet de mthodes lui
permettant dinteragir avec la structure sous-jacente.
CakePHP contient dj des behaviors pour les structures en arbre, les contenus traduits, les interactions par
liste de contrle daccs, sans oublier les behaviors des contributeurs de la communaut dj disponibles
dans la Boulangerie (Bakery) CakePHP (http ://bakery.cakephp.org). Dans cette section nous couvrirons
le schma dusage classique pour ajouter des behaviors aux models, lutilisation des behaviors intgrs
CakePHP et la manire de crer nos propres behaviors.
Au final, les Behaviors sont Mixins 1 avec les callbacks.
Il y a un certain nombre de Behaviors inclus dans CakePHP. Pour en savoir plus sur chacun, rfrencez-vous
aux chapitres ci-dessous :
ACL
class AclBehavior
Le behavior Acl fournit une solution pour intgrer sans souci un model dans votre systme ACL. Il peut
crer la fois les AROs et les ACOs de manire transparente.
Pour utiliser le nouveau behavior, vous pouvez lajouter la proprit $actsAs de votre model. Quand vous
lajoutez au tableau actsAs, vous choisissez de crer lentre Acl correspondante comme un ARO ou un
ACO. Par dfaut, cela cre des AROs :
class User extends AppModel {
public $actsAs = array('Acl' => array('type' => 'requester'));
}
Ceci attacherait le behavior Acl en mode ARO. Pour attacher le behavior ACL en mode ACO, utilisez
class Post extends AppModel {
public $actsAs = array('Acl' => array('type' => 'controlled'));
}
Pour les models duser et de group il est frquent davoir la fois les noeuds ACO et ARO, pour permettre
cela utilisez :
class User extends AppModel {
public $actsAs = array('Acl' => array('type' => 'both'));
}
Usage Gnral
367
Modifi dans la version 2.1 : Vous pouvez maintenant attacher en toute scurit le behavior Acl (AclBehavior) votre Appmodel. Aco, Aro et Noeud Acl (AclNode) sont dornavant des extensions du Model et
non plus de lAppModel, ceci pouvait causer une boucle infinie. Si pour certaines raisons, votre application
est dpendante de lutilisation des models comme extension de lAppModel, alors copiez Le Noeud Acl
(AclNode) dans votre application et tendez nouveau AppModel.
Utiliser le behavior Acl La plupart des tches du behavior Acl sont ralises de faon transparente, dans
le callback afterSave() de votre model. Cependant, son utilisation ncessite que votre Model ait une mthode
parentNode() dfinie. Ceci est utilis par le behavior Acl, pour dterminer les relations parent->enfant. Une
mthode parentNode() de model doit retourner null ou une rfrence au Model parent :
public function parentNode() {
return null;
}
Si vous voulez dfinir un nud ACO ou ARO comme parent pour votre Model, parentNode() doit retourner
lalias du nud ACO ou ARO :
public function parentNode() {
return 'root_node';
}
Voici un exemple plus complet. Utilisons un model dexemple User, avec User belongsTo Group :
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
$data = $this->data;
if (empty($this->data)) {
$data = $this->read();
}
if (!$data['User']['group_id']) {
return null;
}
return array('Group' => array('id' => $data['User']['group_id']));
}
Dans lexemple ci-dessus, le retour est un tableau qui ressemble aux rsultats dun find de model. Il est
important davoir une valeur did dfinie ou bien la relation parentNode chouera. Le behavior Acl utilise
ces donnes pour construire son arborescense.
node() Le Behavior Acl vous permet aussi de rcuprer le nud Acl associ un enregistrement de model.
Aprs avoir dfini $model->id. Vous pouvez utiliser $model->node() pour rcuprer le nud Acl associ.
Vous pouvez aussi rcuprer le nud Acl de nimporte quelle ligne, en passant un tableau de donnes en
paramtre :
368
$this->User->id = 1;
$noeud = $this->User->node();
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user);
Containable
class ContainableBehavior
Une nouvelle intgration au coeur de CakePHP 1.2 est le Behavior Containable
ContainableBehavior. Ce behavior vous permet de filtrer et de limiter les oprations de rcupration
de donnes find. Utiliser Containable vous aidera a rduire lutilisation inutile de votre base de donnes
et augmentera la vitesse et la plupart des performances de votre application. La classe vous aidera aussi a
chercher et filtrer vos donnes pour vos utilisateurs dune faon propre et cohrente.
Le behavior Containable vous permet de rationaliser et de simplifier les oprations de construction du
model. Il agit en modifiant temporairement ou dfinitivement les associations de vos models. Il fait cela en
utilisant des containements pour gnrer une srie dappels bindModel et unbindModel. tant donn
que Containable modifie seulement les relations dj existantes, il ne vous permettra pas de restreindre les
rsultats pour des associations distantes. Pour cela, vous devriez voir les Tables jointes.
Pour utiliser le nouveau behavior, vous pouvez lajouter la proprit $actAs de votre model :
class Post extends AppModel {
public $actsAs = array('Containable');
}
Utilisation de Containable Pour voir comment Containable fonctionne, regardons quelques exemples.
Premirement, nous commencerons avec un appel find() sur un model nomm Post. Disons que ce
Post a plusieurs (hasMany) Comment, et Post a et appartient plusieurs (hasAndBelongsToMany)
Tag. La quantit de donnes rcupres par un appel find() normal est assez tendue
Usage Gnral
369
debug($this->Post->find('all'));
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[auteur] => Daniel
[email] => dan@example.com
[siteweb] => http://example.com
[commentaire] => Premier commentaire
[created] => 2008-05-18 00:00:00
)
[1] => Array
(
[id] => 2
[post_id] => 1
[auteur] => Sam
[email] => sam@example.net
[siteweb] => http://example.net
[commentaire] => Second commentaire
[created] => 2008-05-18 00:00:00
)
)
[Tag] => Array
(
[0] => Array
(
[id] => 1
[name] => A
)
[1] => Array
(
[id] => 2
[name] => B
)
)
)
[1] => Array
(
[Post] => Array
(...
370
Pour certaines interfaces de votre application, vous pouvez ne pas avoir besoin dautant dinformation depuis
le model Post. Le Behavior containable permet de rduire ce que le find() retourne.
Par exemple, pour ne rcuprer que les informations lies au post vous pouvez faire cela :
$this->Post->contain();
$this->Post->find('all');
Aprs avoir fait cela, vous vous retrouvez avec quelque chose de plus concis :
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[titre] => Second article
[contenu] => bbb
[created] => 2008-05-19 00:00:00
)
)
Ceci nest pas nouveau : en fait, vous pouvez obtenir le mme rsultat sans le behavior Containable
en faisant quelque chose comme :
$this->Post->recursive = -1;
$this->Post->find('all');
Le behavior Containable simpose vraiment quand vous avez des associations complexes, et que
vous voulez rogner le nombre dinformation au mme niveau. La proprit $recursive des models est utile si
vous voulez viter un niveau de rcursivit entier, mais pas pour choisir ce que vous garder chaque niveau.
Regardons ensemble comment la methode contain() agit.
Le premier argument de la mthode accepte le nom, ou un tableau de noms, des models garder lors du find.
Si nous dsirons aller chercher tous les posts et les tags annexes (sans aucune information de commentaire),
nous devons essayer quelque chose comme
$this->Post->contain('Tag');
$this->Post->find('all');
Usage Gnral
371
Sans le behavior Containable, nous finirions par utiliser la mthode unbindModel() du model, plusieurs
fois si nous pluchons plusieurs models. Le behavior Containable fournit un moyen plus propre
pour accomplir cette mme tche.
Des associations plus profondes Containable permet galement daller un peu plus loin : vous pouvez
filtrer les donnes des models associs. si vous regardez les rsultats dun appel find() classique, notez le
champ auteur dans le model Comment. Si vous tes intresss par les posts et les noms des commentaires des auteurs - et rien dautre - vous devez faire quelque chose comme :
$this->Post->contain('Comment.auteur');
$this->Post->find('all');
// ou..
$this->Post->find('all', array('contain' => 'Comment.auteur'));
ici, nous avons dit au behavior Containable de nous donner les informations du post, et uniquement le champ
auteur du model Comment associ. Le rsultat du find ressemble :
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[auteur] => Daniel
[post_id] => 1
)
[1] => Array
(
[auteur] => Sam
[post_id] => 1
)
)
)
[1] => Array
(...
Comme vous pouvez le voir, les tableaux de Comment ne contiennent uniquement que le champ auteur (avec
le post_id qui est requis par CakePHP pour prsenter le rsultat)
372
Vous pouvez galement filtrer les donnes associes Comment en spcifiant une condition :
$this->Post->contain('Comment.author = "Daniel"');
$this->Post->find('all');
//ou...
$this->Post->find('all', array('contain' => 'Comment.author = "Daniel"'));
Ceci nous donne comme rsultat les posts et commentaires dont daniel est lauteur :
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => Premier article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[author] => Daniel
[email] => dan@example.com
[website] => http://example.com
[comment] => Premier commentaire
[created] => 2008-05-18 00:00:00
)
)
)
Il y a un important gain utiliser Containable quand on filtre sur des associations plus profondes. Dans
lexemple prcdent, imaginez que vous avez 3 posts dans votre base de donnes et que Daniel a comment
sur 2 de ces posts. Lopration $this->Post->find(all, array(contain => Comment.author = Daniel)) ;
retournerait TOUS les 3 posts, pas juste les 3 posts que Daniel a comment. Cela ne va pas retourner tous
les comments cependant, juste les comments de Daniel.
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => First article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
Usage Gnral
373
(
[id] => 1
[post_id] => 1
[author] => Daniel
[email] => dan@example.com
[website] => http://example.com
[comment] => First comment
[created] => 2008-05-18 00:00:00
)
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[title] => Second article
[content] => bbb
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
)
)
[2] => Array
(
[Post] => Array
(
[id] => 3
[title] => Third article
[content] => ccc
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 22
[post_id] => 3
[author] => Daniel
[email] => dan@example.com
[website] => http://example.com
[comment] => Another comment
[created] => 2008-05-18 00:00:00
)
)
)
Si vous voulez filtrer les posts selon les comments, pour que les posts non comments par Daniel ne soient
pas retourns, le plus simple est de trouver tous les comments de Daniel et de faire un contain sur les Posts.
$this->Comment->find('all', array(
'conditions' => 'Comment.author = "Daniel"',
374
Des filtres supplmentaires peuvent tre utilises en utilisant les options de recherche standard find :
$this->Post->find('all', array('contain' => array(
'Comment' => array(
'conditions' => array('Comment.author =' => "Daniel"),
'order' => 'Comment.created DESC'
)
)));
Voici un exemple dutilisation de ContainableBehavior quand vous avez des relations profondes et
complexes entre les models.
Examinons les associations des models suivants :
User->Profile
User->Account->AccountSummary
User->Post->PostAttachment->PostAttachmentHistory->HistoryNotes
User->Post->Tag
Voici comment nous rcuprons les associations ci-dessus avec le behavior Containable
$this->User->find('all', array(
'contain' => array(
'Profile',
'Account' => array(
'AccountSummary'
),
'Post' => array(
'PostAttachment' => array(
'fields' => array('id', 'name'),
'PostAttachmentHistory' => array(
'HistoryNotes' => array(
'fields' => array('id', 'note')
)
)
),
'Tag' => array(
'conditions' => array('Tag.name LIKE' => '%happy%')
)
)
)
));
Gardez lesprit que la cl contain nest utilise quune seule fois dans le model principal, vous navez
pas besoin dutiliser contain nouveau dans les models lis.
Note : En utilisant les options fields et contain - noubliez pas dinclure toutes les cls trangres que
votre requte requiert directement ou indirectement. Notez galement que pour que le behavior Containable
puisse fonctionner avec le contain pour tous les models, vous devez lattacher votre AppModel.
Usage Gnral
375
Les options du Behavior Containable Le Behavior Containable a plusieurs options qui peuvent
tre dfinies quand le behavior est attach un model. Ces paramtres vous permettent daffiner le behavior
de Containable et de travailler plus facilement avec les autres behaviors.
recursive (boolean, optional), dfinir true pour permettre au behavior Containable, de dterminer automatiquement le niveau de rcursivit ncessaire pour rcuprer les models spcifis et pour paramtrer
la rcursivit du model ce niveau. Le dfinir false dsactive cette fonctionnalit. La valeur par dfaut
est true.
notices (boolean, optional), met des alertes E_NOTICES pour les liaisons rfrences dans un appel
containable et qui ne sont pas valides. La valeur par dfaut est true.
autoFields (boolean, optional), ajout automatique des champs ncessaires pour rcuprer les liaisons
requtes. La valeur par dfaut est true.
order : (string, optional) lordre dans lequel les elements contenus sont tris.
A partir de lexemple prcdent, ceci est un exemple de la faon de forcer les Posts tre tris selon la date
de dernire modification :
$this->User->find('all', array(
'contain' => array(
'Profile',
'Post' => array(
'order' => 'Post.updated DESC'
)
)
));
Vous pouvez changer les paramtres du Behavior Containable lexcution, en r-attachant le behavior
comme vu au chapitre Behaviors (Comportements) (Utiliser les Behaviors).
Le behavior Containable peut quelque fois causer des problmes avec dautres behaviors ou des requtes
qui utilisent des fonctions dagrgations et/ou des clauses GROUP BY. Si vous obtenez des erreurs SQL
invalides cause du mlange de champs agrgs et non-agrgs, essayer de dsactiver le paramtre
autoFields :
$this->Post->Behaviors->load('Containable', array('autoFields' => false));
Note : Si vous fates un contain des associations travers le model la place, il nhonorera pas loption
rcursive de Containable. Donc si vous dfinissez -1 par exemple pour le model, cela ne marchera pas :
376
$this->User->recursive = -1;
$this->User->contain(array('Profile', 'Account'));
$users = $this->paginate('User');
Le Behavior Translate
class TranslateBehavior
Le behavior Translate est en fait assez simple paramtrer et faire fonctionner out of the box, le tout avec
trs peu de configuration. Dans cette section, vous apprendrez comment ajouter et configurer ce behavior,
pour lutiliser dans nimporte quel model.
Si vous utilisez le behavior Translate en parallle de Containable, assurez-vous de dfinir la cl fields pour
vos requtes. Sinon, vous pourriez vous retrouver avec des fragments SQL gnrs invalides.
Initialisation des tables de la Base de donne i18n Vous pouvez soit utiliser la console CakePHP, soit
les crer manuellement. Il est recommand dutiliser la console pour cela, parce quil pourrait arriver que le
layout change dans les futures versions de CakePHP. En restant fidle la console, cela garantira que vous
ayez le bon layout :
./cake i18n
Slectionner[I], ce qui lancera le script dinitialisation de la base de donnes i18n. Il vous sera demand
si vous voulez supprimer toute table existante et si vous voulez en crer une. Rpondez par oui si vous tes
certain quil ny a pas encore une table i18n et rpondez encore par oui pour crer la table.
Attacher le Behavior Translate vos Models Ajoutez-le votre model en utilisant la proprit
$actsAs comme dans lexemple suivant.
class Post extends AppModel {
public $actsAs = array(
'Translate'
);
}
Ceci ne produira encore rien, parce quil faut un couple doptions avant que cela ne commence fonctionner.
Vous devez dfinir, quels champs du model courant devront tre dtects dans la table de traduction que nous
avons cre prcdemment.
Dfinir les Champs Vous pouvez dfinir les champs en tendant simplement la valeur Translate
avec un autre tableau, comme
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'fieldOne', 'fieldTwo', 'and_so_on'
)
Usage Gnral
377
);
}
Aprs avoir fait cela (par exemple, en prcisant title comme lun des champs), vous avez dj termin
la configuration de base. Super ! Daprs notre exemple courant, le model devrait maintenant ressembler
quelque chose comme cela
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
}
Quand vous dfinissez vos champs traduire dans le Behavior Translate, assurez-vous domettre les champs
du schma de model traduits. Si vous laissez les champs en place, il peut y avoir un problme de rcupration
de donnes avec les locales.
Note : Si tous les champs dans votre model sont traduits, assurez-vous dajouter les colonnes created
et modified votre table. CakePHP a besoin dau moins un champ diffrent dune cl primaire avant
denregistrer un enregistrement.
Conclusion A partir de maintenant, chaque mise jour/cration dun enregistrement fera que le Behavior
Translate copiera la valeur de title dans la table de traduction (par dfaut : i18n), avec la locale courante.
Une locale est un identifiant dune langue, pour ainsi dire.
Lire le contenu traduit Par dfaut, le TranslateBehavior va automatiquement rcuprer et
ajouter les donnes bases sur la locale courante. La locale courante est lue partir de
Configure::read(Config.language) qui est assigne par la classe L10n. Vous pouvez surcharger cette valeur par dfaut la vole en utilisant $Model->locale.
Rcuprer les champs traduits dans une locale spcifique En dfinissant $Model->locale, vous
pouvez lire les traductions pour une locale spcifique :
// Lire les donnes de la locale espagnole.
$this->Post->locale = 'es';
$results = $this->Post->find('first', array(
'conditions' => array('Post.id' => $id)
));
// $results va contenir la traduction espagnole.
Rcuprer tous les enregistrements de traduction pour un champ Si vous voulez avoir tous les enregistrements de traduction attachs lenregistrement de model courant, vous tendez simplement le tableau
champ dans votre paramtrage du behavior, comme montr ci-dessous. Vous tes compltement libre de
choisir le nommage.
378
Note : Lenregistrement du model contient un champ virtuel appel locale. Il indique quelle locale est
utilise dans ce rsultat.
Notez que seuls les champs du model que vous fates avec un find seront traduits. Les Models attachs
via les associations ne seront pas traduits parce que le dclenchement des callbacks sur les models associs
nest actuellement pas support.
Usage Gnral
379
Utiliser la mthode bindTranslation Vous pouvez aussi rcuprer toutes les traductions seulement quand
vous en avez besoin, en utilisant la mthode bindTranslation.
TranslateBehavior::bindTranslation($fields, $reset)
$fields st un tableau associatif compos du champ et du nom de lassociation, dans lequel la cl est le
champ traduisible et la valeur est le nom fictif de lassociation.
Avec ce paramtrage, le rsultat de votre find() devrait ressembler quelque chose comme ceci
Array
(
[Post] => Array
(
[id] => 1
[title] => Beispiel Eintrag
[body] => lorem ipsum...
[locale] => de_de
)
[titleTranslation] => Array
(
[0] => Array
(
[id] => 1
[locale] => en_us
[model] => Post
[foreign_key] => 1
[field] => title
[content] => Example entry
)
[1] => Array
(
[id] => 2
[locale] => de_de
[model] => Post
[foreign_key] => 1
[field] => title
[content] => Beispiel Eintrag
)
)
)
Sauvegarder dans une autre Langue Vous pouvez forcer le model qui utilise le TranslateBehavior
sauvegarder dans une autre langue que celle dtecte.
Pour dire un model dans quelle langue le contenu devra tre sauv, changez simplement la valeur de la
proprit $locale du model, avant que vous ne sauvegardiez les donnes dans la base. Vous pouvez faire cela
380
Traduction de Tables Multiples Si vous attendez beaucoup dentre, vous vous demandez certainement
comment grer tout cela dans une base de donnes qui grossit rapidement. Il y a deux proprits introduite
dans le Behavior Translate qui permettent de spcifier quel model doit tre reli au model qui contient les
traductions.
Ceux-ci sont $translateModel et $translateTable.
Disons que nous voulons sauver nos traductions pour tous les posts dans la table post_i18ns au lieu de la
valeur par dfaut de la table i18n. Pour faire cela vous avez besoin de paramtrer votre model comme cela
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Utilise un model diffrent (et table)
Usage Gnral
381
Note : Il est important vous mettiez au pluriel la table. Cest maintenant un model habituel et il peut tre
trait en tant que tel avec les conventions qui en dcoulent. Le schma de la table elle-mme doit tre
identique celui gnr par la console CakePHP. Pour vous assurer quil sintgre vous pourriez initialiser
une table i18n vide au travers de la console et renommer la table aprs coup.
Crer le Model de Traduction Pour que cela fonctionne vous devez crer le fichier du model actuel dans
le dossier des models. La raison est quil ny a pas de proprit pour dfinir le displayField directement dans
le model utilisant ce behavior.
Assurez vous de changer le $displayField en field.
class PostI18n extends AppModel {
public $displayField = 'field'; // important
}
// nom de fichier: PostI18n.php
Cest tout ce quil faut. Vous pouvez aussi ajouter toutes les proprits des models comme $useTable. Mais
pour une meilleure cohrence nous pouvons faire cela dans le model qui utilise ce model de traduction. Cest
l que loption $translateTable entre en jeu.
Modification de la Table Si vous voulez changer le nom de la table, il vous suffit simplement de dfinir
$translateTable dans votre model, comme ceci
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Utilise un model diffrent
public $translateModel = 'PostI18n';
// Utilise une table diffrente pour translateModel
public $translateTable = 'post_translations';
}
A noter que vous ne pouvez pas utiliser $translateTable seule. Si vous navez pas lintention dutiliser un
Model de traduction $translateModel personnalis, alors laissez cette proprit inchange. La raison
est quelle casserait votre configuration et vous afficherait un message Missing Table pour le model I18n
par dfaut, lequel est cr lexcution.
Tree
class TreeBehavior
382
Cest assez courant de vouloir stocker ses donnes sous une forme hirarchique dans la table dune base
de donnes. Des exemples de tels besoins pourraient tre des catgories avec un nombre illimit de souscatgories, des donnes en relation avec un systme de menu multi-niveaux ou une reprsentation littrale
dune hirarchie, comme celle qui est utilise pour stocker les objets de contrle daccs avec la logique
ACL.
Pour de petits arbres de donnes et les cas o les donnes nont que quelques niveaux de profondeurs, cest
simple dajouter un champ parent_id votre table et de lutiliser pour savoir quel objet est le parent de quel
autre. En natif avec CakePHP, il existe cependant un moyen puissant davoir les bnfices de la logique
MPTT MPTT logic <http ://www.sitepoint.com/hierarchical-data-database-2/>, sans avoir connatre les
dtails de limplmentation technique - moins que a ne vous intresse ;).
Pr-requis Pour utiliser le behavior en Arbre (TreeBehavior), votre table ncessite 3 champs tels que lists
ci-dessous (tous sont des entiers) :
parent - le nom du champ par dfaut est parent_id, pour stocker lid de lobjet parent.
left - le nom du champ par dfaut est lft, pour stocker la valeur lft de la ligne courante.
right - le nom du champ par dfaut est rght, pour stocker la valeur rght de la ligne courante.
Si vous tes familier de la logique MPTT vous pouvez vous demander pourquoi un champ parent existe parce quil est tout bonnement plus facile deffectuer certaines tches lusage, si un lien parent direct est
stock en base, comme rechercher les enfants directs.
Note : Le champ parent doit tre capable davoir une valeur NULL ! Cela pourrait sembler fonctionner,
si vous donnez juste une valeur parente de zro aux lments de premier niveau, mais le fait de rordonner
larbre (et sans doute dautres oprations) chouera.
Utilisation Basique Le behavior Tree possde beaucoup de fonctionnalits, mais commenons avec un
exemple simple. Crons la table suivante :
CREATE TABLE categories (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER(10) DEFAULT NULL,
lft INTEGER(10) DEFAULT NULL,
rght INTEGER(10) DEFAULT NULL,
name VARCHAR(255) DEFAULT '',
PRIMARY KEY (id)
);
INSERT INTO
`categories` (`id`, `name`, `parent_id`, `lft`, `rght`)
VALUES
(1, 'My Categories', NULL, 1, 30);
INSERT INTO
`categories` (`id`, `name`, `parent_id`, `lft`, `rght`)
VALUES
(2, 'Fun', 1, 2, 15);
INSERT INTO
`categories` (`id`, `name`, `parent_id`, `lft`, `rght`)
VALUES
(3, 'Sport', 2, 3, 8);
Usage Gnral
383
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(4, 'Surfing', 3, 4, 5);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(5, 'Extreme knitting', 3, 6, 7);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(6, 'Friends', 2, 9, 14);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(7, 'Gerald', 6, 10, 11);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(8, 'Gwendolyn', 6, 12, 13);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(9, 'Work', 1, 16, 29);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(10, 'Reports', 9, 17, 22);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(11, 'Annual', 10, 18, 19);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(12, 'Status', 10, 20, 21);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(13, 'Trips', 9, 23, 28);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(14, 'National', 13, 24, 25);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(15, 'International', 13, 26, 27);
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
Dans le but de vrifier que tout est dfini correctement, nous pouvons crer une mthode de test et afficher
les contenus de notre arbre de catgories, pour voir quoi il ressemble. Avec un simple controller :
384
Nous pouvons vrifier quoi ressemble les donnes de notre arbre de catgories, en visitant /categories.
Vous devriez voir quelque chose comme :
My Categories
Fun
Sport
Surfing
Extreme knitting
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Ajouter des donnes Dans la section prcdente, nous avons utilis des donnes existantes et nous avons
vrifi quelles semblaient hirarchiques avec la mthode generateTreeList. Toutefois vous devez
ajouter vos donnes de la mme manire que vous le feriez pour nimporte quel model. Par exemple :
// pseudo controller code
$data['Category']['parent_id'] = 3;
$data['Category']['name'] = 'Skating';
$this->Category->save($data);
Lorsque vous utilisez le behavior en arbre il nest pas ncessaire de faire plus que de dfinir lid du parent
(parent_id), le behavior tree prendra soin du reste. Si vous ne dfinissez pas lid du parent (parent_id), Le
behavior Tree additionnera vos nouveaux ajouts au sommet de larbre :
Usage Gnral
385
Excuter les extraits de code ci-dessus devrait modifier larbre comme suit :
My Categories
Fun
Sport
Surfing
Extreme knitting
Skating New
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories New
Modification des donnes La modification des donnes est aussi transparente que laddition des donnes.
Si vous modifiez quelque chose, mais ne changez pas le champ de lid du parent (parent_id) - la structure de
vos donnes restera inchange. Par exemple :
// pseudo controller code
$this->Category->id = 5; // id of Extreme knitting
$this->Category->save(array('name' => 'Extreme fishing'));
Le code ci-dessus naffecterait pas le champ de lid du parent (parent_id) - mme si lid du parent (parent_id)
est inclue dans les donnes passes sauvegarder si les donnes ne changent pas, pas plus que la structure
de donnes. Donc larbre de donnes devrait maintenant ressembler :
My Categories
Fun
Sport
Surfing
Extreme fishing Updated
Skating
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
386
Trips
National
International
Other Peoples Categories
Dplacer les donnes autour de votre arbre est aussi une affaire simple. Supposons que Extreme fishing
nappartienne pas Sport, mais devrait se trouver plutt sous Dautres catgories de gens. Avec le code
suivant :
// pseudo controller code
$this->Category->id = 5; // id of Extreme fishing
$newParentId = $this->Category->field(
'id',
array('name' => 'Other People\'s Categories')
);
$this->Category->save(array('parent_id' => $newParentId));
387
Skating
Friends
Gerald
Gwendolyn
Work
Trips
National
International
Other Peoples Categories
Extreme fishing
Interroger et utiliser vos donnes Utiliser et manipuler des donnes hirarchises peut savrer assez
difficile. Cest pourquoi le behavior tree met votre disposition quelques mthodes de permutations en plus
des mthodes find de bases.
Note : La plupart des mthodes de tree se basent et renvoient des donnes tries en fonction du champ lft.
Si vous appelez find() sans trier en fonction de lft, ou si vous fates une demande de tri sur un tree,
vous risquez dobtenir des rsultats inattendus.
class TreeBehavior
children($id = null, $direct = false, $fields = null, $order = null, $limit = null, $page = 1,
$recursive = null)
Paramtres
$id Lid de lenregistrement rechercher.
$direct Defini true pour ne retourner que les descendants directs.
$fields Un simple champ texte ou un tableau de champs inclure dans le retour.
$order Chane SQL des conditions ORDER BY.
$limit SQL LIMIT dclaration.
$page pour accder aux resultats pagins.
$recursive Nombre du niveau de profondeur pour la rcursivit des models associs.
La mthode children prend la cl primaire (lid dune ligne) et retourne les enfants (children), par
dfaut dans lordre dapparition dans larbre. Le second paramtre optionnel definit si il faut ou non
retourner seulement les enfants directs. En utilisant lexemple des donnes de la section prcdente :
$allChildren = $this->Category->children(1); // un tableau plat 11 lments
// -- ou -$this->Category->id = 1;
$allChildren = $this->Category->children(); // un tableau plat 11 lments
Comme avec la mthode children, childCount prend la valeur de la cl primaire (lid) dune
ligne et retourne combien denfant elle contient.
Le second paramtre optionnel definit si il faut ou non compter les enfants directs. En reprenant
lexemple ci dessus :
$totalChildren = $this->Category->childCount(1); // retournera 11
// -- ou -$this->Category->id = 1;
$directChildren = $this->Category->childCount(); //retournera 11
// Seulement les comptes des descendants directs de cette category
$numChildren = $this->Category->childCount(1, true); // retournera 2
Sortie :
array(
[1] =>
[2] =>
[3] =>
[4] =>
[16] =>
[6] =>
[7] =>
[8] =>
[9] =>
[13] =>
[14] =>
[15] =>
[17] =>
[5] =>
)
"My Categories",
"_Fun",
"__Sport",
"___Surfing",
"___Skating",
"__Friends",
"___Gerald",
"___Gwendolyn",
"_Work",
"__Trips",
"___National",
"___International",
"Other People's Categories",
"_Extreme fishing"
formatTreeList($results, $options=array())
Introduit dans la version 2.7.
Paramtres
$results Rsultats de lappel de find(all).
Usage Gnral
389
getParentNode()
Cette fonction comme son nom lindique, donne en retour le noeud parent dun nud, ou false si le
noeud na pas de parent (cest le nud racine). Par exemple :
$parent = $this->Category->getParentNode(2); //<- id de fun
// $parent contient toutes les catgories
390
Utilisation avance Le behavior Tree ne fonctionne pas uniquement en tche de fond, il y a un certain
nombre de mthodes spcifiques dans le behavior Tree pour rpondre a vos besoins de donnes hierarchiques, et des problmes inattendus qui pourraient survenir durant le processus.
TreeBehavior::moveDown()
Utilis pour dplacer un seul nud dans larbre. Vous devez fournir l ID de llment dplacer et un
nombre positif de combien de positions le noeud devrait tre dplac vers le bas. Tous les nuds enfants
pour le noeud spcifi seront galement dplacs.
Voici lexemple dune action dun controller (dans un controller nomm Category) qui dplace un noeud
spcifi vers le bas de larbre :
public function movedown($id = null, $delta = null) {
$this->Category->id = $id;
if (!$this->Category->exists()) {
throw new NotFoundException(__('Invalid category'));
}
if ($delta > 0) {
$this->Category->moveDown($this->Category->id, abs($delta));
} else {
$this->Session->setFlash(
'Please provide the number of positions the field should be' .
'moved down.'
);
}
return $this->redirect(array('action' => 'index'));
}
Par exemple, si vous souhaitez dplacer le Sport (id de 3) dune catgorie vers le bas, vous devriez requter : /categories/movedown/3/1.
TreeBehavior::moveUp()
Utilis pour dplacer un seul nud de larbre. Vous devez fournir lID de llment dplacer et un nombre
positif de combien de positions le noeud devrait tre dplac vers le haut. Tous les nuds enfants seront
galement dplacs.
Voici un exemple dun controller action (dans un controller categories) dplacant un noeud plus haut dans
un arbre :
public function moveup($id = null, $delta = null) {
$this->Category->id = $id;
if (!$this->Category->exists()) {
throw new NotFoundException(__('Invalid category'));
}
if ($delta > 0) {
$this->Category->moveUp($this->Category->id, abs($delta));
} else {
$this->Session->setFlash(
'Please provide a number of positions the category should' .
Usage Gnral
391
Par exemple, si vous souhaitez dplacer la catgory Gwendoline (id de 8) plus haut dune position vous
devriez requter : /categories/moveup/8/1. Maintenant lordre des Amis sera Gwendolyn, Grald.
TreeBehavior::removeFromTree($id = null, $delete = false)
En utilisant cette mthode, un neud sera supprime ou dplace, tout en conservant son sous-arbre, qui sera
apparent un niveau suprieur. Il offre plus de contrle que : ref : model-delete qui, pour un model en
utilisant le behavior tree supprimera le noeud spcifi et tous ses enfants.
Prenons larbre suivant au dbut :
My Categories
Fun
Sport
Surfing
Extreme knitting
Skating
En executant le code suivant avec lid de Sport :
$this->Node->removeFromTree($id);
Larbre deviendrait
My Categories
Fun
Surfing
Extreme knitting
Skating
Ceci dmontre lutilisation alternative de removeFromTree, les enfants ont t reparents et Sport a t
effac.
TreeBehavior::reorder(array(id => null, field => $Model->displayField, order =>
ASC, verify => true))
392
Rordonne les nuds (et nuds enfants) de larbre en fonction du champ et de la direction spcifie dans
les paramtres. Cette mthode ne changera pas le parent dun nud.
$model->reorder(array(
//id de l'enregistrement utiliser comme noeud haut pour rordonner, default: $Model->
'id' => ,
//champ utiliser pour rordonner, par dfaut: $Model->displayField
'field' => ,
//direction de l'ordonnement, par dfaut: 'ASC'
'order' => ,
//vrifier ou pas l'arbre avant de rordonner, par dfaut: true
'verify' =>
));
Note : Si vous avez sauvegard vos donnes ou fait dautres oprations sur le model, vous pouvez dfinir
$model->id = null avant dappeler reorder. Sinon, seuls les enfants du nud actuel et ses enfants
seront rordonns.
Intgrit des donnes En raison de la nature complexe auto-rfrentielle de ces structures de donnes comme les arbres et les listes chanes, elles peuvent parfois se rompre par un appel ngligent.
Rassurez-vous, tout nest pas perdu ! Le behavior Tree contient plusieurs fonctionnalits prcdemment
non-documentes destines se remettre de telles situations.
TreeBehavior::recover($mode = parent, $missingParentAction = null)
Le paramtre mode est utilis pour spcifier la source de linfo qui est correcte. La source oppose de
donnes sera peuple en fonction de cette source dinformation. Ex : si le champ MPTT est corrompu ou
vide, avec le $mode parent la valeur du champ parent_id sera utilise pour peupler les champs
gauche et droite.
Le paramtre missingParentAction sapplique uniquement aux parent mode et dtermine ce quil
faut faire si le champ parent contient un identifiant qui nest pas prsent.
Options $mode permises :
parent - utilise lactuelparent_idpour mettre jour les champs lft et rght.
tree - utilise les champs actuels lftetrghtpour mettre jour le champ
parent_id
Les options de missingParentActions autorises durant lutilisation de mode=parent :
null - ne fait rien et continue
return - ne fait rien et fait un return
delete - efface le noeud
int - definit parent_id cet id
Exemple :
// Reconstruit tous les champs gauche et droit en se basant sur parent_id
$this->Category->recover();
// ou
$this->Category->recover('parent');
Usage Gnral
393
// Reconstruit tous les parent_id en se basant sur les champs lft et rght
$this->Category->recover('tree');
TreeBehavior::reorder($options = array())
Rordonne les nuds (et nuds enfants) de larbre en fonction du champ et de la direction spcifis dans
les paramtres. Cette mthode ne change pas le parent dun nud.
La rorganisation affecte tous les nuds dans larborescence par dfaut, mais les options suivantes peuvent
influer sur le processus :
id - ne rordonne que les noeuds sous ce noeud.
field - champ utiliser pour le tri, par dfaut le displayField du model.
order - ASC pour tri ascendant, DESC pour tri descendant.
verify - avec ou sans vrification avant tri.
$options est utilis pour passer tous les paramtres supplmentaires, et les cls suivantes par dfaut,
toutes sont facultatives :
array(
'id' => null,
'field' => $model->displayField,
'order' => 'ASC',
'verify' => true
)
TreeBehavior::verify()
Retourne True si larbre est valide sinon un tableau derreurs, avec des champs pour le type, lindex, et le
message derreur.
Chaque enregistrement dans le tableau de sortie est un tableau de la forme (type, id,message)
type est soit index ou node
id est lid du noeud erron.
message dpend de lerreur rencontre
Exemple dutilisation :
$this->Category->verify();
Exemple de sortie :
Array
(
[0] => Array
(
[0] =>
[1] =>
[2] =>
)
[1] => Array
(
[0] =>
[1] =>
[2] =>
)
394
"node"
3
"left and right values identical"
"node"
2
"The parent node 999 doesn't exist"
"index"
123
"missing"
"node"
163
"left greater than right"
TreeBehavior::getLevel($id)
Introduit dans la version 2.7.
Si vous ne mettez pas en cache le niveau des noeuds en utilisant loption level dans les configurations,
vous pouvez utiliser cette mthode pour rcuprer le niveau dun noeud en particulier.
Utiliser les Behaviors Les Behaviors sont attachs aux models grce la variable $actsAs des classes
model :
class Category extends AppModel {
public $actsAs = array('Tree');
}
Cette exemple montre comme un model Category pourrait tre grer dans une structure en arbre en utilisant
le behavior Tree. Une fois quun behavior a t spcifi, utilisez les mthodes quil ajoute comme si elles
avaient toujours exist et fait partie du model original :
// Dfinir ID
$this->Category->id = 42;
// Utiliser la mthode children() du behavior:
$kids = $this->Category->children();
Quelques behaviors peuvent ncessiter ou permettre des rglages quand ils sont attachs au model. Ici, nous
indiquons notre behavior Tree les noms des champs left et right de la table sous-jacente :
Usage Gnral
395
Nous pouvons aussi attacher plusieurs behaviors un model. Il ny aucune raison pour que, par exemple,
notre model Category se comporte seulement comme un arbre, il pourrait aussi supporter linternationalisation :
class Category extends AppModel {
public $actsAs = array(
'Tree' => array(
'left' => 'left_node',
'right' => 'right_node'
),
'Translate'
);
}
Jusqu prsent, nous avons ajouter les behaviors aux models en utilisant une variable de classe. Cela signifie
que nos behaviors seront attachs nos models tout au long de leur dure vie. Pourtant, nous pourrions avoir
besoin de dtacher les behaviors des models lexcution. Considrons que dans notre prcdent model
Category, lequel agit comme un model Tree et Translate, nous ayons besoin pour quelque raison de le forcer
ne plus agir comme un model Translate :
// Dtache un behavior de notre model :
$this->Category->Behaviors->unload('Translate');
Cela fera que notre model Category arrtera dornavant de se comporter comme un model Translate. Nous
pourrions avoir besoin, sinon, de dsactiver simplement le behavior Translate pour quil nagisse pas sur
les oprations normales de notre model : nos finds, nos saves, etc. En fait, nous cherchons dsactiver le
behavior qui agit sur nos callbacks de model CakePHP. Au lieu de dtacher le behavior, nous allons dire
notre model darrter dinformer ses callbacks du behavior Translate :
// Empcher le behavior de manipuler nos callbacks de model
$this->Category->Behaviors->disable('Translate');
Nous pourrions galement avoir besoin de chercher si notre behavior manipule ces callbacks de model et si
ce nest pas le cas, alors de restaurer sa capacit ragir avec eux :
// Si notre behavior ne manipule pas nos callbacks de model
if (!$this->Category->Behaviors->enabled('Translate')) {
// Disons lui de le faire maintenant !
$this->Category->Behaviors->enable('Translate');
}
De la mme manire que nous pouvons dtacher compltement un behavior dun model lexcution, nous
pouvons aussi attacher de nouveaux behaviors. Disons que notre model familier Category ncessite de se
comporter comme un model Christmas, mais seulement le jour de Nol :
396
// Si nous sommes le 25 dc
if (date('m/d') === '12/25') {
// Notre model ncessite de se comporter comme un model Christmas
$this->Category->Behaviors->load('Christmas');
}
Nous pouvons aussi utiliser la mthode attach pour surcharger les rglages du behavior :
// Nous changerons un rglage de notre behavior dj attach
$this->Category->Behaviors->load('Tree', array('left' => 'new_left_node'));
Et en utilisant des alias, nous pouvons personnaliser lalias avec lequel il sera charg, lui permettant aussi
dtre charg plusieurs fois avec diffrentes configurations :
// Le behavior sera disponible en tant que 'MyTree'
$this->Category->Behaviors->load('MyTree', array('className' => 'Tree'));
Il y a aussi une mthode pour obtenir la liste des behaviors qui sont attachs un model. Si nous passons
le nom dun behavior une mthode, elle nous dira si ce behavior est attach au model, sinon elle nous
donnera la liste des behaviors attachs :
// Si le behavior Translate n'est pas attach
if (!$this->Category->Behaviors->attached('Translate')) {
// Obtenir la liste de tous les behaviors qui sont attachs au model
$behaviors = $this->Category->Behaviors->attached();
}
Crer des Behaviors Les behaviors qui sont attachs aux Models voient leurs callbacks appels automatiquement. Ces callbacks sont similaires ceux quon trouve dans les Models : beforeFind,
afterFind, beforeValidate, afterValidate, beforeSave, afterSave, beforeDelete,
afterDelete et onError. Regardez Mthodes Callback.
Vos behaviors devront tre placs dans app/Model/Behavior. Ils sont nomms en CamelCase et suffixs par Behavior, par ex. NomBehavior.php. Il est utile dutiliser un behavior du coeur comme template
quand on cre son propre behavior. Vous les trouverez dans lib/Cake/Model/Behavior/.
Chaque callback et behavior prend comme premier paramtre, une rfrence du model par lequel il est
appel.
En plus de limplmentation des callbacks, vous pouvez ajouter des rglages par behavior et/ou par liaison
dun behavior au model. Des informations propos des rglages spcifiques peuvent tre trouves dans les
chapitres concernant les behaviors du cur et leur configuration.
Voici un exemple rapide qui illustre comment les rglages peuvent tres passs du model au behavior :
class Post extends AppModel {
public $actsAs = array(
'YourBehavior' => array(
'option1_key' => 'option1_valeur'
)
);
}
Usage Gnral
397
Puisque les behaviors sont partags travers toutes les instances de model qui lutilisent, une bonne pratique pour stocker les paramtres par nom dalias/model qui utilise le behavior. La cration des behaviors
entranera lappel de leur mthode setup() :
public function setup(Model $Model, $settings = array()) {
if (!isset($this->settings[$Model->alias])) {
$this->settings[$Model->alias] = array(
'option1_key' => 'option1_default_value',
'option2_key' => 'option2_default_value',
'option3_key' => 'option3_default_value',
);
}
$this->settings[$Model->alias] = array_merge(
$this->settings[$Model->alias], (array)$settings);
}
Crer les mthodes du behavior Les mthodes du Behavior sont automatiquement disponibles sur tout
model qui act as le behavior. Par exemple si vous avez :
class Duck extends AppModel {
public $actsAs = array('Flying');
}
Vous seriez capable dappeler les mthodes de FlyingBehavior comme si elles taient des mthodes du
model Duck. Quand vous crez des mthodes dun behavior, vous obtenez automatiquement une rfrence
du model appel en premier paramtre. Tous les autres paramtres fournis sont dcals dune place vers la
droite. Par exemple :
$this->Duck->fly('toronto', 'montreal');
Bien que cette mthode prenne deux paramtres, la mthode signature ressemblerait cela :
public function fly(Model $Model, $from, $to) {
// Faire quelque chose la vole.
}
Gardez lesprit que les mthodes appeles dans un fashion $this->doIt() partir de lintrieur dune
mthode dun behavior nobtiendra pas le paramtre $model automatiquement annex.
Mthodes mappes En plus de fournir des mthodes mixin, les behaviors peuvent aussi fournir des
mthodes dappariemment de formes (pattern matching). Les Behaviors peuvent aussi dfinir des mthodes
mappes. Les mthodes mappes utilisent les pattern matching for method invocation. Cela vous permet
de crer des mthodes du type Model::findAllByXXX sur vos behaviors. Les mthodes mappes ont
besoin dtre dclares dans votre tableau $mapMethods de behaviors. La signature de la mthode pour
une mthode mappe est lgrement diffrente de celle dune mthode mixin normal dun behavior :
class MyBehavior extends ModelBehavior {
public $mapMethods = array('/do(\w+)/' => 'doSomething');
public function doSomething($model, $method, $arg1, $arg2) {
398
debug(func_get_args());
//faire quelque chose
}
}
Ce qui est au-dessus mappera chaque mthode doXXX() apple vers le behavior. Comme vous pouvez
le voir, le model est toujours le premier paramtre, mais le nom de la mthode appele sera le deuxime
paramtre. Cela vous permet de munge le nom de la mthode pour des informations supplmentaires, un
peu comme Model::findAllByXX. Si le behavior du dessus est attach un model, ce qui suit arrivera :
$model->doReleaseTheHounds('karl', 'lenny');
// sortira
'ReleaseTheHounds', 'karl', 'lenny'
Callbacks du Behavior Les Behaviors dun Model peuvent dfinir un nombre de callbacks qui sont dclenchs avant les callbacks du model du mme nom. Les callbacks du Behavior vous permettent de capturer
des vnements dans les models attachs et daugmenter les paramtres ou de les accoler dans un behavior
supplmentaire.
Tous les callbacks des behaviors sont lancs avant les callbacks du model :
beforeFind
afterFind
beforeValidate
afterValidate
beforeSave
afterSave
beforeDelete
afterDelete
Crer un callback du behavior
class ModelBehavior
Les callbacks dun behavior dun model sont dfinis comme de simples mthodes dans votre classe de behavior. Un peu comme les mthodes classiques du behavior, ils reoivent un paramtre $Model en premier
argument. Ce paramtre est le model pour lequel la mthode du behavior a t invoque.
ModelBehavior::setup(Model $Model, array $settings = array())
Appele quand un behavior est attach un model. Les paramtres viennent de la proprit $actsAs
du model attach.
ModelBehavior::cleanup(Model $Model)
Appele quand un behavior est dtach dun model. La mthode de base retire les paramtres du
model bases sur $model->alias. Vous pouvez craser cette mthode et fournir une fonctionnalit
personnalise nettoye.
ModelBehavior::beforeFind(Model $Model, array $query)
Si le beforeFind du behavior retourne false, cela annulera le find(). Retourner un tableau augmentera
les paramtres de requte utiliss pour lopration find.
Usage Gnral
399
400
)
),
'Cookie' => array('name' => 'CookieMonster')
);
La portion de code prcdente est un exemple de configuration dun component avec le tableau
$components. Tous les components du coeur permettent aux paramtres dtre configurs dans la mthode de votre controller beforeFilter(). Cest utile quand vous avez besoin dassigner les rsultats
dune fonction la proprit dun component. Ceci peut aussi tre exprim comme ceci :
public function beforeFilter() {
$this->Auth->authorize = array('controller');
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login'
);
$this->Cookie->name = 'CookieMonster';
}
Cest possible, cependant, que le component ncessite certaines options de configuration avant que le controller beforeFilter() soit lanc. Pour cela, certains components permettent aux options de configuration dtre dfinies dans le tableau $components :
public $components = array(
'DebugKit.Toolbar' => array('panels' => array('history', 'session'))
);
Consultez la documentation approprie pour connatre les options de configuration que chaque component
fournit.
Un paramtre commun utiliser est loption className, qui vous autorise les alias des components. Cette
fonctionnalit est utile quand vous voulez remplacer $this->Auth ou une autre rfrence de Component
commun avec une implmentation sur mesure :
// app/Controller/PostsController.php
class PostsController extends AppController {
public $components = array(
'Auth' => array(
'className' => 'MyAuth'
)
);
}
// app/Controller/Component/MyAuthComponent.php
App::uses('AuthComponent', 'Controller/Component');
class MyAuthComponent extends AuthComponent {
// Ajouter votre code pour surcharger le AuthComponent du coeur
}
401
Utiliser les Components Une fois que vous avez inclus quelques components dans votre controller, les
utiliser est trs simple. Chaque component que vous utilisez est enregistr comme proprit dans votre
controller. Si vous avez charg la SessionComponent et le CookieComponent dans votre controller,
vous pouvez y accder comme ceci :
class PostsController extends AppController {
public $components = array('Session', 'Cookie');
public function delete() {
if ($this->Post->delete($this->request->data('Post.id')) {
$this->Session->setFlash('Post deleted.');
return $this->redirect(array('action' => 'index'));
}
}
Note : Puisque les Models et les Components sont tous deux ajouts aux controllers en tant que proprit,
ils partagent le mme espace de noms. Assurez vous de ne pas donner le mme nom un component et
un model.
Charger les components la vole Vous navez parfois pas besoin de rendre le component accessible sur
chaque action. Dans ce cas l, vous pouvez charger la vole en utilisant la Component Collection. A partir
de lintrieur dun controller, vous pouvez faire comme ce qui suit :
$this->OneTimer = $this->Components->load('OneTimer');
$this->OneTimer->getTime();
Note : Gardez lesprit que le chargement dun component la vole ne va pas appeler la mthode initialize.
Si le component que vous appelez a cette mthode, vous devrez lappeler manuellement aprs le chargement.
Callbacks des Components Les components vous offrent aussi quelques callbacks durant leur cycle de
vie qui vous permettent daugmenter le cycle de la requte. Allez voir lapi API de Component pour plus
dinformations sur les callbacks possibles des components.
Crer un Component Supposons que notre application en ligne ait besoin de raliser une opration mathmatique complexe dans plusieurs sections diffrentes de lapplication. Nous pourrions crer un component
pour hberger cette logique partage afin de lutiliser dans plusieurs controllers diffrents.
La premire tape consiste crer un nouveau fichier et une classe pour le component. Crez le fichier
dans app/Controller/Component/MathComponent.php. La structure de base pour le component ressemblerait quelque chose comme cela :
402
Note : Tous les components comme Math doivent tendre Component. Ne pas le faire vous enverra une
exception.
Inclure votre component dans vos controllers Une fois notre component termin, nous pouvons lutiliser au sein des controllers de lapplication en plaant son nom (sans la partie Component) dans le
tableau $components du controller. Le controller sera automatiquement pourvu dun nouvel attribut
nomm daprs le component, travers lequel nous pouvons accder une instance de celui-ci :
/* Rend le nouveau component disponible par $this->Math
ainsi que le component standard $this->Session */
public $components = array('Math', 'Session');
Les Components dclars dans AppController seront fusionns avec ceux dclars dans vos autres
controllers. Donc il ny a pas besoin de re-dclarer le mme component deux fois.
Quand vous incluez des Components dans un Controller, vous pouvez aussi dclarer un ensemble de
paramtres qui seront passs la mthode initialize() du Component. Ces paramtres peuvent alors tre
pris en charge par le Component :
public $components = array(
'Math' => array(
'precision' => 2,
'generateurAleatoire' => 'srand'
),
'Session', 'Auth'
);
Usage Gnral
403
Note : Au contraire dun component inclus dans un controller, aucun callback ne sera attrap pour un
component inclus dans un component.
API de Component
class Component
La classe de base de Component vous offre quelques mthodes pour le chargement facile des
autres Components travers ComponentCollection comme nous lavons trait avec la gestion
habituelle des paramtres. Elle fournit aussi des prototypes pour tous les callbacks des components.
Component::__construct(ComponentCollection $collection, $settings = array())
Les Constructeurs pour la classe de base du component. Tous les paramtres se trouvent dans
$settings et ont des proprits publiques. Ils vont avoir leur valeur change pour correspondre
aux valeurs de $settings.
Les Callbacks
Component::initialize(Controller $controller)
Est appele avant la mthode du controller beforeFilter.
Component::startup(Controller $controller)
Est appele aprs la mthode du controller beforeFilter mais avant que le controller nexcute laction
prvue.
Component::beforeRender(Controller $controller)
Est appele aprs que le controller excute la logique de laction requte, mais avant le rendu de la
vue et le layout du controller.
Component::shutdown(Controller $controller)
Est appele avant que la sortie soit envoye au navigateur.
Component::beforeRedirect(Controller $controller, $url, $status=null, $exit=true)
Est invoque quand la mthode de redirection du controller est appele, mais avant toute action qui
suit. Si cette mthode retourne false, le controller ne continuera pas de rediriger la requte. Les variables $url, $status et $exit ont la mme signification que pour la mthode du controller. Vous pouvez
404
aussi retourner une chane de caractre qui sera interprte comme une URL pour rediriger ou retourner un array associatif avec la cl url et ventuellement status et exit.
Helpers (Assistants) Les Helpers (Assistants) sont des classes comme les components, pour la couche de
prsentation de votre application. Ils contiennent la logique de prsentation qui est partage entre plusieurs
vues, elements ou layouts. Ce chapitre vous montrera comment crer vos propres helpers et soulignera les
tches basiques que les helpers du cur de CakePHP peuvent vous aider accomplir.
CakePHP dispose dun certain nombre de helpers qui aident la cration des vues. Ils aident la cration
de balises bien-formates (y compris les formulaires), aident la mise en forme du texte, les dures et les
nombres, et peuvent mme acclrer la fonctionnalit AJAX. Pour plus dinformations sur les helpers inclus
dans CakePHP, regardez le chapitre pour chaque helper :
CacheHelper
class CacheHelper(View $view, array $settings = array())
Le helper Cache permet la mise en cache des layouts (mises en page) et des vues permettant de gagner du
temps pour la rcupration de donnes rptitives. Le systme de cache des vues de CakePHP parse les
layout et les vues comme de simple fichier PHP + HTML. Il faut noter que le helper Cache fonctionne de
faon assez diffrente des autres helpers. Il ne possde pas de mthodes appeles directement. A la place,
une vue est marque de tags, indiquant quels blocs de contenus ne doivent pas tre mis en cache. Le Helper
Cache utilise alors les callbacks du helper pour traiter le fichier et ressortir pour gnrer le fichier de cache.
Quand une URL est appele, CakePHP vrifie si cette requte a dj t mise en cache. Si cest le cas, le
processus de distribution de lURL est abandonn. Chacun des blocs non mis en cache sont rendus selon le
processus normal, et la vue est servie. Cela permet de gagner beaucoup de temps pour chaque requte vers
une URL mise en cache, puisquun minimum de code est excut. Si CakePHP ne trouve pas une vue mise
en cache, ou si le cache a expir pour lURL appele, le processus de requte normal se poursuit.
Utilisation du Helper Il y a deux tapes franchir avant de pouvoir utiliser le Helper Cache. Premirement
dans votre APP/Config/core.php d-commenter lappel Configure write pour Cache.check. Ceci
dira CakePHP de regarder dans le cache, et de gnrer laffichage des fichiers en cache lors du traitement
des demandes.
Une fois que vous avez dcomment la ligne Cache.check vous devez ajouter le helper votre tableau
$helpers de votre controller :
class PostsController extends AppController {
public $helpers = array('Cache');
}
Vous devrez aussi ajouter CacheDispatcher vos filtres de dispatcher dans votre bootstrap :
Configure::write('Dispatcher.filters', array(
'CacheDispatcher'
));
Introduit dans la version 2.3 : Si vous avez une configuration avec des domaines ou des langages multiples,
vous pouvez utiliser Configure : :write(Cache.viewPrefix, YOURPREFIX) ; pour stocker les fichiers de
vue prfixs mis en cache.
Usage Gnral
405
Ceci mettra en cache laction view 10 heures et laction index 13 heures. En plaant une valeur usuelle de
strtotime() dans $cacheAction vous pouvez mettre en cache toutes les actions dans le controller :
public $cacheAction = "1 hour";
Vous pouvez aussi activer les callbacks controller/component pour les vues caches cres avec
CacheHelper. Pour faire cela, vous devez utiliser le format de tableau pour $cacheAction et crer
un tableau comme ceci :
public $cacheAction = array(
'view' => array('callbacks' => true, 'duration' => 21600),
'add' => array('callbacks' => true, 'duration' => 36000),
'index' => array('callbacks' => true, 'duration' => 48000)
);
En paramtrant callbacks => true vous dites au CacheHelper (Assistant Cache) que vous voulez que
les fichiers gnrs crent les components et les models pour le controller. De manire additionnelle, lance la
mthode initialize du component, le beforeFilter du controller, et le dmarrage des callbacks de component.
Note : Dfinir callbacks => true fait chouer en partie le but de la mise en cache. Cest aussi la raison pour
laquelle ceci est dsactiv par dfaut.
Marquer les contenus Non-Cachs dans les Vues Il y aura des fois o vous ne voudrez par mettre
en cache une vue intgrale. Par exemple, certaines parties dune page peuvent tre diffrentes, selon que
lutilisateur est actuellement identifi ou quil visite votre site en tant quinvit.
Pour indiquer que des blocs de contenu ne doivent pas tre mis en cache, entourez-les par < !nocache>
< !/nocache> comme ci-dessous :
<!--nocache-->
<?php if ($this->Session->check('User.name')) : ?>
Bienvenue, <?php echo h($this->Session->read('User.name')); ?>.
<?php else: ?>
<?php echo $html->link('Login', 'users/login')?>
<?php endif; ?>
<!--/nocache-->
406
Note : Vous ne pouvez pas utiliser les tags nocache dans les lments. Puisquil ny a pas de callbacks
autour des lments, ils ne peuvent tre cachs.
Il est noter, quune fois une action mise en cache, la mthode du controller correspondante ne sera plus
appele. Quand un fichier cache est cr, lobjet request, et les variables de vues sont srialises avec
serialize() de PHP.
Avertissement : Si vous avez des variables de vues qui contiennent des contenus inserialisable comme
les objets SimpleXML, des gestionnaires de ressource (resource handles), ou des classes closures Il se
peut que vous ne puissiez pas utiliser la mise en cache des vues.
Nettoyer le Cache Il est important de se rappeler que CakePHP va nettoyer le cache si un model utilis
dans la vue mise en cache a t modifi. Par exemple, si une vue mise en cache utilise des donnes du model
Post et quil y a eu une requte INSERT, UPDATE, ou DELETE sur Post, le cache de cette vue est nettoy,
et un nouveau contenu sera gnr la prochaine requte.
Note : Ce systme de nettoyage automatique requiert que le nom du controller/model fasse partie de lURL.
Si vous avez utilis le routing pour changer vos URLs cela ne fonctionnera pas.
Si vous avez besoin de nettoyer le cache manuellement, vous pouvez le faire en appelant Cache : :clear().
Cela nettoiera toutes les donnes mises en cache, lexception des fichiers de vues mis en cache. Si vous
avez besoin de nettoyer les fichiers de vues, utilisez clearCache().
Flash
class FlashHelper(View $view, array $config = array())
FlashHelper fournit une faon de rendre les messages flash qui sont dfinis dans $_SESSION par FlashComponent. FlashComponent et FlashHelper utilisent principalement des elements pour rendre les messages
flash. Les elements flash se trouvent dans le rpertoire app/View/Elements/Flash. Vous remarquerez
que le template de lApp de CakePHP est livr avec deux elements flash : success.ctp et error.ctp.
FlashHelper remplace la mthode flash() de SessionHelper et doit tre utilis la place de cette
mthode.
Rendre les Messages Flash Pour afficher un message flash, vous pouvez simplement utiliser la mthode
render() du FlashHelper :
<?php echo $this->Flash->render() ?>
Par dfaut, CakePHP utilise une cl flash pour les messages flash dans une session. Mais si vous spcifiez
une cl lors de la dfinition du message flash dans FlashComponent, vous pouvez spcifier la cl flash
rendre :
<?php echo $this->Flash->render('other') ?>
Vous pouvez aussi surcharger toutes les options qui sont dfinies dans FlashComponent :
Usage Gnral
407
Note : Par dfaut, CakePHP nchappe pas le HTML dans les messages flash. Si vous utilisez une requte
ou des donnes dutilisateur dans vos messages flash, vous devez les chapper avec h lors du formatage de
vos messages.
Pour plus dinformations sur le tableau doptions disponibles, consultez la section FlashComponent.
FormHelper
class FormHelper(View $view, array $settings = array())
Le Helper Form prend en charge la plupart des oprations lourdes en cration du formulaire. Le Helper
Form se concentre sur la possibilit de crer des formulaires rapidement, dune manire qui permettra de
rationaliser la validation, la re-population et la mise en page (layout). Le Helper Form est aussi flexible
- Il va faire peu prs tout pour vous en utilisant les conventions, ou vous pouvez utiliser des mthodes
spcifiques pour ne prendre uniquement que ce dont vous avez besoin.
Cration de Formulaire La premire mthode dont vous aurez besoin dutiliser pour prendre pleinement
avantage du Helper Form (Helper Formulaire) est create(). Cette mthode affichera un tag douverture
de formulaire.
FormHelper::create(string $model = null, array $options = array())
Tous les paramtres sont optionnels. Si create() est appele sans paramtres, CakePHP supposera
que vous voulez crer un formulaire en rapport avec le controller courant, ou lURL actuelle. La
mthode par dfaut pour les formulaires est POST. Llment du formulaire est galement renvoy
avec un DOM ID. Cet identifiant est cr partir du nom du model, et du nom du controller en
notation CamelCase (les majuscules dlimitent les mots). Si jappelle create() dans une vue de
UsersController, jobtiendrai ce genre de rendu dans ma vue :
<form id="UserAddForm" method="post" action="/users/add">
Note :
Vous pouvez aussi passer false pour $model. Ceci placera vos donne de formulaire dans le tableau : $this->request->data (au lieu du sous
tableau :$this->request->data[Model]). Cela peut tre pratique pour des formulaires courts qui ne reprsenteraient rien dans votre base de donnes.
La mthode create() nous permet galement de personnaliser plusieurs paramtres. Premirement,
vous pouvez spcifier un nom de model. Ce faisant, vous modifiez le contexte de ce formulaire. Tous
les champs seront supposs dpendre de ce model (sauf si spcifi), et tous les models devront tre
408
lis lui. Si vous ne spcifiez pas de model, CakePHP supposera que vous utilisez le model par dfaut
pour le controller courant.
// si vous tes sur /recipes/add
echo $this->Form->create('Recipe');
Affichera :
<form id="RecipeAddForm" method="post" action="/recipes/add">
Affichera :
<form id="RecipeEditForm" method="post" action="/recipes/edit/5">
<input type="hidden" name="_method" value="PUT" />
Note : Comme cest un formulaire de modification, un champ cach (hidden) est cr pour rcrire
la mthode HTTP par dfaut
A la cration de formulaires pour les models dans des plugins. Nous devrons toujours utiliser la
syntaxe de plugin la cration dun formulaire. Cela assurera que le formulaire est correctement
gnr :
echo $this->Form->create('ContactManager.Contact');
Le tableau $options est lendroit o la plupart des paramtres de configurations sont stocks. Ce
tableau spcial peut contenir un certain nombre de paires cl-valeur qui peuvent affecter la manire
dont le formulaire sera cr.
Modifi dans la version 2.0.
LUrl par dfaut pour tous les formulaires, est maintenant lUrl incluant passed, named, et les
paramtres de requte (querystring). Vous pouvez redfinir cette valeur par dfaut en fournissant
$options[url] en second paramtre de $this->Form->create().
Usage Gnral
409
Affichera :
<form id="UserAddForm" method="get" action="/users/add">
Affichera :
<form id="UserAddForm" enctype="multipart/form-data"
method="post" action="/users/add">
Quand vous utilisez put ou delete, votre formulaire aura un fonctionnement quivalent un formulaire
de type post, mais quand il sera envoy, la mthode de requte HTTP sera respectivement rcrite avec
PUT ou DELETE. Cela permettra CakePHP de crer son propre support REST dans les navigateurs
web.
$options[action] La cl action vous permet de dfinir vers quelle action de votre controller
pointera le formulaire. Par exemple, si vous voulez que le formulaire appelle laction login() de votre
controller courant, vous creriez le tableau $options comme ceci
echo $this->Form->create('User', array('action' => 'login'));
Affichera :
<form id="UserLoginForm" method="post" action="/users/login">
</form>
$options[url] Si laction que vous dsirez appeler avec le formulaire nest pas dans le controller
courant, vous pouvez spcifier une URL dans le formulaire en utilisant la cl url de votre tableau $options. LURL ainsi fournie peut tre relative votre application CakePHP
echo $this->Form->create(null, array(
'url' => array('controller' => 'recipes', 'action' => 'add')
));
Affichera :
<form method="post" action="/recipes/add">
410
Affichera :
<form method="get" action="http://www.google.com/search">
Regardez aussi la mthode HtmlHelper::url() pour plus dexemples sur les diffrents types
dURLs.
$options[default] Si la variable default est dfinie false, laction de soumission du formulaire est change de telle manire que le bouton submit (de soumission) ne soumet plus le formulaire.
Si le formulaire a t cr pour tre soumis par AJAX, mettre la variable default FALSE supprime
le comportement par dfaut du formulaire, ainsi vous pouvez collecter les donnes et les soumettre par
AJAX la place.
$options[inputDefaults] Vous pouvez dclarer un jeu doptions par dfaut pour input()
avec la cl inputDefaults pour personnaliser vos input par dfaut :
echo $this->Form->create('User', array(
'inputDefaults' => array(
'label' => false,
'div' => false
)
));
Tous les input crs partir de ce point hriteraient des options dclares dans inputDefaults. Vous pouvez
redfinir le defaultOptions en dclarant loption dans lappel input() :
// Pas de div, Pas de label
echo $this->Form->input('password');
// a un lment label
echo $this->Form->input('username', array('label' => 'Username'));
Fermer le Formulaire
FormHelper::end($options = null, $secureAttributes = array())
Le FormHelper inclut galement une mthode end() qui complte le marquage du formulaire. Souvent, end() affiche juste la base fermante du formulaire, mais lutilisation de end()
permet galement au FormHelper dajouter les champs caches dont le component Security
SecurityComponent besoin. :
<?php echo $this->Form->create(); ?>
<!-- Ici les lments de Formulaire -->
<?php echo $this->Form->end(); ?>
Si une chane est fournie comme premier argument end(), le FormHelper affichera un bouton submit
nomm en consquence en mme temps que la balise de fermeture du formulaire.
echo $this->Form->end('Termine');
Affichera :
<div class="submit">
<input type="submit" value="Termine" />
</div>
</form>
Usage Gnral
411
Affichera :
<div class="glass-pill"><input type="submit" value="Update!" name="Update"></div>
412
//text
//password
//day, month, year, hour, minute,
//meridian
//textarea
echo $this->Form->end('Add');
Outre les options spcifique pour input() vu ci-dessus, vous pouvez spcifier nimporte quelle
options pour le type dinput et nimporte quel attribut HTML (actuellement dans le focus). Pour plus
dinformation sur les $options et $htmlAttributes voir HTMLHelper.
Supposons un User hasAndBelongsToMany Group. Dans votre controller, dfinissez une variable
camelCase au pluriel (groupe -> groupes dans cette exemple, ou ExtraFunkyModele -> extraFunkyModeles) avec les options de slections. Dans laction du controller vous pouvez dfinir
$this->set('groups', $this->User->Group->find('list'));
Et dans la vue une slection multiple peut tre cre avec ce simple code :
echo $this->Form->input('Group');
Si vous voulez un champ de slection utilisant une relation belongsTo ou hasOne, vous pouvez ajouter
ceci dans votre controller Users (en supposant que lUser belongsTo Group) :
Usage Gnral
413
$this->set('groups', $this->User->Group->find('list'));
Si votre nom de model est compos de deux mots ou plus, ex. UserGroup, quand vous passez les
donnes en utilisant set() vous devrez nommer vos donnes dans un format CamelCase (les Majuscules sparent les mots) et au pluriel comme ceci
$this->set('userGroups', $this->UserGroup->find('list'));
// ou bien
$this->set(
'reallyInappropriateModelNames',
$this->ReallyInappropriateModelName->find('list')
);
Note : Essayez dviter lutilisation de FormHelper : :input() pour gnrer les boutons submit.
Utilisez plutt FormHelper::submit().
FormHelper::inputs(mixed $fields = null, array $blacklist = null, $options = array())
Gnre un ensemble dinputs (entres) pour $fields. Si $fields est null, tous les champs, sauf ceux
dfinis dans $blacklist, du model courant seront utiliss.
En plus de laffichage des champs de controller, $fields peut tre utilis pour contrler legend et fieldset (jeu de champs) rendus avec les cls fieldset et legend.
$form->inputs(array(legend => Ma lgende)); Gnrera un jeu de champs input avec une lgende personnalise. Vous pouvez personnaliser des champs input individuels a travers
$fields comme ceci.
echo $form->inputs(array(
'name' => array('label' => 'label perso')
));
En plus des champs de contrle (fields control), inputs() permet dutiliser quelques options supplmentaires.
fieldset Mis false pour dsactiver le jeu de champs (fieldset). Si une chane est fournit, elle
sera utilise comme nom de classe (classname) pour llment fieldset.
legend Mis false pour dsactiver la lgende (legend) pour le jeu de champs input (input set)
gnr. Ou fournit une chane pour personnaliser le texte de la lgende (legend).
Conventions de nommage des champs Le Helper Form est assez volu. Lorsque vous dfinissez un
nom de champ avec les mthodes du Helper Form, celui-ci gnre automatiquement une balise input base
sur le nom de model courant, selon le format suivant :
<input type="text" id="ModelnameFieldname" name="data[Modelname][fieldname]">
Ceci permet domettre le nom du model lors de la gnration des inputs du model pour lequel le formulaire
t cr. Vous pouvez crez des inputs pour des models associs , ou des models arbitraires en passant
dans Modelname.fieldname comme premier paramtre :
414
echo $this->Form->input('Modelname.fieldname');
Si vous avez besoin de spcifier de multiples champs en utilisant le mme nom de champ, crant ainsi un
tableau qui peut tre sauver en un coup avec saveAll(), utilisez les conventions suivantes :
echo $this->Form->input('Modelname.0.fieldname');
echo $this->Form->input('Modelname.1.fieldname');
Affichera :
<input type="text" id="Modelname0Fieldname"
name="data[Modelname][0][fieldname]">
<input type="text" id="Modelname1Fieldname"
name="data[Modelname][1][fieldname]">
Le Helper Form utilise plusieurs suffixes de champ en interne pour la cration de champ input datetime. Si
vous utilisez des champs nomms year, month, day, hour, minute, or meridian et rencontrez des
problmes pour obtenir un input correct, vous pouvez dfinir le nom name de lattribut pour remplacer le
behavior par dfaut :
echo $this->Form->input('Model.year', array(
'type' => 'text',
'name' => 'data[Model][year]'
));
Affichera :
<div class="input file">
<label for="UserField">Field</label>
<input type="file" name="data[User][field]" value="" id="UserField" />
</div>
<div class="input email">
<label for="UserEmail">Email</label>
<input type="email" name="data[User][email]" value="" id="UserEmail" />
</div>
$options[div] Utilisez cette option pour dfinir les attributs de la div contentant linput. En utilisant une valeur chane configurera le nom de classe de la div. Un tableau cls/valeurs paramtrera les
attributs de la div. Alternativement, vous pouvez dfinir cet cl false pour dsactiver le rendu de la div.
Dfinir le nom de classe :
Usage Gnral
415
Affichera :
<div class="class_name">
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
<div class="input text" id="mainDiv" title="Div Title"
style="display:block">
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
$options[label] Dfinissez cette cl la chane que vous voudriez afficher dans le label qui
accompagne le input :
echo $this->Form->input('User.name', array(
'label' => "Alias de l'user"
));
Affichera :
<div class="input">
<label for="UserName">Alias de l'user</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
416
<div class="input">
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Dfinissez ceci dans un tableau pour fournir des options supplmentaires pour llment label. Si vous
faites cela, vous pouvez utiliser une cl text dans le tableau pour personnaliser le texte du label :
echo $this->Form->input('User.name', array(
'label' => array(
'class' => 'bidule',
'text' => 'le traducteur est fou hihaaarrrr!!!'
)
));
Affichera :
<div class="input">
<label for="UserName" class="bidule">le traducteur est fou hihaaarrrr!!!</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
$options[error] En utilisant cette cl vous permettra de transformer les messages de model par
dfaut et de les utiliser, par exemple, pour dfinir des messages i18n. (cf internationalisation). comporte
un nombre de sous-options qui contrles lenveloppe de llment (wrapping) . Le nom de classe de
llment envelopp, ainsi que les messages derreurs qui contiennent du HTML devront tre chapps.
Pour dsactiver le rendu des messages derreurs dfinissez la cl error false :
$this->Form->input('Model.field', array('error' => false));
Pour viter que le code HTML soit automatiquement chapp dans le rendu du message derreur, dfinissez la sous-option escape false :
$this->Form->input('Model.field', array(
'error' => array(
'attributes' => array('escape' => false)
)
));
Pour surcharger les messages derreurs du model utilisez un tableau avec les cls respectant les rgles de
validation :
$this->Form->input('Model.field', array(
'error' => array('tooShort' => __("Ceci n'est pas assez long"))
));
Comme vu ci-dessus vous pouvez dfinir les messages derreurs pour chacune des rgles de validation de
vos models. Vous pouvez de plus fournir des messages i18n pour vos formulaires.
Introduit dans la version 2.3 : Support pour loption errorMessage a t ajout dans 2.3
Usage Gnral
417
$options[before],
$options[between],
$options[separator],
$options[after]
Utilisez ces cls si vous avez besoin dinjecter quelques balises la sortie de la mthode input().
et
Affichera :
<div class="input">
--avant-<label for="UserField">Field</label>
--entre--<input name="data[User][field]" type="text" value="" id="UserField" />
--aprs-</div>
Pour les input de type radio lattribut separator peut tre utilis pour injecter des balise pour sparer
input/label.
echo $this->Form->input('field', array(
'before' => '--avant--',
'after' => '--aprs--',
'between' => '--entre---',
'separator' => '--sparateur--',
'options' => array('1', '2')
));
Affichera :
<div class="input">
--avant-<input name="data[User][field]" type="radio" value="1" id="UserField1" />
<label for="UserField1">1</label>
--sparateur-<input name="data[User][field]" type="radio" value="2" id="UserField2" />
<label for="UserField2">2</label>
--entre----aprs-</div>
Pour un lment de type date et datetime lattribut separator peut tre utilis pour modifier la chane
entre les select. Par dfaut -.
$options[format] Lordre du code HTML gnr par FormHelper est contrlable comme vous le
souhaitez. loption format supporte un tableau de chane dcrivant le model de page que vous voudriez
que llment suive. Les cls de tableau supportes sont :
array('before', 'input', 'between', 'label', 'after','error')
$options[inputDefaults] Sil vous semble rpter la mme option dans de multiples appels
input(), vous pouvez utiliser inputDefaults pour garder un code propre.
418
Tous les inputs crs a partir de ce point hriterons des valeurs dclares dans inputDefaults. Vous pouvez
redfinir defaultOptions en dclarant loption dans lappel de linput() :
// Pas de div, ni label
echo $this->Form->input('password');
// a un lment label
echo $this->Form->input('username', array('label' => 'Username'));
Si vous avez besoin de changer plus tard les valeurs par dfaut, vous pourrez utiliser
FormHelper::inputDefaults().
GET Form Inputs Quand vous utilisez FormHelper pour gnrer des inputs pour les formulaires GET,
les noms dinput seront automatiquement raccourcis pour que les noms soient plus lisibles pour les humains.
Par exemple :
// Cre <input name="email" type="text" />
echo $this->Form->input('User.email');
// Cre <select name="Tags" multiple="multiple">
echo $this->Form->input('Tags.Tags', array('multiple' => true));
Si vous voulez surcharger les attributs name gnrs, vous pouvez utiliser loption name :
// Cre le plus habituel <input name="data[User][email]" type="text" />
echo $this->Form->input('User.email', array('name' => 'data[User][email]'));
Gnrer des types dinputs spcifiques En plus de la mthode gnrique input(), le FormHelper
des mthodes spcifiques pour gnrer diffrents types dinputs. Ceci peut tre utilis pour gnrer juste un
extrait de code input, et combin avec dautres mthodes comme label() et error() pour gnrer des
layouts (mise en page) compltements personnalises.
Options Communes Beaucoup des diffrentes mthodes dinput supportent un jeu doptions communes.
Toutes ses options sont aussi supports par input(). Pour rduire les rptitions les options communes
partages par toutes les mthodes input sont :
$options[class] Vous pouvez dfinir le nom de classe pour un input :
echo $this->Form->input('title', array('class' => 'class-perso'));
$options[id] Dfinir cette cl pour forcer la valeur du DOM id pour cet input.
Usage Gnral
419
$options[default] Utilis pour dfinir une valeur par dfaut au champ input. La valeur est
utilise si les donnes passes au formulaire ne contiennent pas de valeur pour le champ (ou si aucune
donne nest transmise)
Exemple dutilisation :
echo $this->Form->input('ingredient', array('default' => 'Sucre'));
Exemple avec un champ slectionn (Taille Moyen sera slectionn par dfaut) :
$sizes = array('s' => 'Small', 'm' => 'Medium', 'l' => 'Large');
echo $this->Form->input('size', array('options' => $sizes, 'default' => 'm'));
Note : Vous ne pouvez pas utiliser default pour slectionner une chekbox - vous devez plutt dfinir
cette valeur dans $this->request->data dans votre controller, ou dfinir loption checked de
input true.
La valeur par dfaut des champs Date et datetime peut tre dfinie en utilisant la cl selected.
Attention lutilisation de false pour assigner une valeur par dfaut. Une valeur false est utilis pour
dsactiver/exclure les options dun champ, ainsi default => false ne dfinirait aucune valeur.
A la place, utilisez default => 0.
En plus des options ci-dessus, vous pouvez mixer nimporte quel attribut HTML que vous souhaitez utiliser.
Chacun des nom doptions non-special sera trait comme un attribut HTML, et appliqu a llment HTML
gnr.
Les options pour select, checkbox et inputs radio
$options[selected] Utilis en combinaison avec un input de type select (ex. Pour les types
select, date, heure, datetime) . Dfinissez selected pour dfinir llment que vous souhaiteriez dfinir
par dfaut au rendu de linput :
echo $this->Form->input('heure_fermeture', array(
'type' => 'time',
'selected' => '13:30:00'
));
Note : La cl selected pour les inputs de type date et datetime peuvent aussi tre des timestamps UNIX.
$options[empty] Est dfini true, pour forcer linput rester vide.
Quand pass une list select (liste de selection), ceci crera une option vide avec une valeur vide dans la
liste droulante. Si vous voulez une valeur vide avec un texte affich ou juste une option vide, passer une
chane pour vider :
echo $this->Form->input('field', array(
'options' => array(1, 2, 3, 4, 5),
'empty' => '(choisissez)'
));
Sortie:
.. code-block:: html
420
<div class="input">
<label for="UserField">Field</label>
<select name="data[User][field]" id="UserField">
<option value="">(choisissez)</option>
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
<option value="3">4</option>
<option value="4">5</option>
</select>
</div>
Note : Si vous avez besoin de dfinir la valeur par dfaut dun champ password vide, utilisez value=>
(deux fois simple cote) la place.
Une liste de paire de cl-valeur peut tre fournie pour un champ de type date ou datetime :
echo $this->Form->dateTime('Contact.date', 'DMY', '12',
array(
'empty' => array(
'day' => 'DAY', 'month' => 'MONTH', 'year' => 'YEAR',
'hour' => 'HOUR', 'minute' => 'MINUTE', 'meridian' => false
)
)
);
Affiche :
<select name="data[Contact][date][day]" id="ContactDateDay">
<option value="">DAY</option>
<option value="01">1</option>
// ...
<option value="31">31</option>
</select> - <select name="data[Contact][date][month]" id="ContactDateMonth">
<option value="">MONTH</option>
<option value="01">January</option>
// ...
<option value="12">December</option>
</select> - <select name="data[Contact][date][year]" id="ContactDateYear">
<option value="">YEAR</option>
<option value="2036">2036</option>
// ...
<option value="1996">1996</option>
</select> <select name="data[Contact][date][hour]" id="ContactDateHour">
<option value="">HOUR</option>
<option value="01">1</option>
// ...
<option value="12">12</option>
</select>:<select name="data[Contact][date][min]" id="ContactDateMin">
<option value="">MINUTE</option>
<option value="00">00</option>
// ...
<option value="59">59</option>
Usage Gnral
421
$options[hiddenField] Pour certain types d input (checkboxes, radios) un input cach est
cr ainsi la cl dans $this->request->data existera mme sans valeur spcifie :
<input type="hidden" name="data[Post][Published]" id="PostPublished_" value="0" />
<input type="checkbox" name="data[Post][Published]" value="1" id="PostPublished" />
Retournera :
<input type="checkbox" name="data[Post][Published]" value="1" id="PostPublished" />
Si vous voulez crer de multiples blocs dentrs regroups ensemble dans un formulaire, vous devriez
utiliser ce paramtre sur tous les inputs except le premier. Si le input cach est en place diffrents
endroits cest seulement le dernier groupe de valeur dinput qui sera sauvegard.
Dans cet exemple , seules les couleurs tertiaires seront passes, et les couleurs primaires seront rcrite :
<h2>Couleurs Primaires</h2>
<input type="hidden" name="data[Color][Color]" id="Couleurs_" value="0" />
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursRouges" />
<label for="CouleursRouges">Rouge</label>
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursBleus" />
<label for="CouleursBleus">Bleu</label>
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursJaunes" />
<label for="CouleursJaunes">Jaune</label>
<h2>Couleurs Tertiaires</h2>
<input type="hidden" name="data[Color][Color]" id="Couleurs_" value="0" />
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursVertes" />
<label for="CouleursVertes">Vert</label>
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursPourpres" />
<label for="CouleursPourpres">Pourpre</label>
<input type="checkbox" name="data[Addon][Addon][]" value="5" id="CouleursOranges" />
<label for="CouleursOranges">Orange</label>
En dsactivant le champ cach hiddenField dans le second groupe dinput empchera ce behavior.
Vous pouvez dfinir une valeur diffrente pour le champ cach autre que 0 comme N :
echo $this->Form->checkbox('published', array(
'value' => 'Y',
'hiddenField' => 'N',
));
422
$options[dateFormat] Utilis pour spcifier le format des inputs select (menu de slection)
pour un jeu dinput en relation avec le temps. Les valeurs valides comprennent nimporte quelle combinaison de D, M et Y or null. Les input seront placs dans lordre dfinit par loption dateFormat.
$options[minYear], $options[maxYear] Utilis en combinaison avec un input
date/datetime. Dfinit les valeurs minimales et/ou maximales de fin montres dans le champ select years.
$options[orderYear] Utilis en combinaison avec un input date/datetime. Dfinit lordre dans
lequel la valeur de lanne sera dlivr. Les valeurs valides sont asc, desc. La valeur par dfaut est
desc.
$options[interval] Cette option spcifie lcart de minutes entre chaque option dans la select
box minute :
echo $this->Form->input('Model.time', array(
'type' => 'time',
'interval' => 15
));
Crera 4 options dans la select box minute. Une toute les 15 minutes.
$options[round] Peut tre dfini up ou down pour forcer larrondi dans quelque soit la direction. Par dfaut null qui arrondit la moiti suprieure selon interval.
Introduit dans la version 2.4.
lments de Formulaire-Mthodes spcifiques Tous les elements sont crs dans un form pour le model
User comme dans les exemples ci-dessous. Pour cette raison, le code HTML gnr contiendra des attributs
qui font rfrence au model User Ex : name=data[User][username], id=UserUsername
FormHelper::label(string $fieldName, string $text, array $options)
Cre un lment label. $fieldName est utilis pour gnrer le Dom id. Si $text nest pas dfini,
$fieldName sera utilis pour dfinir le texte du label :
echo $this->Form->label('User.name');
echo $this->Form->label('User.name', 'Your username');
Affichera :
<label for="UserName">Name</label>
<label for="UserName">Your username</label>
$options peut soit tre un tableau dattributs HTML, ou une chane qui sera utilise comme nom
de classe :
echo $this->Form->label('User.name', null, array('id' => 'user-label'));
echo $this->Form->label('User.name', 'Your username', 'highlight');
Affichera :
<label for="UserName" id="user-label">Name</label>
<label for="UserName" class="highlight">Your username</label>
423
Affichera :
<input name="data[User][username]" type="text" class="users" id="UserUsername" />
Affichera :
<input name="data[User][password]" value="" id="UserPassword" type="password">
Affichera :
<input name="data[User][id]" id="UserId" type="hidden">
Si le form est dit (qui est le tableau $this->request->data va contenir les informations
sauvegardes pour le model User), la valeur correspondant au champ id sera automatiquement
ajoute au HTML gnr. Exemple pour data[User][id] = 10 :
<input name="data[User][id]" id="UserId" type="hidden" value="10" />
Modifi dans la version 2.0 : Les champs cachs nenlvent plus la classe attribute. Cela signifie que
si il y a des erreurs de validation sur les champs cachs, le nom de classe error-field sera appliqu.
FormHelper::textarea(string $fieldName, array $options)
Cre un champ input textarea (zone de texte).
echo $this->Form->textarea('notes');
Affichera :
<textarea name="data[User][notes]" id="UserNotes"></textarea>
Si le form est dit (ainsi, le tableau $this->request->data va contenir les informations sauvegardes pour le model User), la valeur correspondant au champs notes sera automatiquement
ajoute au HTML gnr. Exemple :
<textarea name="data[User][notes]" id="UserNotes">
Ce texte va tre dit.
</textarea>
Note : Le type dinput textarea permet lattribut $options dchapper escape lequel
dtermine si oui ou non le contenu du textarea doit tre chapp. Par dfaut true.
424
Options
En plus de Options Communes, textarea() supporte quelques options spcifiques :
$options[rows], $options[cols] Ces deux cls spcifient le nombre de lignes et
de colonnes :
echo $this->Form->textarea('textarea', array('rows' => '5', 'cols' => '5'));
Affichera :
<textarea name="data[Form][textarea]" cols="5" rows="5" id="FormTextarea">
</textarea>
Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />
Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />
Affichera :
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />
Usage Gnral
425
Affichera :
<input
<input
<label
<input
<label
Si pour quelque raisons vous ne voulez pas du input cach, dfinissez $attributes[value]
une valeur slectionne ou le boolen false
Modifi dans la version 2.1 : Loption dattribut $attributes[disabled] a t ajoute dans
CakePHP 2.1.
FormHelper::select(string $fieldName, array $options, array $attributes)
Cre un menu de slection, rempli des lments compris dans $options, avec loption spcifie
par $attributes[value] sera montr comme slectionn par dfaut. Dfinir false la cl
empty dans la variable $attributes pour empcher loption empty par dfaut :
$options = array('H' => 'Homme', 'F' => 'Femme');
echo $this->Form->select('genre', $options)
Affichera :
<select name="data[User][genre]" id="UserGenre">
<option value=""></option>
<option value="H">Homme</option>
<option value="F">Femme</option>
</select>
Linput de type select permet un attribut $option spcial appele escape qui accepte un
boolen et dtermine si il faut que lentit HTML encode le contenu des options slectionnes. Par
dfaut true :
$options = array('H' => 'Homme', 'F' => 'Femme');
echo $this->Form->select('genre', $options, array('escape' => false));
Affichera :
<select name="data[User][field]" id="UserField">
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
<option value="3">4</option>
426
<option value="4">5</option>
</select>
Les options peuvent aussi tre fournies comme des paires cl-valeur :
echo $this->Form->select('field', $options, array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2',
'Value 3' => 'Label 3'
));
Affichera :
<select name="data[User][field]" id="UserField">
<option value="Value 1">Label 1</option>
<option value="Value 2">Label 2</option>
<option value="Value 3">Label 3</option>
</select>
Si vous souhaitez gnrer un select avec des groupes optionnels, passez les donnes dans un format
hirarchique. Ceci fonctionnera avec les checkboxes multiples et les boutons radios galement, mais
au lieu des groupes optionnels enveloppez les lments dans des fieldsets :
$options = array(
'Group 1' => array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
),
'Group 2' => array(
'Value 3' => 'Label 3'
)
);
echo $this->Form->select('field', $options);
Affichera :
<select name="data[User][field]" id="UserField">
<optgroup label="Group 1">
<option value="Value 1">Label 1</option>
<option value="Value 2">Label 2</option>
</optgroup>
<optgroup label="Group 2">
<option value="Value 3">Label 3</option>
</optgroup>
</select>
$attributes[multiple] Si multiple a t dfini true pour un input select, celui ci autorisera les slections multiples :
echo $this->Form->select('Model.field', $options, array('multiple' => true));
Vous pouvez galement dfinir checkbox multiple pour afficher une liste de check boxes relis :
$options = array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
);
Usage Gnral
427
Affichera :
Output :
<div class="input select">
<label for="ModelField">Field</label>
<input name="data[Model][field]" value="" id="ModelField"
type="hidden">
<div class="checkbox">
<input name="data[Model][field][]" disabled="disabled"
value="Value 1" id="ModelField1" type="checkbox">
<label for="ModelField1">Label 1</label>
</div>
<div class="checkbox">
<input name="data[Model][field][]" value="Value 2"
id="ModelField2" type="checkbox">
<label for="ModelField2">Label 2</label>
</div>
</div>
Modifi dans la version 2.3 : Le support pour les tableaux dans $attributes[disabled] a
t ajoute dans 2.3.
FormHelper::file(string $fieldName, array $options)
Pour ajouter un champ upload un formulaire, vous devez vous assurer que le enctype du formulaire
est dfinit a multipart/form-data, donc commenons avec une fonction create comme ci-dessous :
428
Ensuite ajoutons lune ou lautre des deux lignes dans le fichier de vue de votre formulaire :
echo $this->Form->input('Document.submittedfile', array(
'between' => '<br />',
'type' => 'file'
));
// OU
echo $this->Form->file('Document.submittedfile');
En raisons des limitations du code HTML lui mme, il nest pas possible de placer des valeurs par
dfauts dans les champs inputs de type file. A chacune des fois ou le formulaire sera affich, la valeur
sera vide.
Lors de la soumission, le champ file fournit un tableau tendu de donnes au script recevant les
donnes de formulaire.
Pour lexemple ci-dessus, les valeurs dans le tableau de donnes soumis devraient tre organises
comme la suite, si CakePHP t install sur un server Windows .tmp_name aura un chemin
diffrent dans un environnement Unix :
$this->request->data['Document']['submittedfile'] = array(
'name' => conference_schedule.pdf,
'type' => application/pdf,
'tmp_name' => C:/WINDOWS/TEMP/php1EE.tmp,
'error' => 0,
'size' => 41737,
);
Ce tableau est gnr par PHP lui-mme, pour plus de dtails sur la faon dont PHP gre les donnes
passes a travers les champs files. lire la section file uploads du manuel de PHP 3 .
Validation des Uploads Ci dessous lexemple dune mthode de validation dfinit dans votre model pour
valider si un fichier t uploader avec succs :
public function isUploadedFile($params) {
$val = array_shift($params);
if ((isset($val['error']) && $val['error'] == 0) ||
(!empty( $val['tmp_name']) && $val['tmp_name'] != 'none')
) {
return is_uploaded_file($val['tmp_name']);
}
return false;
}
3. http ://php.net/features.file-upload
Usage Gnral
429
Affichera :
<form enctype="multipart/form-data" method="post" action="/users/add">
<input name="data[User][avatar]" value="" id="UserAvatar" type="file">
Affichera :
<div class="submit"><input value="Submit" type="submit"></div>
Vous pouvez aussi passer une URL relative ou absolue vers une image pour le paramtre caption au
lieu dun caption text :
echo $this->Form->submit('ok.png');
Affichera :
<div class="submit"><input type="image" src="/img/ok.png"></div>
$this->Form->button('Un bouton');
$this->Form->button('Un autre Bouton', array('type' => 'button'));
$this->Form->button('Initialise le Formulaire', array('type' => 'reset'));
$this->Form->button('Soumettre le Formulaire', array('type' => 'submit'));
Affichera :
430
<button
<button
<button
<button
type="submit">Un bouton</button>
type="button">Un autre Bouton</button>
type="reset">Initialise le Formulaire</button>
type="submit">Soumettre le Formulaire</button>
Le input de type button supporte loption escape qui accepte un boolen et dtermine si oui ou
non lentit HTML encode le $title du bouton. Par dfaut false :
echo $this->Form->button('Submit Form', array('type' => 'submit', 'escape' => true));
Usage Gnral
431
Affichera :
<select
<option
<option
<option
<option
<option
<option
<option
<option
name="data[User][purchased][annee]" id="UserPurchasedYear">
value=""></option>
value="2009">2009</option>
value="2008">2008</option>
value="2007">2007</option>
value="2006">2006</option>
value="2005">2005</option>
value="2004">2004</option>
value="2003">2003</option>
<option value="2002">2002</option>
<option value="2001">2001</option>
<option value="2000">2000</option>
</select>
Affichera :
<select name="data[User][mob][month]" id="UserMobMonth">
<option value=""></option>
<option value="01">January</option>
<option value="02">February</option>
<option value="03">March</option>
<option value="04">April</option>
<option value="05">May</option>
<option value="06">June</option>
<option value="07">July</option>
<option value="08">August</option>
<option value="09">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
Vous pouvez passer votre propre tableau des mois utiliser en paramtrant lattribut monthNames,
ou avoir les mois affichs comme des nombres en passant false. (Note : les mois par dfaut sont
internationaliss et peuvent tre traduits en utilisant la localisation) :
echo $this->Form->month('mob', array('monthNames' => false));
432
echo $this->Form->day('created');
Affichera :
<select name="data[User][created][day]" id="UserCreatedDay">
<option value=""></option>
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
...
<option value="31">31</option>
</select>
433
$this->Form->inputDefaults(array(
'label' => false,
'div' => false,
'class' => 'fancy'
)
);
Tous les champs crs partir ce point de retour vont hriter des options dclares dans inputDefaults. Vous
pouvez surcharger les options par dfaut en dclarant loption dans lappel input() :
434
Note : Le Helper html est disponible dans toutes les vues par dfaut. Si vous recevez une erreur vous
informant quil nest pas disponible, cest habituellement d a son nom qui a t oubli de la configuration
manuelle de la variable $helpers du controller.
Insertion dlments correctement formats La tche la plus importante que le Helper Html accomplit
est la cration dun balisage bien form. Nayez pas peur de lutiliser souvent - vous pouvez cacher les
vues dans cakePHP pour conomiser du temps CPU quand les vues sont rendues et dlivres. Cette section
couvrira les mthodes du Helper Html et comment les utiliser.
HtmlHelper::charset($charset=null)
Paramtres
$charset (string) Jeu de caractre dsir. Sil est null, la valeur de
App.encoding sera utilise.
Utilis pour crer une balise meta spcifiant le jeu de caractres du document. UTF-8 par dfaut.
Exemple dutilisation :
echo $this->Html->charset();
Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Sinon :
Usage Gnral
435
echo $this->Html->charset('ISO-8859-1');
Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
Affichera :
<link rel="stylesheet" type="text/css" href="/css/forms.css" />
Le premier paramtre peut tre un tableau pour inclure des fichiers multiples.
echo $this->Html->css(array('forms', 'tables', 'menu'));
Affichera :
<link rel="stylesheet" type="text/css" href="/css/forms.css" />
<link rel="stylesheet" type="text/css" href="/css/tables.css" />
<link rel="stylesheet" type="text/css" href="/css/menu.css" />
Vous pouvez inclure un fichier CSS depuis un plugin charg en utilisant syntaxe de plugin. Pour
inclure app/Plugin/DebugKit/webroot/css/toolbar.css, vous pouvez utiliser ce qui
suit :
echo $this->Html->css('DebugKit.toolbar.css');
Si vous voulez inclure un fichier CSS qui partage un nom avec un plugin charg vous pouvez faire ce qui suit. Par exemple vous avez un plugin Blog, et souhaitez inclure galement
app/webroot/css/Blog.common.css :
.. versionchanged:: 2.4
Cette mthode peut aussi tre utilise pour ajouter les balises de mots cls et les descriptions. Exemple :
<?php
echo $this->Html->meta(
'keywords',
'enter any meta keyword here'
Usage Gnral
437
);
?>
// Sortie
<meta name="keywords" content="enter any meta keyword here" />
<?php
echo $this->Html->meta(
'description',
'enter any meta description here'
);
?>
// Sortie
<meta name="description" content="enter any meta description here" />
Si vous voulez ajouter une balise personnalise alors le premier paramtre devra tre un tableau. Pour
ressortir une balise de robots noindex, utilisez le code suivant :
echo $this->Html->meta(array('name' => 'robots', 'content' => 'noindex'));
Modifi dans la version 2.1 : La valeur par dfaut de doctype est HTML5 avec la version 2.1.
HtmlHelper::style(array $data, boolean $oneline = true)
Paramtres
$data (array) Un ensemble de cl => valeurs avec des proprits CSS.
438
Affichera
background:#633; border-bottom:1px solid #000; padding:10px;
Affichera :
<img src="/img/cake_logo.png" alt="CakePHP" />
Pour crer un lien dimage, spcifiez le lien de destination en utilisant loption url dans
$htmlAttributes.
echo $this->Html->image("recipes/6.jpg", array(
"alt" => "Brownies",
'url' => array('controller' => 'recipes', 'action' => 'view', 6)
));
Affichera :
<a href="/recipes/view/6">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Si vous crez des images dans des mails, ou voulez des chemins absolus pour les images,
vous pouvez utiliser loption fullBase :
echo $this->Html->image("logo.png", array('fullBase' => true));
Affichera :
<img src="http://example.com/img/logo.jpg" alt="" />
Vous pouvez inclure des fichiers images depuis un plugin charg en utilisant la syntaxe
de plugin. Pour inclure app/Plugin/DebugKit/webroot/img/icon.png, vous
pouvez faire cela :
echo $this->Html->image('DebugKit.icon.png');
Usage Gnral
439
Si vous voulez inclure un fichier image qui partage un nom avec un plugin charg vous pouvez faire ce qui suit. Par exemple si vous avez in plugin Blog, et voulez inclure galement
app/webroot/js/Blog.icon.png :
echo $this->Html->image('Blog.icon.png', array('plugin' => false));
Affichera :
<a href="/pages/home" class="button" target="_blank">Enter</a>
Affichera :
<a href="http://www.yourdomain.com/dashboards/index">Dashboard</a>
Affichera :
440
Affichera :
<a href="/images/view/1?height=400&width=500">View image</a>
Quand il y a utilisation de paramtres nomms, utilisez la syntaxe en tableau et incluez les noms
pour TOUS les paramtres dans lURL. En utilisant la syntaxe en chane pour les paramtres (par ex
recipes/view/6/comments :false va rsulter ce que les caractres seront chapps du HTML et le
lien ne fonctionnera pas comme souhait.
<?php
echo $this->Html->link(
$this->Html->image("recipes/6.jpg", array("alt" => "Brownies")),
array(
'controller' => 'recipes',
'action' => 'view',
'id' => 6,
'comments' => false
)
);
Affichera :
<a href="/recipes/view/id:6/comments:false">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Les caractres spciaux HTML de $title seront convertis en entits HTML. Pour dsactiver cette
conversion, dfinissez loption escape false dans le tableau $options :
<?php
echo $this->Html->link(
$this->Html->image("recipes/6.jpg", array("alt" => "Brownies")),
"recipes/view/6",
array('escape' => false)
);
Affichera :
<a href="/recipes/view/6">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Dfinir escape false va aussi dsactiver lchappement des attributs du lien. Puisque depuis 2.4,
vous pouvez utiliser loption escapeTitle pour juste dsactiver lchappement du titre et pas des
attributs.
Usage Gnral
441
<?php
echo $this->Html->link(
$this->Html->image('recipes/6.jpg', array('alt' => 'Brownies')),
'recipes/view/6',
array('escapeTitle' => false, 'title' => 'hi "howdy"')
);
Affichera :
<a href="/recipes/view/6" title="hi "howdy"">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
442
'video.mp4',
array(
'src' => 'video.ogg',
'type' => "video/ogg; codecs='theora, vorbis'"
)
),
array('autoplay')
); ?>
// Sortie
<video autoplay="autoplay">
<source src="/files/video.mp4" type="video/mp4"/>
<source src="/files/video.ogg" type="video/ogg;
codecs='theora, vorbis'"/>
</video>
< ?php echo $this->Html->tag(span, Bonjour le Monde, array(class => welcome)) ; ?>
// Affichera <span class=welcome>Bonjour le Monde</span>
// Pas de texte spcifi. < ?php echo $this->Html->tag(span, null, array(class => welcome)) ; ?>
// Affichera <span class=welcome>
Note :
Le texte nest pas chapp par dfaut mais vous pouvez utiliser
$htmlOptions[escape] = true pour chapper votre texte. Ceci remplace un quatrime paramtre boolean $escape = false qui tait prsent dans les prcdentes versions.
HtmlHelper::div(string $class, string $text, array $options)
Paramtres
$class (string) Le nom de classe de la div.
$text (string) Le contenu de la div.
$options (array) Un tableau dattributs attributs html.
Utilis pour les sections de balisage envelopps dans des div. Le premier paramtre spcifie une
classe CSS, et le second est utilis pour fournir le texte envelopper par les balises div. Si le dernier
paramtre t dfini true, $text sera affich en HTML-chapp.
Si aucun texte nest spcifi, seulement une balise div douverture est retourne. :
Usage Gnral
443
<?php
echo $this->Html->div('error', 'Entrez votre numro de carte bleue S.V.P');
?>
// Affichera
<div class="error">Entrez votre numro de carte bleue S.V.P</div>
Affichera :
<script type="text/javascript" href="/js/scripts.js"></script>
Vous pouvez lier des fichiers avec des chemins absolus tant quils ne se trouvent pas dans
app/webroot/js :
444
echo $this->Html->script('/autrerep/fichier_script');
Affichera :
<script type="text/javascript" href="http://code.jquery.com/jquery.min.js"></script>
Le premier paramtre peut tre un tableau pour inclure des fichiers multiples.
echo $this->Html->script(array('jquery', 'wysiwyg', 'scripts'));
Affichera :
<script type="text/javascript" href="/js/jquery.js"></script>
<script type="text/javascript" href="/js/wysiwyg.js"></script>
<script type="text/javascript" href="/js/scripts.js"></script>
Vous pouvez insrer dans la balise script un bloc spcifique en utilisant loption block.
echo $this->Html->script('wysiwyg', array('block' => 'scriptBottom'));
Dans votre layout, vous pouvez ressortir toutes les balises script ajoutes dans scriptBottom :
echo $this->fetch('scriptBottom');
Vous pouvez inclure des fichiers de script depuis un plugin en utilisant la syntaxe syntaxe de plugin.
Pour inclure app/Plugin/DebugKit/webroot/js/toolbar.js vous devriez faire cela :
echo $this->Html->script('DebugKit.toolbar.js');
Si vous voulez inclure un fichier de script qui partage un nom de fichier avec un plugin charg
vous pouvez faire cela. Par exemple si vous avez Un plugin Blog, et voulez inclure galement
app/webroot/js/Blog.plugins.js, vous devriez :
echo $this->Html->script('Blog.plugins.js', array('plugin' => false));
Modifi dans la version 2.1 : Loption block a t ajout. Le support de la syntaxe syntaxe de plugin
a t ajout.
HtmlHelper::scriptBlock($code, $options = array())
Paramtres
$code (string) Le code placer dans la balise script.
$options (array) Un tableau dattributs attributs html.
Gnre un bloc de code contenant des options $options[inline] dfinies de $code
mettre false pour voir le bloc de script apparatre dans le bloc de script de
la vue. Dautres options dfinies seront ajoutes comme attributs dans les balises de
script. $this->Html->scriptBlock(stuff, array(defer => true)); crera
une balise script avec lattribut defer="defer".
HtmlHelper::scriptStart($options = array())
Paramtres
Usage Gnral
445
HtmlHelper::nestedList(array $list, array $options = array(), array $itemOptions = array(), string $tag = ul)
Paramtres
$list (array) Ensemble dlments lister.
$options (array) Attributs HTML supplmentaires des balises de listes (ol/ul) ou
si ul/ol utilise cela comme une balise.
$itemOptions (array) Attributs additionnels des balises de listes item(LI).
$tag (string) Type de balise liste utiliser (ol/ul).
Fabrique une liste imbrique (UL/OL) dans un tableau associatif :
$list = array(
'Languages' => array(
'English' => array(
'American',
'Canadian',
'British',
),
'Spanish',
'German',
)
);
echo $this->Html->nestedList($list);
Sortie :
// Affichera (sans les espaces blancs)
<ul>
<li>Languages
<ul>
<li>English
<ul>
<li>American</li>
<li>Canadian</li>
<li>British</li>
</ul>
446
</li>
<li>Spanish</li>
<li>German</li>
</ul>
</li>
</ul>
// Affichera
<tr>
<th>Date</th>
<th>Title</th>
<th>Active</th>
</tr>
echo $this->Html->tableHeaders(
array('Date','Title','Active'),
array('class' => 'status'),
array('class' => 'product_table')
);
Sortie :
<tr class="status">
<th class="product_table">Date</th>
<th class="product_table">Title</th>
<th class="product_table">Active</th>
</tr>
Modifi dans la version 2.2 : tableHeaders() accepte maintenant les attributs par cellule, regardez ci-dessous.
Depuis 2.2 vous pouvez dfinir des attributs par colonne, ceux-ci sont utiliss la place de ceux par
dfaut dans $thOptions :
echo $this->Html->tableHeaders(array(
'id',
array('Name' => array('class' => 'highlight')),
array('Date' => array('class' => 'sortable'))
));
Sortie :
Usage Gnral
447
<tr>
<th>id</th>
<th class="highlight">Name</th>
<th class="sortable">Date</th>
</tr>
Sortie :
<tr><td>Jul 7th, 2007</td><td>Best Brownies</td><td>Yes</td></tr>
<tr><td>Jun 21st, 2007</td><td>Smart Cookies</td><td>Yes</td></tr>
<tr><td>Aug 1st, 2006</td><td>Anti-Java Cake</td><td>No</td></tr>
echo $this->Html->tableCells(array(
array('Jul 7th, 2007', array('Best Brownies', array('class' => 'highlight')) , 'Ye
array('Jun 21st, 2007', 'Smart Cookies', 'Yes'),
array('Aug 1st, 2006', 'Anti-Java Cake', array('No', array('id' => 'special'))),
));
// Sortie
<tr><td>Jul 7th, 2007</td><td class="highlight">Best Brownies</td><td>Yes</td></tr>
<tr><td>Jun 21st, 2007</td><td>Smart Cookies</td><td>Yes</td></tr>
<tr><td>Aug 1st, 2006</td><td>Anti-Java Cake</td><td id="special">No</td></tr>
echo $this->Html->tableCells(
array(
array('Red', 'Apple'),
array('Orange', 'Orange'),
array('Yellow', 'Banana'),
),
array('class' => 'darker')
);
448
Output :
<tr class="darker"><td>Red</td><td>Apple</td></tr>
<tr><td>Orange</td><td>Orange</td></tr>
<tr class="darker"><td>Yellow</td><td>Banana</td></tr>
Usage Gnral
449
Output :
<form action="http://example.com" method="post" class="myform">
Vous
pouvez
alors
charger
ces
balises
$this->Html->loadConfig(html5_tags);.
dfinis
en
appelant
450
Loption $startText peut aussi accepter un tableau. Cela donne plus de contrle travers le premier lien gnr :
echo $this->Html->getCrumbs(' > ', array(
'text' => $this->Html->image('home.png'),
'url' => array('controller' => 'pages', 'action' => 'display', 'home'),
'escape' => false
));
Une cl qui nest pas text ou url sera passe link() comme paramtre $options.
Modifi dans la version 2.1 : Le paramtre $startText accepte maintenant un tableau.
HtmlHelper::addCrumb(string $name, string $link = null, mixed $options = null)
Maintenant, dans votre vue vous allez devoir ajouter ce qui suit pour dmarrer le fil dAriane sur
chacune de vos pages.
$this->Html->addCrumb('Users', '/users');
$this->Html->addCrumb('Add User', array('controller' => 'users', 'action' => 'add'));
Ceci ajoutera la sortie Home > Users > Add User dans votre layout o le fil dAriane a t ajout.
HtmlHelper::getCrumbList(array $options = array(), mixed $startText)
Paramtres
$options (array) Un tableau d attributs HTML pour les elements contenant
<ul>. Peut aussi contenir les options separator, firstClass, lastClass et escape.
$startText (string|array) Le texte ou lelment qui prcde ul.
Retourne le fil dAriane comme une liste (x)html.
Cette mthode utilise HtmlHelper::tag() pour gnrer la liste et ces lments. Fonctionne de
la mme manire que getCrumbs(), il utilise toutes les options que chacun des fils a ajout. Vous
pouvez utiliser le paramtre $startText pour fournir le premier lien de fil. Cest utile quand vous
voulez inclure un lien racine. Cette option fonctionne de la mme faon que loption $startText
pour getCrumbs().
Modifi dans la version 2.1 : Le paramtre $startText a t ajout.
Modifi dans la version 2.3 : Les options separator, firstClass et lastClass ont t ajoutes.
Modifi dans la version 2.5 : Loption escape a t ajoute.
JSHelper
class JsHelper(View $view, array $settings = array())
Avertissement : JsHelper est actuellement dprci et compltement retir de 3.x. Nous recommandons
dutiliser du JavaScript classique et de directement intragir avec les librairies si possible.
Depuis le dbut le support de CakePHP pour Javascript a t orient vers Prototype/Scriptaculous (librairie
JavaScript). Tandis que nous continuons de penser quil sagit dexcellentes bibliothques Javascript, il a
t demand la communaut de supporter dautres librairies. Plutt que denlever Prototype en faveur
dune autre librairie JavaScript. Nous avons cr un adaptateur fonctionnant sur le principe dun Helper
et avons inclu 3 des librairies les plus demandes. Prototype/scriptaculous, Mootools/Mootools-more, et
Usage Gnral
451
jQuery/jQueryUI. Bien que lAPI nest pas aussi vaste que le Helper Ajax, nous pensons que la solution
base sur ladaptateur permet une solution plus extensible offrant aux dveloppeurs la puissance et la flexibilit dont ils ont besoin pour rpondre leurs besoins spcifiques.
Les moteurs Javascript forment lpine dorsale du nouveau Helper Js. Un moteur JavaScript traduit un
lment Javascript abstrait dans un code JavaScript concret spcifique la librairie en cours dutilisation.
De plus ils crent un systme extensible utiliser pour les autres.
Utilisation dun moteur Javascript spcifique Avant tout, tlchargez votre librairie JavaScript prfre
et placez la dans app/webroot/js.
Puis, vous devez inclure la librairie dans votre page. Pour linclure dans toutes les pages, ajoutez cette ligne
dans la section <head> de app/View/Layouts/default.ctp :
echo $this->Html->script('jquery'); // Inclut la librairie Jquery
Remplacez jquery par le nom de votre fichier de librairie (.js sera ajout au nom).
Par dfaut les scripts sont mis en cache, et vous devez explicitement imprimer le cache. Pour faire cela la
fin de chacune des pages, incluez cette ligne juste avant la balise de fin de </body>
echo $this->Js->writeBuffer(); // crit les scripts en mmoire cache
Attention : Vous devez inclure la librairie dans votre page et afficher le cache pour que le helper fonctionne.
La selection du moteur Javascript est dclare quand vous incluez le helper dans votre controller
public $helpers = array('Js' => array('Jquery'));
La partie ci-dessus utilise le moteur Jquery dans les instances du Helper Js dans vos vues. Si vous ne dclarez
pas un moteur spcifique, le moteur Jquery sera utilis par dfaut. Comme il est mentionn ci-dessus, il y a
trois moteurs implments dans le noyau, mais nous encourageons la communaut tendre la compatibilit
des librairies.
Utilisation de jQuery avec dautres librairies La librairie jQuery, et virtuellement tous ses plugins sont
limits au sein de lespace jQuery. Comme rgle gnrale, les objets globaux sont stocks dans lespace JQuery, ainsi vous ne devriez pas avoir de clash entre Jquery et dautre librairies (comme Prototype,
MooTools, ou YUI).
Ceci dit, il y a une mise en garde : Par dfaut, jQuery utilise $ comme raccourci de jQuery
Pour redfinir le raccourci $, utilisez la variable jQueryObject :
$this->Js->JqueryEngine->jQueryObject = '$j';
echo $this->Html->scriptBlock(
'var $j = jQuery.noConflict();',
array('inline' => false)
);
// Demande jQuery de se placer dans un mode noconflict
452
Utilisation du Helper Js dans des helpers personnaliss Dclarez le Helper Js dans le tableau
$helpers de votre Helper personnalis :
public $helpers = array('Js');
Note : Il nest pas possible de dclarer le moteur JavaScript dans un Helper personnalis. Ceci naurait
aucun effet.
Si vous tes prt utiliser un moteur JavaScript autre que celui par dfaut, fates le paramtrage du Helper
dans votre controller comme ceci :
public $helpers = array(
'Js' => array('Prototype'),
'CustomHelper'
);
Est un exemple de chanage de mthode. Le chanage de mthode nest pas possible dans PHP4 et lexemple
ci-dessus devrait tre crit comme :
Usage Gnral
453
$this->Js->get('#foo');
$this->Js->event('click', $eventCode);
Options communes Dans le but de simplifier le dveloppement et comme les librairies JavaScript peuvent
changer, un ensemble courant doptions est pris en charge par JsHelper, ces options courantes seront
mappes en dehors des options spcifiques de la librairies en interne. Si vous ne prvoyez pas la commutation
des librairies, chaque librairie supporte toutes les fonctions de callback natives et les options.
Enveloppement de Callback Par dfaut, toutes les options de callback sont enveloppes dans une
fonction anonyme avec les bons arguments. Vous pouvez dsactiver ce comportement en fournissant
wrapCallbacks = false dans votre tableau doptions.
Travailler avec des scripts bufferiss Un inconvnient la prcdente implmentation des fonctionnalits de type dAJAX tait la dispersion des balises de script partout dans le document , et limpossibilit
de bufferiser les scripts ajouts par les lments dans la mise en page. Le nouveau Helper Js si il est utilis
correctement vite ces deux questions. Il est recommand de placer $this->Js->writeBuffer()
la fin du fichier layout au dessus la balise </body>. Ceci permettra tous les scripts gnrs dans les
lments du layout dtre ressortis (output) un endroit. Il doit tre not que les scripts bufferiss sont grs
sparment des scripts de fichiers inclus.
JsHelper::writeBuffer($options = array())
crit tous le codes Javascript gnrs jusquici dans un bloc de code ou les met en mmoire cache dans un
fichier et retourne un script li.
Options
inline - Dfini true pour avoir la sortie des scripts dans un bloc de script inline. si cache est aussi
true, une balise de lien de script sera gnre (par dfaut true)
cache - Dfini true pour avoir les scripts dans un fichier de la mmoire cache et sy reli (false par
dfaut)
clear - Dfini false pour viter au fichier de cache dtre effac (true par dfaut)
onDomReady - enveloppe les scripts en mmoire cache dans un evnement domready (par dfaut true)
safe - si un block inline est gnr il sera envelopp dans < ![CDATA[ ... ]]> (true par dfaut)
La cration dun fichier de cache avec writeBuffer() ncessite que webroot/js soit accessible en
criture et permette au navigateur de placer dans le cache les ressources de script gnr pour la page.
JsHelper::buffer($content)
Ajoute $content au buffer de script interne.
JsHelper::getBuffer($clear = true)
Rcupre le contenu du buffer courant. Passe false pour ne pas effacer le buffer en mme temps.
Bufferiser des mthodes qui ne sont normalement pas bufferise
Quelques mthodes dans le Helper sont bufferise par dfaut. Le moteur bufferise les mthodes suivantes
par dfaut :
event
sortable
454
drag
drop
slider
De plus vous pouvez forcer une autre mthode du Helper Js utiliser la mise en mmoire cache. En ajoutant
un boolen la fin des arguments vous pouvez forcer dautres mthodes daller en mmoire cache. Par
exemple la mthode each() qui nest normalement pas bufferise :
$this->Js->each('alert("sapristi!");', true);
Ce qui est ci-dessus va forcer la mthode each() utiliser le buffer. En revanche si vous souhaitez quune
mthode bufferise ne bufferise plus, vous pouvez passer un false comme le dernier argument :
$this->Js->event('click', 'alert("sapristi!");', false);
Ceci forcera la fonction event qui est normalement mis en mmoire cache retourner son rsultat.
Dautres Mthodes Les moteurs Javascript du noyau fournissent les mmes fonctionnalits dfinies a
travers les autres librairies, il y a aussi un sous-ensemble doptions communes qui sont traduites dans les
options spcifiques des librairies. Tout cela pour fournir au dveloppeurs finaux une Api unifie autant que
possible. La liste suivante de mthodes est supporte par tous les moteurs inclus dans le noyau CakePHP.
Chaque fois que vous voyez une liste spare pour les Options et les Event Options Les deux ensembles de paramtres sont fournis dans le tableau $options pour la mthode.
JsHelper::object($data, $options = array())
Srialise $data vers JSON. Cette mthode est un proxy pour json_encode() avec quelques
fonctionnalits supplmentaires ajoute avec le paramtre $options.
Options :
prefix - Chane ajoute en dbut des donnes retournes.
postfix - Chane ajoute aux donne retourne.
Exemple dutilisation :
$json = $this->Js->object($data);
JsHelper::sortable($options = array())
Sortable gnre un extrait de code pour fabriquer un ensemble dlments (souvent une liste) drag and
drop triable.
Les options normalises sont :
Options
containment - Conteneur de laction de dplacement.
handle - Selecteur de llment. Seul cet lment commencera laction de tri.
revert - Sil faut ou pas utiliser un effet pour dplacer llment triable dans sa position finale.
opacity - Opacit de lespace rserv.
distance - Distance a laquelle llment triable doit tre dragg avant que le tri nopre.
Event Options
start - vnement lanc quand le tri commence.
sort - vnement lanc quand le tri est en cours.
complete - vnement lanc quand le tri est termin.
Usage Gnral
455
Dautres options sont supportes par chacune des librairies Javascript, et vous pouvez obtenir dans
leurs documentation respective des informations plus dtailles sur les options et les paramtres.
Exemple dutilisation :
$this->Js->get('#ma-liste');
$this->Js->sortable(array(
'distance' => 5,
'containment' => 'parent',
'start' => 'onStart',
'complete' => 'onStop',
'sort' => 'onSort',
'wrapCallbacks' => false
));
En imaginant que vous tiez en train dutiliser le moteur Jquery, vous devriez avoir le code suivant
dans votre block Javascript gnr.
$("#myList").sortable({
containment:"parent",
distance:5,
sort:onSort,
start:onStart,
stop:onStop
});
456
JsHelper::get($selector)
Dfinit la slection interne dans un slecteur CSS. La slection active est utilise dans les oprations
ultrieures jusqu ce quune nouvelle soit faite.
$this->Js->get('#element');
Le JsHelper fait maintenant rfrence toutes les mthodes de la slection bases sur #element.
Pour changer la slection active appelez get() nouveau avec un nouvel lment.
JsHelper::set(mixed $one, mixed $two = null)
Passe des variables dans JavaScript. Vous permet de dfinir des variables qui seront retournes quand
le buffer est extrait avec Helper Js::getBuffer() ou Helper Js::writeBuffer().
La variable Javascript utilise pour retourner les variables peut tre controlle avec Helper
Js::$setVariable.
JsHelper::drag($options = array())
Rend un lment draggable.
Options
handle - selecteur de llment.
snapGrid - La grille de pixel qui dclenche les mouvements, un tableau(x, y)
container - Llment qui agit comme un rectangle de selection pour llment
draggable.
Options dvnements
start - vnement lanc quand le drag dmarre.
drag - vnement lanc chaque tape du drag.
stop - vnement lanc quand le drag sarrte. (souris relche)
Exemple dutilisation :
$this->Js->get('#element');
$this->Js->drag(array(
'container' => '#content',
'start' => 'onStart',
'drag' => 'onDrag',
'stop' => 'onStop',
'snapGrid' => array(10, 10),
'wrapCallbacks' => false
));
Si vous utilisiez le moteur Jquery le code suivant devrait tre ajout au buffer
$("#element").draggable({
containment:"#content",
drag:onDrag,
grid:[10,10],
start:onStart,
stop:onStop
});
JsHelper::drop($options = array())
Fabrique un lment accepte des lments dragguables et agit comme dropzone pour les lments
draggs.
Options
Usage Gnral
457
Si vous utilisiez le moteur jQuery le code suivant devrait tre ajout au buffer.
$("#element").droppable({
accept:".items",
drop:onDrop,
out:onExit,
over:onHover
});
Note : Les lments Droppables dans Mootools fonctionnent diffremment des autres librairies. Les
Droppables sont implments comme une extension de Drag. Donc pour faire une selection get() pour
llment droppable. Vous devez aussi fournir une rgle de selecteur llment draggable. De plus,
les droppables Mootools hritent de toutes les option de Drag.
JsHelper::slider($options = array())
Cr un morceau de code Javascript qui converti un lment dans un morceau de code slider ui. Voir les
implmentations des diffrentes librairies pour des utilisations supplmentaires et les fonctionnalits.
Options
handle - l id de llment utilis dans le sliding.
direction - La direction du slider soit vertical ou horizontal.
min - La valeur minimale pour le slider.
max - La valeur maximale pour le slider.
step - Le nombre dtapes que le curseur aura.
value - Le dcalage initial du slider.
Events
change - Lanc quand la valeur du slider est actualis.
complete - Lanc quand un utilisateur arrte de slider le gestionnaire.
Exemple dutilisation :
$this->Js->get('#element');
$this->Js->slider(array(
'complete' => 'onComplete',
'change' => 'onChange',
458
'min' => 0,
'max' => 10,
'value' => 2,
'direction' => 'vertical',
'wrapCallbacks' => false
));
Si vous utilisiez le moteur jQuery le code suivant devrait tre ajout au buffer.
$("#element").slider({
change:onChange,
max:10,
min:0,
orientation:"vertical",
stop:onComplete,
value:2
});
Usage Gnral
459
$this->Js->get('#some-link');
$this->Js->event('click', $this->Js->alert('saperlipopette!'));
Si vous employiez la librairie jQuery vous devriez avoir le code Javascript suivant ajout au buffer.
Notez que lvnement du navigateur par dfaut nest pas annul :
$('#some-link').bind('click', function (event) {
alert('hey you!');
});
JsHelper::domReady($callback)
Cr lvnement spcial DOM ready. JsHelper::writeBuffer() enveloppe automatiquement les scripts bufferiss dans une mthode domReady.
JsHelper::each($callback)
Cr un morceau de code qui effectue une itration sur les lments slectionns, et insre
$callback.
Exemple :
$this->Js->get('div.message');
$this->Js->each('$(this).css({color: "red"});');
JsHelper::alert($message)
Cr un extrait de code JavaScript contenant un alert(). Par dfaut, alert ne bufferise pas, et
retourne le morceau de script suivant.
$alert = $this->Js->alert('Zogotunga!');
JsHelper::confirm($message)
Cr un bout de code contenant confirm(). Par dfaut, confirm ne bufferise pas, et retourne le
morceau de script suivant.
$alert = $this->Js->confirm('Vraiment certain?');
460
JsHelper::prompt($message, $default)
Cr un bout de code Javascript contenant prompt(). Par dfaut, prompt ne bufferise pas, et
retourne le morceau de code suivant.
$prompt = $this->Js->prompt('C'est quoi ta couleur prfre?', 'bleu');
Va cr un bouton submit et un vnement onclick attach. Lvnement click sera bufferis par
dfaut.
echo $this->Js->submit('Save', array(
'update' => '#content',
'div' => false,
'type' => 'json',
'async' => false
));
Usage Gnral
461
echo $this->Js->link(
'Page 2',
array('page' => 2),
array('update' => '#content')
);
JsHelper::serializeForm($options = array())
Srialise le formulaire attach au $selector. Passe true pour $isForm si la selection courante est
un lment de formulaire. Converti le formulaire ou llment de formulaire attach la slection
courante dans un objet chane/json (dpendant de limplmentation de la librairie) pour utilisation
avec les oprations XHR.
Options
isForm - est ce que la slection courante est un formulaire ou un input ? (par dfaut false)
inline - est ce que le traitement du rendu sera utilis dans un autre traitement JS ? (par dfaut
false)
En dfinissant inline == false vous permet de retirer la bordure ;. Ceci est utile quand vous avez besoin
de srialiser un lment de formulaire comme faisant parti dune autre opration Javascript ou utilisez
la mthode de srialisation dans un Objet littral.
JsHelper::redirect($url)
Redirige la page vers $url en utilisant window.location.
JsHelper::value($value)
Convertit une variable native PHP dun type dans une reprsentation JSON quivalente. chappe une
valeur de chane dans une chane compatible JSON. Les caractre UTF-8 seront chapps .
La Pagination AJAX Bien mieux quavec la pagination AJAX de la 1.2, vous pouvez utiliser le Helper
JS pour grer les liens de pagination AJAX au lieu de liens HTML.
Fabriquer les liens AJAX Avant de pouvoir crer les liens ajax vous devez inclure la librairie Javascript
qui correspond ladaptateur que vous utilisez avec le Helper JS. Par dfaut le Helper Js utilise
jQuery. Donc dans votre layout incluez jQuery (ou la librairie que vous utilisez). Assurez vous galement
dinclure RequestHandlerComponent dans votre behavior. Ajoutez ce qui suit dans votre controller :
public $components = array('RequestHandler');
public $helpers = array('Js');
462
Ce qui suit relie la librairie Javascript que vous voulez utiliser. Pour cet exemple nous utiliserons jQuery :
echo $this->Html->script('jquery');
De mme quavec la 1.2 vous devez dire au PaginatorHelper que vous voulez faire des liens Javascript
avancs au lieu des plain HTML. Pour faire cela utilisez options() :
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true
));
La classe PaginatorHelper sait maintenant quil faut crer des liens Javascript tendus, et que ces liens
devront mettre jour le contenu #content de llment. Bien sr cet lment doit exister, et la plupart
du temps vous voulez envelopper le $content_for_layout par une div qui correspond lid utilise
dans loption update. Vous devez galement dfinir evalScripts true si vous utilisez des adaptateurs
Mootools ou Prototype, sans evalScripts ces librairies seront incapables de relier les requtes entrent
elles. Loption indicator nest pas supporte par le Helper JS et sera ignore.
Vous venez donc de crer tous les liens demands pour le fonctionnement de la pagination. Puisque le
Helper Js bufferise automatiquement tous les contenus de scripts pour rduire les balises <script>
dans vos codes sources vous devez appeler la restitution du buffer. A la fin de votre fichier de vue. Vrifiez
linclusion de :
echo $this->Js->writeBuffer();
Si vous oubliez cela vous ne pourrez pas enchaner les liens de pagination AJAX. Quand vous crivez le
buffer, cela lefface galement , et vous navez donc pas vous inquiter de doublon de code Javascript.
Ajouter des effets et des transitions Depuis que indicator nest plus support, vous devez ajouter les
effets dindicator vous mme. :
<!DOCTYPE html>
<html>
<head>
<?php echo $this->Html->script('jquery'); ?>
//more stuff here.
</head>
<body>
<div id="content">
<?php echo $this->fetch('content'); ?>
</div>
<?php
echo $this->Html->image(
'indicator.gif',
array('id' => 'busy-indicator')
);
?>
</body>
</html>
Usage Gnral
463
Rappelez vous de placer le fichier indicator.gif dans le rpertoire app/webroot/img. Vous devriez voir une
situation o indicator.gif saffiche immdiatement au chargement de la page. Vous avez besoin dinsrer cet
indicateur #busy-indicator { display:none; } dans votre fichier CSS principal.
Avec le layout ci-dessus, nous avons inclus un indicateur, qui affichera une animation occup que nous
aurons montrer et cacher avec le Helper Js. Pour faire cela, nous avons besoin de mettre jour notre
fonction options() :
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true,
'before' => $this->Js->get('#busy-indicator')->effect(
'fadeIn',
array('buffer' => false)
),
'complete' => $this->Js->get('#busy-indicator')->effect(
'fadeOut',
array('buffer' => false)
),
));
Ceci montrera/cachera llment indicateur occup avant et aprs que le contenu de la balise #content
soit mis jour. Bien que indicator ait t enlev, les nouvelles fonctionnalits du JsHelper permettent
la cration de plus de contrle et deffets plus complexes.
NumberHelper
class NumberHelper(View $view, array $settings = array())
Le helper Number contient des mthodes pratiques qui permettent laffichage des nombres dans divers
formats communs dans vos vues. Ces mthodes contiennent des moyens pour formater les devises, pourcentages, taille des donnes, le format des nombres avec prcisions et aussi de vous donner davantage de
souplesse en matire de formatage des nombres.
Modifi dans la version 2.1 : NumberHelper a t remani dans une classe CakeNumber pour permettre
une utilisation plus facile a lextrieur de la couche View. Dans une vue, ces mthodes sont accessibles
via la classe NumberHelper et vous pouvez lappeler comme vous pourriez appeler une mthode de helper
normale : $this->Number->method($args);.
Toutes ces fonctions retournent le nombre format ; Elles naffichent pas automatiqement la sortie dans la
vue.
NumberHelper::currency(float $number, string $currency = USD, array $options = array())
Paramtres
$number (float) La valeur convertir.
$currency (string) Le format de monnaie connu utiliser.
$options (array) Options, voir ci-dessous.
Cette mthode est utilise pour afficher un nombre dans des formats de monnaie courante
(EUR,GBP,USD). Lutilisation dans une vue ressemble ceci :
464
Le premier paramtre $number, doit tre un nombre virgule qui reprsente le montant dargent
que vous dsirez. Le second paramtre est utilis pour choisir un schma de formatage de monnaie
courante :
$currency 1234.56, format par le type courant
EUR
C1.234,56
GBP
1,234.56
USD
$1,234.56
Le troisime paramtre est un tableau doptions pour dfinir la sortie. Les options suivantes sont
disponibles :
Option
Description
before
Le symbole de la monnaie placer avant les nombres ex : $
after
Le symbole de la monnaie placer aprs les nombres dcimaux ex : c. Dfinit le
boolen false pour utiliser aucun symbole dcimal ex : 0.35 => $0.35.
zero
Le texte utiliser pour des valeurs zro, peut tre une chane de caractres ou un
nombre. ex : 0, Free !
places
Nombre de dcimales utiliser. ex : 2
thouSparateur des milliers ex : ,
sands
decimals Symbole de Sparateur des dcimales. ex : .
negative
Symbole pour les nombres ngatifs. Si gal (), le nombre sera entour avec ( et )
escape
La sortie doit-elle tre chappe de htmlentity ? Par dfaut dfini true
wholeSym- La chane de caractres utiliser pour les tous nombres. ex : dollars
bol
wholePo- Soit before soit after pour placer le symbole entier
sition
fractionChane de caractres utiliser pour les nombres en fraction. ex : cents
Symbol
fractionSoit before soit after pour placer le symbole de fraction
Position
fractionFraction exponent de cette monnaie spcifique. Par dfaut 2.
Exponent
Si une valeur $currency non reconnue est fournie, elle est prfixe par un nombre format en USD.
Par exemple :
// Appel avec NumberHelper
echo $this->Number->currency('1234.56', 'FOO');
// Sortie
FOO 1,234.56
// Appel avec CakeNumber
Usage Gnral
465
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency('1234.56', 'FOO');
NumberHelper::defaultCurrency(string $currency)
Paramtres
$currency
(string)
Dfini
une
monnaie
connu
pour
CakeNumber::currency().
Setter/getter pour la monnaie par dfaut. Ceci retire la ncessit de toujours passer la monnaie
CakeNumber::currency() et change toutes les sorties de monnaie en dfinissant les autres par
dfaut.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.
NumberHelper::addFormat(string $formatName, array $options)
Paramtres
$formatName (string) Le nom du format utiliser dans le futur.
$options (array) Le tableau doptions pour ce format. Utilise les mmes cls
$options comme CakeNumber::currency().
before Symbole de monnaie avant le nombre. False pour aucun.
after Symbole de monnaie aprs le nombre. False pour aucun.
zero Le texte utiliser pour les valeurs zro, peut tre une chane de caractres
ou un nombre. ex : 0, Free !
places Nombre de dcimal utiliser. ex. 2.
thousands Sparateur des milliers. ex : ,.
decimals Symbole de Sparateur des dcimales. ex : ..
negative Symbole pour les nombres ngatifs. Si gal (), le nombre sera entour
avec ( et ).
escape La sortie doit-elle tre chappe de htmlentity ? Par dfaut true.
wholeSymbol Chane de caractres utiliser pour tous les nombres. ex : dollars.
wholePosition Soit before soit after pour placer le symbole complet.
fractionSymbol Chane de caractres utiliser pour les nombres fraction. ex :
cents.
fractionPosition Soit before soit after pour placer le symbole de fraction.
Ajoute le format de monnaie au helper Number. Facilite la rutilisation des formats de monnaie.
Vous pouvez maintenant utiliser BRL de manire courte quand vous formatez les montants de monnaie :
// appel par NumberHelper
echo $this->Number->currency($value, 'BRL');
// appel par CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency($value, 'BRL');
466
Les formats ajouts sont fusionns avec les formats par dfaut suivants :
array(
'wholeSymbol'
'wholePosition'
'fractionSymbol'
'fractionPosition'
'zero'
'places'
'thousands'
'decimals'
'negative'
'escape'
'fractionExponent'
)
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
'',
'before',
false,
'after',
0,
2,
',',
'.',
'()',
true,
2
Usage Gnral
467
Introduit dans la version 2.4 : Largument $options avec loption multiply a t ajout.
NumberHelper::fromReadableSize(string $size, $default)
Paramtres
$size (string) La valeur formate lisible par un humain.
Cette mthode enlve le format dun nombre partir dune taille de byte lisible par un humain en un
nombre entier de bytes.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3
NumberHelper::toReadableSize(string $dataSize)
Paramtres
$data_size (string) Le nombre de bytes pour le rendre lisible.
Cette mthode formate les tailles de donnes dans des formes lisibles pour lhomme. Elle fournit une
manire raccourcie de convertir les en KB, MB, GB, et TB. La taille est affiche avec un niveau de
prcision deux chiffres, selon la taille de donnes fournie (ex : les tailles suprieurs sont exprimes
dans des termes plus larges) :
// appel avec NumberHelper
echo $this->Number->toReadableSize(0); // 0 Bytes
echo $this->Number->toReadableSize(1024); // 1 KB
echo $this->Number->toReadableSize(1321205.76); // 1.26 MB
echo $this->Number->toReadableSize(5368709120); // 5.00 GB
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::toReadableSize(0); // 0 Bytes
echo CakeNumber::toReadableSize(1024); // 1 KB
echo CakeNumber::toReadableSize(1321205.76); // 1.26 MB
echo CakeNumber::toReadableSize(5368709120); // 5.00 GB
468
Le paramtre $number est le nombre que vous souhaitez formater pour la sortie. Avec aucun $options
fourni, le nombre 1236.334 sortirait comme ceci : 1,236. Notez que la prcision par dfaut est daucun
chiffre aprs la virgule.
Le paramtre $options est l o rside la relle magie de cette mthode.
Si vous passez un entier alors celui-ci devient le montant de prcision pour la fonction.
Si vous passez un tableau associatif, vous pouvez utiliser les cls suivantes :
places (integer) : le montant de prcision dsir.
before (string) : mettre avant le nombre sortir.
escape (boolean) : si vous voulez la valeur avant dtre chappe.
decimals (string) : utilis pour dlimiter les places des dcimales dans le nombre.
thousands (string) : utilis pour marquer les milliers, millions, . . .
Exemple :
// appel avec NumberHelper
echo $this->Number->format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
));
// sortie ' 123,456.79'
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
));
// sortie ' 123,456.79'
Le paramtre $number est le nombre que vous planifiez sur le formatage de sortie. Avec aucun $options fourni, le nombre 1236.334 sortirait 1,236. Notez que la valeur de prcision par dfaut est aucune
dcimale.
Le paramtre $options prend les mmes cls que CakeNumber::format() lui-mme :
places (integer) : le montant de precision souhait.
before (string) : mettre avant le nombre sorti.
after (string) : mettre aprs le nombre sorti.
decimals (string) : utilis pour dlimiter les places de la dcimal dans un nombre.
Usage Gnral
469
thousands (string) : utilis pour marquer les places des centaines, millions, . . .
Exemple :
// appel avec NumberHelper
echo $this->Number->formatDelta('123456.7890', array(
'places' => 2,
'decimals' => '.',
'thousands' => ','
));
// sortie '+123,456.79'
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::formatDelta('123456.7890', array(
'places' => 2,
'decimals' => '.',
'thousands' => ','
));
// sortie '+123,456.79'
Paginator
class PaginatorHelper(View $view, array $settings = array())
Le Helper Paginator est utilis pour prsenter des contrles de pagination comme les numros de pages et
les liens suivant/prcdent. Il travaille en tandem avec PaginatorComponent.
Voir aussi Pagination pour des informations sur la faon de crer des jeux de donnes pagins et faire des
requtes pagines.
Cration de liens tris
PaginatorHelper::sort($key, $title = null, $options = array())
Paramtres
$key (string) Le nom de la cl du jeu denregistrement qui doit tre trie.
$title (string) Titre du lien. Si $title est null $key sera utilise pour le titre et sera
gnre par inflexion.
$options (array) Options pour le tri des liens.
Gnre un lien de tri. Dfinit le nom ou les paramtres de la chane de recherche pour le tri et la direction.
Les liens par dfaut fourniront un tri ascendant. Aprs le premier clique, les liens gnrs avec sort()
greront le changement de direction automatiquement. Les liens de tri par dfaut ascendant. Si le jeu de
rsultat est tri en ascendant avec la cl spcifie le liens retourn triera en dcroissant.
Les cls accepte pour $options :
escape Si vous voulez que le contenu soit encod en HTML, true par dfaut.
model Le model utiliser, par dfaut PaginatorHelper : :defaultModel().
direction La direction par dfaut utiliser quand ce lien nest pas actif.
470
lock Verrouiller la direction. Va seulement utiliser la direction par dfaut, par dfaut false.
Introduit dans la version 2.5 : Vous pouvez maintenant dfinir loption lock true afin de verrouiller la
direction du tri dans la direction spcifie.
En considrant que vous paginez des posts, quils sont sur la page un :
echo $this->Paginator->sort('user_id');
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">User Id</a>
Vous pouvez utiliser le paramtre title pour crer des textes personnaliss pour votre lien :
echo $this->Paginator->sort('user_id', 'User account');
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">User account</a>
Si vous utilisez de lHTML comme des images dans vos liens rappelez-vous de paramtrer lchappement :
echo $this->Paginator->sort(
'user_id',
'<em>User account</em>',
array('escape' => false)
);
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">
<em>User account</em>
</a>
Loption de direction peut tre utilise pour paramtrer la direction par dfaut pour un lien. Une fois quun
lien est activ, il changera automatiquement de direction comme habituellement :
echo $this->Paginator->sort('user_id', null, array('direction' => 'desc'));
Sortie
<a href="/posts/index/page:1/sort:user_id/direction:desc/">User Id</a>
Loption lock peut tre utilise pour verrouiller le tri dans la direction spcifie :
echo $this->Paginator->sort('user_id', null, array('direction' => 'asc', 'lock' => true));
Usage Gnral
471
last Si vous voulez que les derniers liens soit gnrs, dfinit un entier pour dfinir le nombre de
dernier liens gnrer. Par dfaut false. Suit la mme logique que loption first. il y a mthode
last() utiliser sparment si vous le voulez.
ellipsis Contenu des suspensions, par dfaut ...
La balise currentTag utiliser pour le nombre de page courant, par dfaut null. Cela vous autorise
gnrer par exemple le Bootstrap Twitter comme les liens avec le nombre de page courant enroul dans
les balises a ou span supplmentaires.
Bien que cette mthode permette beaucoup de customisation pour ses sorties. Elle est aussi prte pour tre
appele sans aucun paramtres.
echo $this->Paginator->numbers();
En utilisant les options first et last vous pouvez crer des liens pour le dbut et la fin du jeu de page. Le code
suivant pourrait crer un jeu de liens de page qui inclut les liens des deux premiers et deux derniers rsultats
de pages :
echo $this->Paginator->numbers(array('first' => 2, 'last' => 2));
Modifi dans la version 2.1 : Loption currentClass t ajoute dans la version 2.1.
Introduit dans la version 2.3 : Loption currentTag a t ajoute dans 2.3.
Cration de liens de sauts En plus de gnrer des liens qui vont directement sur des numros de pages spcifiques, vous voudrez souvent des liens qui amnent vers le lien prcdent ou suivant, premire et dernire
pages dans le jeu de donnes pagines.
PaginatorHelper::prev($title = << Previous, $options = array(), $disabledTitle = null,
$disabledOptions = array())
472
Paramtres
$title (string) Titre du lien.
$options (mixed) Options pour le lien de pagination.
$disabledTitle (string) Titre quand le lien est dsactiv, comme quand vous tes
dj sur la premire page, sans page prcdente o aller.
$disabledOptions (mixed) Options pour le lien de pagination dsactiv.
Gnre un lien vers la page prcdente dans un jeu denregistrements pagins.
$options et $disabledOptions supportent les cls suivantes :
tag La balise enveloppante que vous voulez utiliser, span par dfaut.
escape Si vous voulez que le contenu soit encod en HTML, par dfaut true.
model Le model utiliser, par dfaut PaginatorHelper : :defaultModel()
Un simple exemple serait :
echo $this->Paginator->prev(
' << ' . __('previous'),
array(),
null,
array('class' => 'prev disabled')
);
Si vous tiez actuellement sur la secondes pages des posts (articles), vous obtenez le rsultat suivant :
<span class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
<< previous
</a>
</span>
Sortie :
<li class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
</li>
Output :
<a class="prev" rel="prev"
href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
Usage Gnral
473
Ceci cr un simple lien pour la premire page. Ne retournera rien si vous tes sur la premire page.
Vous pouvez aussi utiliser un nombre entier pour indiquer combien de premier liens pagins vous
voulez gnrer :
echo $this->Paginator->first(3);
Ceci crera des liens pour les 3 premires pages, une fois la troisime page ou plus atteinte. Avant
cela rien ne sera retourn.
Les paramtres doption acceptent ce qui suit :
tag La balise tag enveloppante que vous voulez utiliser, par dfaut span.
after Contenu insrer aprs le lien/tag.
model Le model utiliser par dfaut PaginatorHelper : :defaultModel().
separator Contenu entre les liens gnrs, par dfaut | .
ellipsis Contenu pour les suspensions, par dfaut ....
PaginatorHelper::last($last = last >>, $options = array())
Cette mthode fonctionne trs bien comme la mthode first(). Elle a quelques diffrences cependant. Elle ne gnrera pas de lien si vous tes sur la dernire page avec la valeur chane $last. Pour
une valeur entire de $last aucun lien ne sera gnr une fois que lutilisateur sera dans la zone des
dernires pages.
PaginatorHelper::current(string $model = null)
rcupre la page actuelle pour le jeu denregistrement du model donn :
// Ou l'URL est: http://example.com/comments/view/page:3
echo $this->Paginator->current('Comment');
// la sortie est 3
separator Le sparateur entre la page actuelle et le nombre de pages. Par dfaut of . Ceci est utilis
en conjonction avec format =pages qui la valeur par dfaut de format :
echo $this->Paginator->counter(array(
'separator' => ' sur un total de '
));
model
Le
nom
du
model
en
cours
de
pagination,
par
dfaut
PaginatorHelper::defaultModel(). Ceci est utilis en conjonction avec la chane personnalise de loption format.
Modification des options que le Helper Paginator utilise
PaginatorHelper::options($options = array())
Paramtres
$options (mixed) Options par dfaut pour les liens de pagination. Si une chane
est fournie - elle est utilise comme id de llment DOM actualiser.
Dfinit toutes les options pour le Helper Paginator Helper. Les options supportes sont :
url LURL de laction de pagination. url comporte quelques sous options telles que :
sort La cl qui dcrit la faon de trier les enregistrements.
Usage Gnral
475
Ce qui se trouve ci-dessus ajoutera en comme paramtre de route pour chacun des liens que le helper va
gnrer. Il crera galement des liens avec des tris, direction et valeurs de page spcifiques. Par dfaut
PaginatorHelper fusionnera cela dans tous les paramtres passs et nomms. Ainsi vous naurez pas le
faire dans chacun des fichiers de vue.
escape Dfinit si le champ titre des liens doit tre chapp HTML. Par dfaut true.
update Le selecteur CSS de llment actualiser avec le rsultat de lappel de pagination AJAX. Si
cela nest pas spcifi, des liens rguliers seront crs :
$this->Paginator->options(array('update' => '#content'));
Ceci est utile lors de lutilisation de la pagination AJAX La Pagination AJAX. Gardez lesprit que la
valeur actualise peut tre un selecteur CSS valide, mais il est souvent plus simple dutiliser un selecteur
id.
model
Le
nom
du
model
en
cours
de
pagination,
par
dfaut
PaginatorHelper::defaultModel().
Utilisation de paramtres GET pour la pagination Normalement la Pagination dans CakePHP utilise
Paramtres Nomms. Il y a des fois ou vous souhaiterez utilisez des paramtres GET la place. Alors que la
principale option de configuration pour cette fonctionnalit est dans PaginatorComponent, vous avez
des contrles supplmentaires dans les vues. Vous pouvez utiliser options() pour indiquer que vous voulez
la conversion dautres paramtres nomms :
$this->Paginator->options(array(
'convertKeys' => array('your', 'keys', 'here')
));
Configurer le Helper Paginator pour utiliser le Helper Javascript Par dfaut le Helper
Paginator utilise JsHelper pour effectuer les fonctionnalits AJAX. Toutefois, si vous ne voulez
pas cela et que vous voulez utiliser un Helper personnalis pour les liens AJAX, vous pouvez le faire en
changeant le tableau $helpers dans votre controller. Aprs avoir lanc paginate() fates ce qui suit :
// Dans l'action de votre controller.
$this->set('posts', $this->paginate());
$this->helpers['Paginator'] = array('ajax' => 'CustomJs');
476
Changera le Helper Paginator pour utiliser CustomJs pour les oprations AJAX. Vous pourriez
aussi dfinir la cl AJAX pour tre un Helper, tant que la classe implmente la mthode link() qui se
comporte comme HtmlHelper::link().
La Pagination dans les Vues Cest vous de dcider comment afficher les enregistrements lutilisateur,
mais la plupart des fois, ce sera fait lintrieur des tables HTML. Lexemple ci-dessous suppose une
prsentation tabulaire, mais le Helper Paginator disponible dans les vues Na pas toujours besoin dtre
limit en tant que tel.
Voir les dtails sur PaginatorHelper 5 dans l API. Comme mentionn prcdemment, le Helper Paginator
offre galement des fonctionnalits de tri qui peuvent tre facilement intgrs dans vos en-ttes de colonne
de table :
// app/View/Posts/index.ctp
<table>
<tr>
<th><?php echo $this->Paginator->sort('id', 'ID'); ?></th>
<th><?php echo $this->Paginator->sort('title', 'Title'); ?></th>
</tr>
<?php foreach ($data as $recipe): ?>
<tr>
<td><?php echo $recipe['Recipe']['id']; ?> </td>
<td><?php echo h($recipe['Recipe']['title']); ?> </td>
</tr>
<?php endforeach; ?>
</table>
Lingrdient final pour laffichage de la pagination dans les vues est laddition de pages de navigation, aussi
fournies par le Helper de Pagination :
// Montre les numros de page
echo $this->Paginator->numbers();
5. http ://api.cakephp.org/2.4/class-PaginatorHelper.html
Usage Gnral
477
Le texte de sortie de la mthode counter() peut galement tre personnalis en utilisant des marqueurs
spciaux :
echo $this->Paginator->counter(array(
'format' => 'Page {:page} of {:pages}, showing {:current} records out of
{:count} total, starting on record {:start}, ending on {:end}'
));
Dautres Mthodes
PaginatorHelper::link($title, $url = array(), $options = array())
Paramtres
$title (string) Titre du lien.
$url (mixed) Url de laction. Voir Router : :url().
$options (array) Options pour le lien. Voir options() pour la liste des cls.
Les cls acceptes pour $options :
update - L Id de llment DOM que vous souhaitez actualiser. Cr des liens prs pour AJAX.
escape Si vous voulez que le contenu soit encod comme une entit HTML, par dfaut true.
model Le model utiliser, par dfaut PaginatorHelper : :defaultModel().
Cr un lien ordinaire ou AJAX avec des paramtres de pagination :
echo $this->Paginator->link('Sort by title on page 5',
array('sort' => 'title', 'page' => 5, 'direction' => 'desc'));
pointant
vers
Paramtres
$options (array) Tableau doptions Pagination/URL. Comme utilis dans les
mthodes options() ou link().
$asArray (boolean) Retourne lURL comme dans un tableau, ou une chane URL.
Par dfaut false.
$model (string) Le model sur lequel paginer.
Par dfaut retourne une chane URL compltement pagine utiliser dans des contextes non-standard
(ex. JavaScript).
echo $this->Paginator->url(array('sort' => 'titre'), true);
PaginatorHelper::defaultModel()
Retourne le model par dfaut du jeu de pagination ou null si la pagination nest pas initialise.
PaginatorHelper::params(string $model = null)
Retourne les paramtres courants de la pagination du jeu de rsultat dun model donn :
478
debug($this->Paginator->params());
/*
Array
(
[page] => 2
[current] => 2
[count] => 43
[prevPage] => 1
[nextPage] => 3
[pageCount] => 3
[order] =>
[limit] => 20
[options] => Array
(
[page] => 2
[conditions] => Array
(
)
)
[paramType] => named
)
*/
479
Crer un flux RSS avec RssHelper Cet exemple suppose que vous ayez un Controller Posts et un Model
Post dj crs et que vous vouliez crer une vue alternative pour les flux RSS.
Crer une version xml/rss de posts/index est vraiment simple avec CakePHP. Aprs quelques tapes faciles,
vous pouvez tout simplement ajouter lextension .rss demande posts/index pour en faire votre URL
posts/index.rss. Avant daller plus loin en essayant dinitialiser et de lancer notre service Web, nous
avons besoin de faire un certain nombre de choses. Premirement, le parsing dextensions doit tre activ
dans app/config/routes.php :
Router::parseExtensions('rss');
Dans lappel ci-dessus, nous avons activ lextension .rss. Quand vous utilisez
Router::parseExtensions(), vous pouvez passer autant darguments ou dextensions que
vous le souhaitez. Cela activera le content-type de chaque extension utilise dans votre application.
Maintenant, quand ladresse posts/index.rss est demande, vous obtiendrez une version XML de
votre posts/index. Cependant, nous avons dabord besoin dditer le controller pour y ajouter le code
rss-spcifique.
Code du Controller Cest une bonne ide dajouter RequestHandler au tableau $components de votre
controller Posts. Cela permettra beaucoup dautomagie de se produire :
public $components = array('RequestHandler');
Notre vue utilise aussi TextHelper pour le formatage, ainsi il doit aussi tre ajout au controller :
public $helpers = array('Text');
Avant que nous puissions faire une version RSS de notre posts/index, nous avons besoin de mettre certaines
choses en ordre. Il pourrait tre tentant de mettre le canal des mtadonnes dans laction du controller et
de le passer votre vue en utilisant la mthode Controller::set(), mais ceci est inappropri. Cette
information pourrait galement aller dans la vue. Cela arrivera sans doute plus tard, mais pour linstant,
si vous avez un ensemble de logique diffrent entre les donnes utilises pour crer le flux RSS et les
donnes pour la page HTML, vous pouvez utiliser la mthode RequestHandler::isRss(), sinon
votre controller pourrait rester le mme :
// Modifie l'action du Controller Posts correspondant
// l'action qui dlivre le flux rss, laquelle est
// l'action index dans notre exemple
public function index() {
if ($this->RequestHandler->isRss() ) {
$posts = $this->Post->find(
'all',
array('limit' => 20, 'order' => 'Post.created DESC')
);
return $this->set(compact('posts'));
}
// ceci n'est pas une requte RSS
// donc on retourne les donnes utilises par l'interface du site web
$this->paginate['Post'] = array(
480
Maintenant que toutes ces variables de Vue sont dfinies, nous avons besoin de crer un layout rss.
Layout Un
layout
Rss
est
trs
simple,
app/View/Layouts/rss/default.ctp :
mettez
les
contenus
suivants
dans
if (!isset($documentData)) {
$documentData = array();
}
if (!isset($channelData)) {
$channelData = array();
}
if (!isset($channelData['title'])) {
$channelData['title'] = $this->fetch('title');
}
$channel = $this->Rss->channel(array(), $channelData, $this->fetch('content'));
echo $this->Rss->document($documentData, $channel);
Il ne ressemble pas plus mais grce la puissance du RssHelper il fait beaucoup pour amliorer le visuel
pour nous. Nous navons pas dfini $documentData ou $channelData dans le controller, cependant
dans CakePHP vos vues peuvent retourner les variables au layout. Ce qui est lendroit o notre tableau
$channelData va venir dfinir toutes les donnes meta pour notre flux.
Ensuite il y a le fichier de vue pour mes posts/index. Un peu comme le fichier de layout que nous avons cr,
nous avons besoin de crer un rpertoire View/Posts/rss/ et un nouveau index.ctp lintrieur de
ce rpertoire. Les contenus du fichier sont ci-dessous.
View Notre vue, localise dans app/View/Posts/rss/index.ctp, commence par dfinir les variables $documentData et $channelData pour le layout, celles-ci contiennent toutes les metadonnes
pour notre flux RSS. Cest fait en utilisant la mthode View::set() qui est analogue la mthode
View::set(). Ici nous passons les canaux de donnes en retour au layout :
$this->set('channelData', array(
'title' => __("Most Recent Posts"),
'link' => $this->Html->url('/', true),
'description' => __("Most recent posts."),
'language' => 'en-us'));
La seconde partie de la vue gnre les lments pour les enregistrements actuels du flux. Ceci est accompli en bouclant sur les donnes qui ont t passes la vue ($items) et en utilisant la mthode
RssHelper::item(). Lautre mthode que vous pouvez utiliser RssHelper::items() qui prend
un callback et un tableau des items pour le flux. (La mthode que jai vu utilise pour le callback a toujours
t appele transformRss(). Il y a un problme pour cette mthode, qui est quelle nutilise aucune des
Usage Gnral
481
classes de helper pour prparer vos donnes lintrieur de la mthode de callback parce que la porte
lintrieur de la mthode ninclut pas tout ce qui nest pas pass lintrieur, ainsi ne donne pas accs au
TimeHelper ou tout autre helper dont vous auriez besoin. RssHelper::item() transforme le tableau
associatif en un lment pour chaque pair de valeur de cl.
Note : Vous devrez modifier la variable $postLink comme il se doit pour votre application.
foreach ($posts as $post) {
$postTime = strtotime($post['Post']['created']);
$postLink = array(
'controller' => 'posts',
'action' => 'view',
'year' => date('Y', $postTime),
'month' => date('m', $postTime),
'day' => date('d', $postTime),
$post['Post']['slug']
);
// Retire & chappe tout HTML pour tre sr que le contenu va tre valid.
$bodyText = h(strip_tags($post['Post']['body']));
$bodyText = $this->Text->truncate($bodyText, 400, array(
'ending' => '...',
'exact' => true,
'html'
=> true,
));
echo
$this->Rss->item(array(), array(
'title' => $post['Post']['title'],
'link' => $postLink,
'guid' => array('url' => $postLink, 'isPermaLink' => 'true'),
'description' => $bodyText,
'pubDate' => $post['Post']['created']
));
}
Vous pouvez voir ci-dessus que nous pouvons utiliser la boucle pour prparer les donnes devant tre transformes en lments XML. Il est important de filtrer tout texte de caractres non brute en-dehors de la
description, spcialement si vous utilisez un diteur de texte riche pour le corps de votre blog. Dans le
code ci-dessus nous utilisons strip_tags() et h() pour retirer/chapper tout caractre spcial XML du
contenu, puisquils peuvent entraner des erreurs de validation. Une fois que nous avons dfini les donnes
pour le feed, nous pouvons ensuite utiliser la mthode RssHelper::item() pour crer le XML dans le
format RSS. Une fois que vous avez toutes ces configurations, vous pouvez tester votre feed RSS en allant
votre /posts/index.rss et que vous verrez votre nouveau feed. Il est toujours important que vous
validiez votre feed RSS avant de le mettre en live. Ceci peut tre fait en visitant les sites qui valident le XML
comme Le Validateur de Feed ou le site de w3c http ://validator.w3.org/feed/.
Note : Vous aurez besoin de dfinir la valeur de debug dans votre configuration du coeur 1 ou 0 pour
obtenir un flux valide, cause des diffrentes informations de debug ajoutes automatiquement sous des
paramtres de debug plus haut qui cassent la syntaxe XML ou les rgles de validation du flux.
482
483
SessionHelper
class SessionHelper(View $view, array $settings = array())
quivalent du Component Session, le Helper Session offre la majorit des fonctionnalits du component
et les rend disponible dans votre vue. Le Helper session est automatiquement ajout la vue, il nest pas
ncessaire de lajouter la variable tableau $helpers dans votre controller.
La grande diffrence entre le Component Session et le Helper Session est que ce dernier ne peut pas crire
dans la session.
Comme pour le Component Session, les donnes sont crites et lues en utilisant des structures de tableaux
avec la notation avec points, comme ci-dessous :
array('User' =>
array('username' => 'super@example.com')
);
tant donn ce tableau, le nud sera accessible par User.username, le point indiquant le tableau imbriqu. Cette notation est utilise pour toutes les mthodes du helper Session o une variable $key est
utilise.
SessionHelper::read(string $key)
Type retourn mixed
Lire partir de la Session. Retourne une chane de caractre ou un tableau dpendant des contenus de
la session.
SessionHelper::consume($name)
Type retourn mixed
Lit et supprime une valeur de Session. Cest utile quand vous voulez combiner la lecture et la suppression de valeurs en une seule opration.
SessionHelper::check(string $key)
Type retourn boolean
Vrifie si une cl est dans la Session. Retourne un bolen sur lexistence dun cl.
SessionHelper::error()
Type retourn string
Retourne la dernire erreur encourue dans une session.
SessionHelper::valid()
Type retourn boolean
Utilise pour vrifier si une session est valide dans une vue.
Affichage de notifications ou de messages flash
SessionHelper::flash(string $key = flash, array $params = array())
Obsolte depuis la version 2.7.0 : Vous devez utiliser Flash pour afficher les messages flash.
Comme expliqu dans Cration de messages de notification vous pouvez crer
des notifications uniques pour le feedback. Aprs avoir cr les messages avec
SessionComponent::setFlash(), vous voudrez les afficher. Une fois que le message
est affich, il sera retir et ne saffichera plus :
484
echo $this->Session->flash();
Comme pour la mthode du component, vous pouvez dfinir des proprits supplmentaires et personnaliser quel lment est utilis. Dans le controller, vous pouvez avoir du code comme :
// dans un controller
$this->Session->setFlash('Le user n'a pu tre supprim.');
Quand le message sort, vous pouvez choisir llment utilis pour afficher ce message :
// dans un layout.
echo $this->Session->flash('flash', array('element' => 'failure'));
Vous pouvez aussi passer des paramtres supplmentaires dans la mthode flash(), ce qui vous
permet de gnrer des messages personnaliss :
// Dans le controller
$this->Session->setFlash('Thanks for your payment %s');
// Dans le layout.
echo $this->Session->flash('flash', array(
'params' => array('name' => $user['User']['name'])
'element' => 'payment'
));
// View/Elements/payment.ctp
<div class="flash payment">
<?php printf($message, h($name)); ?>
</div>
TextHelper
class TextHelper(View $view, array $settings = array())
TextHelper possde des mthodes pour rendre le texte plus utilisable et sympa dans vos vues. Il aide activer
les liens, formater les URLs, crer des extraits de texte autour des mots ou des phrases choisies, mettant
en vidence des mots cls dans des blocs de texte et tronquer lgamment de longues tendues de texte.
Modifi dans la version 2.1 : Plusieurs des mthodes de TextHelper ont t dplaces dans la classe
String pour permettre une utilisation plus facile de la couche View. Dans une vue, ces mthodes sont
Usage Gnral
485
accessibles avec la classe TextHelper et vous pouvez lappeler comme vous appelleriez une mthode normale
de helper : $this->Text->method($args);.
TextHelper::autoLinkEmails(string $text, array $options=array())
Paramtres
$text (string) Le texte convertir.
$options (array) Un tableau d attributs HTML pour gnrer les liens.
Ajoute les liens aux adresses email bien formes dans $text, selon toute les options dfinies dans
$options (regardez HtmlHelper::link()).
$myText = 'Pour plus d'informations sur nos ptes et desserts fameux,
contactez info@example.com';
$linkedText = $this->Text->autoLinkEmails($myText);
Sortie :
Pour plus d'informations sur nos ptes et desserts fameux,
contactez <a href="mailto:info@example.com">info@example.com</a>
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement ces inputs. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoLinkUrls(string $text, array $options=array())
Paramtres
$text (string) Le texte convertir.
$options (array) Un tableau d attributs HTML pour la gnration de liens.
De mme que dans autoLinkEmails(), seule cette mthode cherche les chanes de caractre qui
commence par https, http, ftp, ou nntp et les liens de manire approprie.
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement son input. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoLink(string $text, array $options=array())
Paramtres
$text (string) Le texte lier automatiquement.
$htmlOptions (array) Un tableau d attributs HTML pour gnrer les liens.
Excute la fonctionnalit dans les deux autoLinkUrls() et autoLinkEmails() sur le $text
fourni. Tous les URLs et emails sont lis de manire approprie donne par $htmlOptions fourni.
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement son input. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoParagraph(string $text)
Paramtres
$text (string) Le texte convertir.
Ajoute <p> autour du texte o la double ligne retourne et <br> o une simple ligne retourne, sont
trouvs.
$myText = 'For more information
regarding our world-famous pastries and desserts.
contact info@example.com';
$formattedText = $this->Text->autoParagraph($myText);
486
Output :
<p>Pour plus d\'information<br />
selon nos clbres ptes et desserts.<p>
<p>contact info@example.com</p>
Sortie :
Highlights $needle in $haystack <span class="highlight">using</span>
the $options['format'] string specified or a default string.
TextHelper::stripLinks($text)
Enlve le $text fourni de tout lien HTML.
TextHelper::truncate(string $text, int $length=100, array $options)
Paramtres
$text (string) Le texte tronquer.
$length (int) La longueur en caractres pour laquelle le texte doit tre tronqu.
$options (array) Un tableau doptions utiliser.
Usage Gnral
487
Si $text est plus long que $length, cette mthode le tronque la longueur $length et ajoute un
prefix ellipsis, si dfini. Si exact est pass false, le truchement va se faire au premier
espace aprs le point o $length a dpass. Si html est pass true, les balises html seront
respectes et ne seront pas coupes.
$options est utilis pour passer tous les paramtres supplmentaires, et a les cls suivantes possibles par dfaut, celles-ci tant toutes optionnelles :
array(
'ellipsis' => '...',
'exact' => true,
'html' => false
)
Exemple :
// appel avec TextHelper
echo $this->Text->truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
Sortie :
The killer crept...
Modifi dans la version 2.3 : ending a t remplac par ellipsis. ending est toujours utilis dans
2.2.1.
TextHelper::tail(string $text, int $length=100, array $options)
Paramtres
$text (string) The text tronquer.
$length (int) La longueur en caractres pour laquelle le texte doit tre tronqu.
$options (array) Un tableau doptions utiliser.
Si $text est plus long que $length, cette mthode retire une sous-chane initiale avec la longueur
de la diffrence et ajoute un suffixe ellipsis, si il est dfini. Si exact est pass false,
le truchement va se faire au premier espace avant le moment o le truchement aurait t fait.
$options est utilis pour passer tous les paramtres supplmentaires, et a les cls possibles suivantes par dfaut, toutes sont optionnelles :
488
array(
'ellipsis' => '...',
'exact' => true
)
Sortie :
...a TV, a C# program that can divide by zero, death metal t-shirts
Usage Gnral
489
Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...
Sortie :
red, orange, yellow, green, blue, indigo et violet
TimeHelper
class TimeHelper(View $view, array $settings = array())
Le Helper Time vous permet, comme il lindique de gagner du temps. Il permet le traitement rapide des
informations se rapportant au temps. Le Helper Time a deux tches principales quil peut accomplir :
1. Il peut formater les chanes de temps.
2. Il peut tester le temps (mais ne peut pas le courber, dsol).
Modifi dans la version 2.1 : TimeHelper a t reconstruit dans la classe CakeTime pour faciliter lutilisation en-dehors de la couche View. Dans une vue, ces mthodes sont accessibles via la
classe TimeHelper et vous pouvez lappeler comme vous appelleriez une mthode normale de helper :
$this->Time->method($args);.
Utiliser le Helper Une utilisation courante de Time Helper est de compenser la date et le time pour
correspondre au time zone de lutilisateur. Utilisons un exemple de forum. Votre forum a plusieurs utilisateurs qui peuvent poster des messages depuis nimporte quelle partie du monde. Une faon facile de
grer le temps est de sauvegarder toutes les dates et les times GMT+0 or UTC. Dcommenter la ligne
date_default_timezone_set(UTC); dans app/Config/core.php pour sassurer que le
time zone de votre aplication est dfini GMT+0.
Ensuite, ajoutez un time zone votre table users et fates les modifications ncessaires pour permettre vos
utilisateurs de dfinir leur time zone. Maintenant que nous connaissons le time zone de lutilisateur connect,
nous pouvons corriger la date et le temps de nos posts en utilisant le Helper Time :
490
echo $this->Time->format(
'F jS, Y h:i A',
$post['Post']['created'],
null,
$user['User']['time_zone']
);
// Affichera August 22nd, 2011 11:53 PM pour un utilisateur dans GMT+0
// August 22nd, 2011 03:53 PM pour un utilisateur dans GMT-8
// et August 23rd, 2011 09:53 AM GMT+10
La plupart des mthodes du Helper Time contiennent un paramtre $timezone. Le paramtre $timezone
accepte une chane identifiante de timezone valide ou une instance de la classe DateTimeZone.
Formatage
TimeHelper::convert($serverTime, $timezone = NULL)
Type retourn integer
Convertit tant donn le time (dans le time zone du serveur) vers le time de lutilisateur, tant donn
son/sa sortie de GMT.
// appel via TimeHelper
echo $this->Time->convert(time(), 'Asia/Jakarta');
// 1321038036
// appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::convert(time(), new DateTimeZone('Asia/Jakarta'));
Usage Gnral
491
Modifi dans la version 2.2 : Le paramtre $timezone remplace $userOffset utilis dans 2.1 et
suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::format($date, $format = NULL, $default = false, $timezone = NULL)
Type retourn string
Va retourner une chane formate avec le format donn en utilisant les options de formatage de la
fonction PHP strftime() 6 :
// appel via TimeHelper
echo $this->Time->format('2011-08-22 11:53:00', '%B %e, %Y %H:%M %p');
// August 22nd, 2011 11:53 AM
echo $this->Time->format('%r', '+2 days');
// 2 days from now formatted as Sun, 13 Nov 2011 03:36:10 AM EET
// appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2011-08-22 11:53:00', '%B %e, %Y %H:%M %p');
echo CakeTime::format('+2 days', '%c');
Vous pouvez aussi fournir la date/time en premier argument. En faisant cela vous devrez utiliser le
format strftime compatible. Cette signature dappel vous permet de tirer parti du format de date
de la locale ce qui nest pas possible en utilisant le format de date() compatible :
// appel avec TimeHelper
echo $this->Time->format('2012-01-13', '%d-%m-%Y', 'invalid');
// appel avec CakeTime
6. http ://www.php.net/manual/en/function.strftime.php
492
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2011-08-22', '%d-%m-%Y');
Modifi dans la version 2.2 : Les paramtres $format et $date sont en ordre oppos par rapport ce qui se faisait dans 2.1 et suivants. Le paramtre $timezone remplace le paramtre
$userOffset utilis dans 2.1 et suivants. Le paramtre $default remplace le paramtre
$invalid utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $date accepte aussi maintenant un objet DateTime.
TimeHelper::fromString($dateString, $timezone = NULL)
Type retourn string
Prend une chane et utilise strtotime 7 pour la convertir en une date integer :
// Appel avec TimeHelper
echo $this->Time->fromString('Aug 22, 2011');
// 1313971200
echo $this->Time->fromString('+1 days');
// 1321074066 (+1 day from current date)
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::fromString('Aug 22, 2011');
echo CakeTime::fromString('+1 days');
Usage Gnral
493
494
Utilisez loption end pour dterminer le point de cutoff pour ne plus utiliser de mots ; par dfaut
+1 month :
// Appel avec TimeHelper
echo $this->Time->timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
// On Nov 10th, 2011 it would display: 2 months, 2 weeks, 6 days ago
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
Utilisez loption accuracy pour dterminer la prcision de la sortie. Vous pouvez utiliser ceci pour
limiter la sortie :
// Si $timestamp est il y a 1 month, 1 week, 5 days et 6 hours
echo CakeTime::timeAgoInWords($timestamp, array(
'accuracy' => array('month' => 'month'),
'end' => '1 year'
));
// Sort '1 month ago'
495
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
Introduit dans la version 2.4 : Les nouveaux paramtres doption relativeString (par dfaut
%s ago) et absoluteString (par dfaut on %s) pour permettre la personnalisation de la
chane de sortie rsultante sont maintenant disponibles.
TimeHelper::toRSS($dateString, $timezone = NULL)
Type retourn string
Va retourner une chane de date au format RSS Sat, 12 Jan 2008 00 :00 :00 -0500
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toUnix($dateString, $timezone = NULL)
Type retourn integer
Un enrouleur pour fromString.
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toServer($dateString, $timezone = NULL, $format = Y-m-d H :i :s)
Type retourn mixed
Introduit dans la version 2.2 : Retourne une date formate dans le timezone du serveur.
TimeHelper::timezone($timezone = NULL)
Type retourn DateTimeZone
Introduit dans la version 2.2 : Retourne un objet timezone partir dune chane de caractres ou de
lobjet timezone de lutilisateur. Si la fonction est appele sans paramtres, elle essaie dobtenir le
timezone de la variable de configuration Config.timezone.
496
wasWithinLast prend un intervalle de time qui est une chane au format 3 months et accepte un
intervalle de time en secondes, minutes, heures, jours, semaines, mois et annes (pluriels ou non). Si
un intervalle de time nest pas reconnu (par exemple, si il y a une faute de frappe) ensuite ce sera par
dfaut days.
Utiliser et configurer les Helpers Vous activez les helpers dans CakePHP, en faisant prendre conscience
un controller quils existent. Chaque controller a une proprit $helpers, qui liste les helpers disponibles
dans la vue. Pour activer un helper dans votre vue, ajoutez son nom au tableau $helpers du controller :
Usage Gnral
497
Lajout des helpers depuis les plugins utilise la syntaxe de plugin utilise partout ailleurs dans CakePHP :
class BakeriesController extends AppController {
public $helpers = array('Blog.Comment');
}
Vous pouvez aussi ajouter les helpers depuis une action, dans ce cas, ils seront uniquement accessibles pour
cette action et dans aucune autre action du controller. Ceci conomise de la puissance de calcul pour les
autres actions qui nutilisent pas le helper, tout en permettant de conserver le controller mieux organis :
class BakeriesController extends AppController {
public function bake() {
$this->helpers[] = 'Time';
}
public function mix() {
// Le Helper Time n'est pas charg ici et n'est par consquent
// pas disponible
}
}
Si vous avez besoin dactiver un helper pour tous les controllers, ajoutez son nom dans le tableau $helpers
du fichier /app/Controller/AppController.php ( crer si pas prsent). Noubliez pas dinclure
les helpers par dfaut Html et Form :
class AppController extends Controller {
public $helpers = array('Form', 'Html', 'Js', 'Time');
}
Vous pouvez passer des options dans les helpers. Ces options peuvent tre utilises pour dfinir les valeurs
dattributs ou modifier le comportement du helper :
class AwesomeHelper extends AppHelper {
public function __construct(View $view, $settings = array()) {
parent::__construct($view, $settings);
debug($options);
}
}
class AwesomeController extends AppController {
public $helpers = array('Awesome' => array('option1' => 'valeur1'));
}
Depuis 2.3 les options sont fusionnes avec la proprit Helper::$settings du helper.
Une configuration courante est dutiliser loption className, qui vous permet de crer des alias de helper
dans vos vues. Cette fonctionnalit est utile quand vous voulez remplacer $this->Html ou tout autre
Helper de rfrence avec une mise en oeuvre personnalise :
498
// app/Controller/PostsController.php
class PostsController extends AppController {
public $helpers = array(
'Html' => array(
'className' => 'MyHtml'
)
);
}
// app/View/Helper/MyHtmlHelper.php
App::uses('HtmlHelper', 'View/Helper');
class MyHtmlHelper extends HtmlHelper {
// Ajouter votre code pour craser le HtmlHelper du coeur
}
Ce qui est au-dessus fera un alias de MyHtmlHelper vers $this->Html dans vos vues.
Note : Faire un alias dun helper remplace cette instance partout o le helper est utilis, y compris dans les
autres Helpers.
Lutilisation des configurations du helper vous permet de configurer de manire dclarative vos helpers et de
garder la logique de configuration de vos actions des controllers. Si vous avez des options de configuration
qui ne peuvent pas tre inclues comme des parties de dclaration de classe, vous pouvez les dfinir dans le
callback beforeRender de votre controller :
class PostsController extends AppController {
public function beforeRender() {
parent::beforeRender();
$this->helpers['CustomStuff'] = $this->_getCustomStuffSettings();
}
}
Utiliser les Helpers Une fois que vous avez configur les helpers que vous souhaitiez utiliser, dans
votre controller, chaque helper est expos en proprit publique dans la vue. Par exemple, si vous utilisiez
HtmlHelper, vous serez capable dy accder en faisant ce qui suit :
echo $this->Html->css('styles');
Ce qui est au-dessus appelera la mthode css du HtmlHelper. Vous pouvez accder nimporte quel helper
charg en utilisant $this->{$helperName}. Il peut venir un temps o vous aurez besoin de charger
dynamiquement un helper partir dune vue. Vous pouvez utiliser la vue du HelperCollection pour
le faire :
$mediaHelper = $this->Helpers->load('Media', $mediaSettings);
Le HelperCollection est une collection et supporte lAPI collection utilise partout ailleurs dans CakePHP.
Usage Gnral
499
Mthodes de Callback Les Helpers disposent de plusieurs callbacks qui vous permettent daugmenter le
processus de rendu de vue. Allez voir la documentation de API de Helper et Collections pour plus dinformations.
Crer des Helpers Si un helper du coeur (ou lun prsent sur github ou dans la Boulangerie) ne correspond pas vos besoins, les helpers sont faciles crer.
Mettons que nous voulions crer un helper, qui pourra tre utilis pour produire un lien CSS, faonn
spcialement selon vos besoins, diffrents endroits de votre application. Afin de trouver une place
votre logique dans la structure de helper existante dans CakePHP, vous devrez crer une nouvelle classe
dans /app/View/Helper. Appelons notre helper LienHelper. Le fichier de la classe PHP ressemblera
quelque chose comme ceci :
/* /app/View/Helper/LienHelper.php */
App::uses('AppHelper', 'View/Helper');
class LienHelper extends AppHelper {
public function lancerEdition($titre, $url) {
// La logique pour crer le lien spcialement format se place
ici...
}
}
Note : Les Helpers doivent tendre soit AppHelper soit Helper ou implmenter tous les callbacks dans
lAPI de Helper.
Inclure dautres Helpers Vous souhaitez peut-tre utiliser quelques fonctionnalits dj existantes dans
un autre helper. Pour faire cela, vous pouvez spcifier les helpers que vous souhaitez utiliser avec un tableau
$helpers, format comme vous le feriez dans un controller :
/* /app/View/Helper/LienHelper.php (Utilisant d'autres helpers) */
App::uses('AppHelper', 'View/Helper');
class LienHelper extends AppHelper {
public $helpers = array('Html');
public function lancerEdition($titre, $url) {
// Utilisation du helper HTML pour sortir une donne formate
$link = $this->Html->link($titre, $url, array('class' => 'edit'));
return '<div class="editOuter">' . $link . '</div>';
}
}
Utiliser votre Helper Une fois que vous avez crez votre helper et lavez plac dans
/app/View/Helper/, vous serez capable de linclure dans vos controllers en utilisant la variable spciale $helpers :
500
Une fois que votre controller est au courant de cette nouvelle classe, vous pouvez lutiliser dans vos vues en
accdant un objet nomm daprs le helper :
<!-- fait un lien en utilisant le nouveau helper -->
<?php echo $this->Lien->lancerEdition('Changer cette recette', '/recipes/edit/5'); ?>
Crer des fonctionnalits vos Helpers Tous les helpers tendent une classe spciale, AppHelper
(comme les models tendent AppModel et les controllers tendent AppController). Pour crer une fonctionnalit disponible pour tous les helpers, crez /app/View/Helper/AppHelper.php :
App::uses('Helper', 'View');
class AppHelper extends Helper {
public function customMethod () {
}
}
API de Helper
class Helper
La classe de base pour les Helpers. Elle fournit un nombre de mthodes utiles et des fonctionnalits
pour le chargement dautres helpers.
Helper::webroot($file)
Dcide du nom de fichier du webroot de lapplication. Si un thme est actif et que le fichier existe
dans le webroot du thme courant, le chemin du fichier du thme sera retourn.
Helper::url($url, $full = false)
Gnre une URL chappe de HTML, qui dlgue Router::url().
Helper::value($options = array(), $field = null, $key = value)
Rcupre la valeur pour un nom dinput donn.
Helper::domId($options = null, $id = id)
Gnre une valeur id en CamelCase pour le champ slectionn courant. Ecraser cette mthode dans
votre AppHelper vous permettra de changer la faon dont CakePHP gnre les attributs ID.
Callbacks
Helper::beforeRenderFile($viewFile)
Est appel avant que tout fichier de vue soit rendu. Cela inclut les elements, les vues, les vues parentes
et les layouts.
Helper::afterRenderFile($viewFile, $content)
Est appel aprs que tout fichier de vue est rendu. Cela inclut les elements, les vues, les vues parentes
et les layouts. Un callback peut modifier et retourner $content pour changer la manire dont le
contenu rendu est affich dans le navigateur.
Usage Gnral
501
Helper::beforeRender($viewFile)
La mthode beforeRender est appel aprs la mthode beforeRender du controller, mais avant les
rendus du controller de la vue et du layout Reoit le fichier rendre en argument.
Helper::afterRender($viewFile)
Est appel aprs que la vue est rendu, mais avant que le rendu du layout ait commenc.
Helper::beforeLayout($layoutFile)
Est appel avant que le rendu du layout commence. Reoit le nom du fichier layout en argument.
Helper::afterLayout($layoutFile)
Est appel aprs que le rendu du layout est fini. Reoit le nom du fichier layout en argument.
Collections
Les Components, les Helpers, les Behaviors et les Tasks partagent tous une structure similaire et des comportements. CakePHP 2.0 fournit maintenant une API unifie pour interagir avec les objets collections similaires. Lobjet collection dans cakePHP vous donne un moyen uniforme dinteragir avec diffrentes sortes
dobjets dans votre application.
Mme si les exemples ci-dessous utiliseront des Components, le mme comportement peut tre envisag
pour les Helpers, Behaviors, et des Tasks en plus des components.
Charger et Dcharger les objets
Le chargement dobjets sur nimporte quelle collection peut tre effectu en utilisant la mthode load() :
$this->Prg = $this->Components->load('Prg');
$this->Prg->process();
Au chargement du component, si il nest pas charg dans la collection, une nouvelle instance sera cre. Si
le component est dj charg, une autre instance ne sera pas cre. Au chargement des components, vous
pouvez aussi leurs fournir des configurations additionnelles :
$this->Cookie = $this->Components->load('Cookie', array('name' => 'sweet'));
Tout couple cl/valeur fourni sera passe au constructeur de Component. Une exception cette rgle est
className. ClassName est une cl spciale qui est utilise pour crer des alias dobjets dans une collection. Ceci permet davoir des noms de component qui ne refltent pas les noms de classes, ce qui peut tre
utile quand on tend les components du noyau :
$this->Auth = $this->Components->load('Auth', array('className' => 'MyCustomAuth'));
$this->Auth->user(); // Utilise rellement MyCustomAuth::user();
Linverse du chargement dun objet, est son dchargement. Les objets dchargs sont retirs de la mmoire,
et nauront pas de callbacks supplmentaires dclenchs sur eux :
$this->Components->unload('Cookie');
$this->Cookie->read(); // Fatal error.
502
Dclenchement de callbacks
Les callbacks sont supports par les collections dobjets. Quand une collection a un callback dclench,
cette mthode sera appele sur tous les objets activs dans la collection. Vous pouvez passer des paramtres
au boucle de callback comme ceci
$this->Behaviors->trigger('afterFind', array($this, $results, $primary));
Ci-dessus $this sera pass comme premier argument toutes les mthodes afterFind des helpers. Il y a
plusieurs options qui peuvent tre utilises pour contrler comment les callbacks sont tus :
breakOn Dfini la valeur ou aux valeurs pour lesquels vous voulez stopper la propagation. Peut tre
une valeur scalaire, ou un tableau de valeur stopper. False par dfaut.
break Dfini true pour valider larrt. Quand un dclencheur est cass, la dernire valeur
sera retourne. Si utilis en combinaison avec collectReturn les rsultats collects
seront retourns. False par dfaut.
collectReturn Dfini true pour collecter le retour de chaque objet dans un tableau. Ce tableau de
donnes retournes sera retourn depuis lappel trigger(). False par dfaut.
triggerDisabled Dclenchera le callback sur tous les objets dans la collection mme ceux qui sont
non-activs. False par dfaut.
modParams Permet chacun des objets auquel le callback fait des demandes de modifier les
paramtres de lobjet suivant. Paramtrer modParams en valeur entire vous permettra de modifier le
paramtre avec cet index. Nimporte quelle valeur non-nulle modifiera lindex de paramtre indiqu.
False par dfaut.
Effacer des boucles de callback En utilisant les options break et breakOn vous pouvez annuler une
boucle de callback mi-chemin semblable interrompre la propagation vnementielle en JavaScript
$this->Behaviors->trigger(
'beforeFind',
array($this, $query),
array('break' => true, 'breakOn' => false)
);
Dans lexemple ci-dessus, si nimporte quel behavior retourne false depuis sa mthode beforeFind, il ny
aura pas dautres callback appels. Le retour de trigger() sera false.
Activation et dsactivation des objets
Une fois quun objet est charg dans une collection vous pourriez avoir besoin de le dactiver. Dsactiver
un objet dans une collection empche aux futurs callbacks dtre tus sur lobjet moins que loption
triggerDisabled soit utilise :
// Dsactive le Helper HTML
$this->Helpers->disable('Html');
// R-active le Helper plus tard
$this->Helpers->enable('Html');
Usage Gnral
503
Les objets dsactivs peuvent toujours avoir leur mthodes et proprits normales utilises. La diffrence
majeure entre un objet activ et dsactiv se fait en regard des callbacks. Vous pouvez interroger une collection pour connatre les objets activs, ou vrifier si un objet spcifique est toujours activ en utilisant
enabled() :
// Vrifie si oui ou on un Helper spcifique est activ.
$this->Helpers->enabled('Html');
// $enabled contiendra un tableau des helpers actuellement activs.
$enabled = $this->Helpers->enabled();
Behaviors (Comportements)
Les behaviors ajoutent des fonctionnalits supplmentaires vos models. CakePHP offre un certain nombre
de behaviors integrs tels que TreeBehavior et ContainableBehavior.
Pour en apprendre plus sur la cration et lutilisation des behaviors, lire la section sur Behaviors (Comportements).
Behaviors (Comportements)
Les behaviors ajoutent des fonctionnalits supplmentaires vos models. CakePHP offre un certain nombre
de behaviors integrs tels que TreeBehavior et ContainableBehavior.
Pour en apprendre plus sur la cration et lutilisation des behaviors, lire la section sur Behaviors (Comportements).
ACL
class AclBehavior
Le behavior Acl fournit une solution pour intgrer sans souci un model dans votre systme ACL. Il peut
crer la fois les AROs et les ACOs de manire transparente.
Pour utiliser le nouveau behavior, vous pouvez lajouter la proprit $actsAs de votre model. Quand vous
lajoutez au tableau actsAs, vous choisissez de crer lentre Acl correspondante comme un ARO ou un
ACO. Par dfaut, cela cre des AROs :
class User extends AppModel {
public $actsAs = array('Acl' => array('type' => 'requester'));
}
Ceci attacherait le behavior Acl en mode ARO. Pour attacher le behavior ACL en mode ACO, utilisez
class Post extends AppModel {
public $actsAs = array('Acl' => array('type' => 'controlled'));
}
504
Pour les models duser et de group il est frquent davoir la fois les noeuds ACO et ARO, pour permettre
cela utilisez :
class User extends AppModel {
public $actsAs = array('Acl' => array('type' => 'both'));
}
Modifi dans la version 2.1 : Vous pouvez maintenant attacher en toute scurit le behavior Acl (AclBehavior) votre Appmodel. Aco, Aro et Noeud Acl (AclNode) sont dornavant des extensions du Model et
non plus de lAppModel, ceci pouvait causer une boucle infinie. Si pour certaines raisons, votre application
est dpendante de lutilisation des models comme extension de lAppModel, alors copiez Le Noeud Acl
(AclNode) dans votre application et tendez nouveau AppModel.
Utiliser le behavior Acl
La plupart des tches du behavior Acl sont ralises de faon transparente, dans le callback afterSave()
de votre model. Cependant, son utilisation ncessite que votre Model ait une mthode parentNode() dfinie.
Ceci est utilis par le behavior Acl, pour dterminer les relations parent->enfant. Une mthode parentNode()
de model doit retourner null ou une rfrence au Model parent :
public function parentNode() {
return null;
}
Si vous voulez dfinir un nud ACO ou ARO comme parent pour votre Model, parentNode() doit retourner
lalias du nud ACO ou ARO :
public function parentNode() {
return 'root_node';
}
Voici un exemple plus complet. Utilisons un model dexemple User, avec User belongsTo Group :
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
$data = $this->data;
if (empty($this->data)) {
$data = $this->read();
}
if (!$data['User']['group_id']) {
return null;
}
return array('Group' => array('id' => $data['User']['group_id']));
}
Behaviors (Comportements)
505
Dans lexemple ci-dessus, le retour est un tableau qui ressemble aux rsultats dun find de model. Il est
important davoir une valeur did dfinie ou bien la relation parentNode chouera. Le behavior Acl utilise
ces donnes pour construire son arborescense.
node()
Le Behavior Acl vous permet aussi de rcuprer le nud Acl associ un enregistrement de model. Aprs
avoir dfini $model->id. Vous pouvez utiliser $model->node() pour rcuprer le nud Acl associ.
Vous pouvez aussi rcuprer le nud Acl de nimporte quelle ligne, en passant un tableau de donnes en
paramtre :
$this->User->id = 1;
$noeud = $this->User->node();
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user);
Containable
class ContainableBehavior
Une nouvelle intgration au coeur de CakePHP 1.2 est le Behavior Containable
ContainableBehavior. Ce behavior vous permet de filtrer et de limiter les oprations de rcupration
de donnes find. Utiliser Containable vous aidera a rduire lutilisation inutile de votre base de donnes
et augmentera la vitesse et la plupart des performances de votre application. La classe vous aidera aussi a
chercher et filtrer vos donnes pour vos utilisateurs dune faon propre et cohrente.
Le behavior Containable vous permet de rationaliser et de simplifier les oprations de construction du
model. Il agit en modifiant temporairement ou dfinitivement les associations de vos models. Il fait cela en
utilisant des containements pour gnrer une srie dappels bindModel et unbindModel. tant donn
que Containable modifie seulement les relations dj existantes, il ne vous permettra pas de restreindre les
rsultats pour des associations distantes. Pour cela, vous devriez voir les Tables jointes.
Pour utiliser le nouveau behavior, vous pouvez lajouter la proprit $actAs de votre model :
506
Utilisation de Containable
Pour voir comment Containable fonctionne, regardons quelques exemples. Premirement, nous commencerons avec un appel find() sur un model nomm Post. Disons que ce Post a plusieurs (hasMany)
Comment, et Post a et appartient plusieurs (hasAndBelongsToMany) Tag. La quantit de donnes
rcupres par un appel find() normal est assez tendue
debug($this->Post->find('all'));
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[auteur] => Daniel
[email] => dan@example.com
[siteweb] => http://example.com
[commentaire] => Premier commentaire
[created] => 2008-05-18 00:00:00
)
[1] => Array
(
[id] => 2
[post_id] => 1
[auteur] => Sam
[email] => sam@example.net
[siteweb] => http://example.net
[commentaire] => Second commentaire
[created] => 2008-05-18 00:00:00
)
)
[Tag] => Array
(
Behaviors (Comportements)
507
Pour certaines interfaces de votre application, vous pouvez ne pas avoir besoin dautant dinformation depuis
le model Post. Le Behavior containable permet de rduire ce que le find() retourne.
Par exemple, pour ne rcuprer que les informations lies au post vous pouvez faire cela :
$this->Post->contain();
$this->Post->find('all');
Aprs avoir fait cela, vous vous retrouvez avec quelque chose de plus concis :
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[titre] => Second article
[contenu] => bbb
[created] => 2008-05-19 00:00:00
)
)
Ceci nest pas nouveau : en fait, vous pouvez obtenir le mme rsultat sans le behavior Containable
en faisant quelque chose comme :
508
$this->Post->recursive = -1;
$this->Post->find('all');
Le behavior Containable simpose vraiment quand vous avez des associations complexes, et que
vous voulez rogner le nombre dinformation au mme niveau. La proprit $recursive des models est utile si
vous voulez viter un niveau de rcursivit entier, mais pas pour choisir ce que vous garder chaque niveau.
Regardons ensemble comment la methode contain() agit.
Le premier argument de la mthode accepte le nom, ou un tableau de noms, des models garder lors du find.
Si nous dsirons aller chercher tous les posts et les tags annexes (sans aucune information de commentaire),
nous devons essayer quelque chose comme
$this->Post->contain('Tag');
$this->Post->find('all');
Sans le behavior Containable, nous finirions par utiliser la mthode unbindModel() du model, plusieurs
fois si nous pluchons plusieurs models. Le behavior Containable fournit un moyen plus propre
pour accomplir cette mme tche.
Des associations plus profondes
Containable permet galement daller un peu plus loin : vous pouvez filtrer les donnes des models associs.
si vous regardez les rsultats dun appel find() classique, notez le champ auteur dans le model Comment.
Si vous tes intresss par les posts et les noms des commentaires des auteurs - et rien dautre - vous devez
faire quelque chose comme :
$this->Post->contain('Comment.auteur');
$this->Post->find('all');
// ou..
$this->Post->find('all', array('contain' => 'Comment.auteur'));
ici, nous avons dit au behavior Containable de nous donner les informations du post, et uniquement le champ
auteur du model Comment associ. Le rsultat du find ressemble :
[0] => Array
(
[Post] => Array
(
[id] => 1
[titre] => Premier article
[contenu] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
Behaviors (Comportements)
509
Comme vous pouvez le voir, les tableaux de Comment ne contiennent uniquement que le champ auteur (avec
le post_id qui est requis par CakePHP pour prsenter le rsultat)
Vous pouvez galement filtrer les donnes associes Comment en spcifiant une condition :
$this->Post->contain('Comment.author = "Daniel"');
$this->Post->find('all');
//ou...
$this->Post->find('all', array('contain' => 'Comment.author = "Daniel"'));
Ceci nous donne comme rsultat les posts et commentaires dont daniel est lauteur :
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => Premier article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[author] => Daniel
[email] => dan@example.com
[website] => http://example.com
[comment] => Premier commentaire
[created] => 2008-05-18 00:00:00
)
)
)
510
Il y a un important gain utiliser Containable quand on filtre sur des associations plus profondes. Dans
lexemple prcdent, imaginez que vous avez 3 posts dans votre base de donnes et que Daniel a comment
sur 2 de ces posts. Lopration $this->Post->find(all, array(contain => Comment.author = Daniel)) ;
retournerait TOUS les 3 posts, pas juste les 3 posts que Daniel a comment. Cela ne va pas retourner tous
les comments cependant, juste les comments de Daniel.
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => First article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[author] => Daniel
[email] => dan@example.com
[website] => http://example.com
[comment] => First comment
[created] => 2008-05-18 00:00:00
)
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[title] => Second article
[content] => bbb
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
)
)
[2] => Array
(
[Post] => Array
(
[id] => 3
[title] => Third article
[content] => ccc
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
Behaviors (Comportements)
511
Si vous voulez filtrer les posts selon les comments, pour que les posts non comments par Daniel ne soient
pas retourns, le plus simple est de trouver tous les comments de Daniel et de faire un contain sur les Posts.
$this->Comment->find('all', array(
'conditions' => 'Comment.author = "Daniel"',
'contain' => 'Post'
));
Des filtres supplmentaires peuvent tre utilises en utilisant les options de recherche standard find :
$this->Post->find('all', array('contain' => array(
'Comment' => array(
'conditions' => array('Comment.author =' => "Daniel"),
'order' => 'Comment.created DESC'
)
)));
Voici un exemple dutilisation de ContainableBehavior quand vous avez des relations profondes et
complexes entre les models.
Examinons les associations des models suivants :
User->Profile
User->Account->AccountSummary
User->Post->PostAttachment->PostAttachmentHistory->HistoryNotes
User->Post->Tag
Voici comment nous rcuprons les associations ci-dessus avec le behavior Containable
$this->User->find('all', array(
'contain' => array(
'Profile',
'Account' => array(
'AccountSummary'
),
'Post' => array(
'PostAttachment' => array(
'fields' => array('id', 'name'),
'PostAttachmentHistory' => array(
'HistoryNotes' => array(
512
Gardez lesprit que la cl contain nest utilise quune seule fois dans le model principal, vous navez
pas besoin dutiliser contain nouveau dans les models lis.
Note : En utilisant les options fields et contain - noubliez pas dinclure toutes les cls trangres que
votre requte requiert directement ou indirectement. Notez galement que pour que le behavior Containable
puisse fonctionner avec le contain pour tous les models, vous devez lattacher votre AppModel.
Le Behavior Containable a plusieurs options qui peuvent tre dfinies quand le behavior est attach
un model. Ces paramtres vous permettent daffiner le behavior de Containable et de travailler plus facilement avec les autres behaviors.
recursive (boolean, optional), dfinir true pour permettre au behavior Containable, de dterminer automatiquement le niveau de rcursivit ncessaire pour rcuprer les models spcifis et pour paramtrer
la rcursivit du model ce niveau. Le dfinir false dsactive cette fonctionnalit. La valeur par dfaut
est true.
notices (boolean, optional), met des alertes E_NOTICES pour les liaisons rfrences dans un appel
containable et qui ne sont pas valides. La valeur par dfaut est true.
autoFields (boolean, optional), ajout automatique des champs ncessaires pour rcuprer les liaisons
requtes. La valeur par dfaut est true.
order : (string, optional) lordre dans lequel les elements contenus sont tris.
A partir de lexemple prcdent, ceci est un exemple de la faon de forcer les Posts tre tris selon la date
de dernire modification :
$this->User->find('all', array(
'contain' => array(
'Profile',
'Post' => array(
'order' => 'Post.updated DESC'
)
)
));
Vous pouvez changer les paramtres du Behavior Containable lexcution, en r-attachant le behavior
comme vu au chapitre Behaviors (Comportements) (Utiliser les Behaviors).
Le behavior Containable peut quelque fois causer des problmes avec dautres behaviors ou des requtes
qui utilisent des fonctions dagrgations et/ou des clauses GROUP BY. Si vous obtenez des erreurs SQL
Behaviors (Comportements)
513
Note : Si vous fates un contain des associations travers le model la place, il nhonorera pas loption
rcursive de Containable. Donc si vous dfinissez -1 par exemple pour le model, cela ne marchera pas :
$this->User->recursive = -1;
$this->User->contain(array('Profile', 'Account'));
$users = $this->paginate('User');
Le Behavior Translate
class TranslateBehavior
Le behavior Translate est en fait assez simple paramtrer et faire fonctionner out of the box, le tout avec
trs peu de configuration. Dans cette section, vous apprendrez comment ajouter et configurer ce behavior,
pour lutiliser dans nimporte quel model.
Si vous utilisez le behavior Translate en parallle de Containable, assurez-vous de dfinir la cl fields pour
vos requtes. Sinon, vous pourriez vous retrouver avec des fragments SQL gnrs invalides.
Initialisation des tables de la Base de donne i18n
Vous pouvez soit utiliser la console CakePHP, soit les crer manuellement. Il est recommand dutiliser la
console pour cela, parce quil pourrait arriver que le layout change dans les futures versions de CakePHP.
En restant fidle la console, cela garantira que vous ayez le bon layout :
./cake i18n
Slectionner[I], ce qui lancera le script dinitialisation de la base de donnes i18n. Il vous sera demand
si vous voulez supprimer toute table existante et si vous voulez en crer une. Rpondez par oui si vous tes
certain quil ny a pas encore une table i18n et rpondez encore par oui pour crer la table.
514
Ajoutez-le votre model en utilisant la proprit $actsAs comme dans lexemple suivant.
class Post extends AppModel {
public $actsAs = array(
'Translate'
);
}
Ceci ne produira encore rien, parce quil faut un couple doptions avant que cela ne commence fonctionner.
Vous devez dfinir, quels champs du model courant devront tre dtects dans la table de traduction que nous
avons cre prcdemment.
Dfinir les Champs
Vous pouvez dfinir les champs en tendant simplement la valeur Translate avec un autre tableau,
comme
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'fieldOne', 'fieldTwo', 'and_so_on'
)
);
}
Aprs avoir fait cela (par exemple, en prcisant title comme lun des champs), vous avez dj termin
la configuration de base. Super ! Daprs notre exemple courant, le model devrait maintenant ressembler
quelque chose comme cela
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
}
Quand vous dfinissez vos champs traduire dans le Behavior Translate, assurez-vous domettre les champs
du schma de model traduits. Si vous laissez les champs en place, il peut y avoir un problme de rcupration
de donnes avec les locales.
Note : Si tous les champs dans votre model sont traduits, assurez-vous dajouter les colonnes created
et modified votre table. CakePHP a besoin dau moins un champ diffrent dune cl primaire avant
denregistrer un enregistrement.
Behaviors (Comportements)
515
Conclusion
A partir de maintenant, chaque mise jour/cration dun enregistrement fera que le Behavior Translate
copiera la valeur de title dans la table de traduction (par dfaut : i18n), avec la locale courante. Une
locale est un identifiant dune langue, pour ainsi dire.
Lire le contenu traduit
Par dfaut, le TranslateBehavior va automatiquement rcuprer et ajouter les donnes bases sur la locale courante. La locale courante est lue partir de Configure::read(Config.language) qui
est assigne par la classe L10n. Vous pouvez surcharger cette valeur par dfaut la vole en utilisant
$Model->locale.
Rcuprer les champs traduits dans une locale spcifique En dfinissant $Model->locale, vous
pouvez lire les traductions pour une locale spcifique :
// Lire les donnes de la locale espagnole.
$this->Post->locale = 'es';
$results = $this->Post->find('first', array(
'conditions' => array('Post.id' => $id)
));
// $results va contenir la traduction espagnole.
Rcuprer tous les enregistrements de traduction pour un champ Si vous voulez avoir tous les enregistrements de traduction attachs lenregistrement de model courant, vous tendez simplement le tableau
champ dans votre paramtrage du behavior, comme montr ci-dessous. Vous tes compltement libre de
choisir le nommage.
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title' => 'titleTranslation'
)
);
}
516
Note : Lenregistrement du model contient un champ virtuel appel locale. Il indique quelle locale est
utilise dans ce rsultat.
Notez que seuls les champs du model que vous fates avec un find seront traduits. Les Models attachs
via les associations ne seront pas traduits parce que le dclenchement des callbacks sur les models associs
nest actuellement pas support.
Utiliser la mthode bindTranslation Vous pouvez aussi rcuprer toutes les traductions seulement quand
vous en avez besoin, en utilisant la mthode bindTranslation.
TranslateBehavior::bindTranslation($fields, $reset)
$fields st un tableau associatif compos du champ et du nom de lassociation, dans lequel la cl est le
champ traduisible et la valeur est le nom fictif de lassociation.
Avec ce paramtrage, le rsultat de votre find() devrait ressembler quelque chose comme ceci
Array
(
[Post] => Array
(
[id] => 1
[title] => Beispiel Eintrag
Behaviors (Comportements)
517
Vous pouvez forcer le model qui utilise le TranslateBehavior sauvegarder dans une autre langue que celle
dtecte.
Pour dire un model dans quelle langue le contenu devra tre sauv, changez simplement la valeur de la
proprit $locale du model, avant que vous ne sauvegardiez les donnes dans la base. Vous pouvez faire cela
dans votre controller ou vous pouvez le dfinir directement dans le model.
Exemple A : Dans votre controller :
class PostsController extends AppController {
public function add() {
if (!empty($this->request->data)) {
$this->Post->locale = 'de_de'; // we are going to save the german version
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->redirect(array('action' => 'index'));
}
}
}
}
518
Si vous attendez beaucoup dentre, vous vous demandez certainement comment grer tout cela dans une
base de donnes qui grossit rapidement. Il y a deux proprits introduite dans le Behavior Translate qui
permettent de spcifier quel model doit tre reli au model qui contient les traductions.
Ceux-ci sont $translateModel et $translateTable.
Disons que nous voulons sauver nos traductions pour tous les posts dans la table post_i18ns au lieu de la
valeur par dfaut de la table i18n. Pour faire cela vous avez besoin de paramtrer votre model comme cela
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Utilise un model diffrent (et table)
public $translateModel = 'PostI18n';
}
Note : Il est important vous mettiez au pluriel la table. Cest maintenant un model habituel et il peut tre
trait en tant que tel avec les conventions qui en dcoulent. Le schma de la table elle-mme doit tre
identique celui gnr par la console CakePHP. Pour vous assurer quil sintgre vous pourriez initialiser
une table i18n vide au travers de la console et renommer la table aprs coup.
Crer le Model de Traduction Pour que cela fonctionne vous devez crer le fichier du model actuel dans
le dossier des models. La raison est quil ny a pas de proprit pour dfinir le displayField directement dans
le model utilisant ce behavior.
Assurez vous de changer le $displayField en field.
Behaviors (Comportements)
519
Cest tout ce quil faut. Vous pouvez aussi ajouter toutes les proprits des models comme $useTable. Mais
pour une meilleure cohrence nous pouvons faire cela dans le model qui utilise ce model de traduction. Cest
l que loption $translateTable entre en jeu.
Modification de la Table Si vous voulez changer le nom de la table, il vous suffit simplement de dfinir
$translateTable dans votre model, comme ceci
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Utilise un model diffrent
public $translateModel = 'PostI18n';
// Utilise une table diffrente pour translateModel
public $translateTable = 'post_translations';
}
A noter que vous ne pouvez pas utiliser $translateTable seule. Si vous navez pas lintention dutiliser un
Model de traduction $translateModel personnalis, alors laissez cette proprit inchange. La raison
est quelle casserait votre configuration et vous afficherait un message Missing Table pour le model I18n
par dfaut, lequel est cr lexcution.
Tree
class TreeBehavior
Cest assez courant de vouloir stocker ses donnes sous une forme hirarchique dans la table dune base
de donnes. Des exemples de tels besoins pourraient tre des catgories avec un nombre illimit de souscatgories, des donnes en relation avec un systme de menu multi-niveaux ou une reprsentation littrale
dune hirarchie, comme celle qui est utilise pour stocker les objets de contrle daccs avec la logique
ACL.
Pour de petits arbres de donnes et les cas o les donnes nont que quelques niveaux de profondeurs, cest
simple dajouter un champ parent_id votre table et de lutiliser pour savoir quel objet est le parent de quel
autre. En natif avec CakePHP, il existe cependant un moyen puissant davoir les bnfices de la logique
MPTT MPTT logic <http ://www.sitepoint.com/hierarchical-data-database-2/>, sans avoir connatre les
dtails de limplmentation technique - moins que a ne vous intresse ;).
520
Pr-requis
Pour utiliser le behavior en Arbre (TreeBehavior), votre table ncessite 3 champs tels que lists ci-dessous
(tous sont des entiers) :
parent - le nom du champ par dfaut est parent_id, pour stocker lid de lobjet parent.
left - le nom du champ par dfaut est lft, pour stocker la valeur lft de la ligne courante.
right - le nom du champ par dfaut est rght, pour stocker la valeur rght de la ligne courante.
Si vous tes familier de la logique MPTT vous pouvez vous demander pourquoi un champ parent existe parce quil est tout bonnement plus facile deffectuer certaines tches lusage, si un lien parent direct est
stock en base, comme rechercher les enfants directs.
Note : Le champ parent doit tre capable davoir une valeur NULL ! Cela pourrait sembler fonctionner,
si vous donnez juste une valeur parente de zro aux lments de premier niveau, mais le fait de rordonner
larbre (et sans doute dautres oprations) chouera.
Utilisation Basique
Le behavior Tree possde beaucoup de fonctionnalits, mais commenons avec un exemple simple. Crons
la table suivante :
CREATE TABLE categories (
id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER(10) DEFAULT NULL,
lft INTEGER(10) DEFAULT NULL,
rght INTEGER(10) DEFAULT NULL,
name VARCHAR(255) DEFAULT '',
PRIMARY KEY (id)
);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(1, 'My Categories', NULL, 1, 30);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(2, 'Fun', 1, 2, 15);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(3, 'Sport', 2, 3, 8);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(4, 'Surfing', 3, 4, 5);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(5, 'Extreme knitting', 3, 6, 7);
Behaviors (Comportements)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
521
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(6, 'Friends', 2, 9, 14);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(7, 'Gerald', 6, 10, 11);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(8, 'Gwendolyn', 6, 12, 13);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(9, 'Work', 1, 16, 29);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(10, 'Reports', 9, 17, 22);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(11, 'Annual', 10, 18, 19);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(12, 'Status', 10, 20, 21);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(13, 'Trips', 9, 23, 28);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(14, 'National', 13, 24, 25);
INSERT INTO
`categories` (`id`, `name`, `parent_id`,
VALUES
(15, 'International', 13, 26, 27);
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
`lft`, `rght`)
Dans le but de vrifier que tout est dfini correctement, nous pouvons crer une mthode de test et afficher
les contenus de notre arbre de catgories, pour voir quoi il ressemble. Avec un simple controller :
class CategoriesController extends AppController {
public function index() {
$data = $this->Category->generateTreeList(
null,
null,
null,
' '
);
522
debug($data); die;
}
}
Nous pouvons vrifier quoi ressemble les donnes de notre arbre de catgories, en visitant /categories.
Vous devriez voir quelque chose comme :
My Categories
Fun
Sport
Surfing
Extreme knitting
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Ajouter des donnes Dans la section prcdente, nous avons utilis des donnes existantes et nous avons
vrifi quelles semblaient hirarchiques avec la mthode generateTreeList. Toutefois vous devez
ajouter vos donnes de la mme manire que vous le feriez pour nimporte quel model. Par exemple :
// pseudo controller code
$data['Category']['parent_id'] = 3;
$data['Category']['name'] = 'Skating';
$this->Category->save($data);
Lorsque vous utilisez le behavior en arbre il nest pas ncessaire de faire plus que de dfinir lid du parent
(parent_id), le behavior tree prendra soin du reste. Si vous ne dfinissez pas lid du parent (parent_id), Le
behavior Tree additionnera vos nouveaux ajouts au sommet de larbre :
// pseudo code du controller
$data = array();
$data['Category']['name'] = 'Other People\'s Categories';
$this->Category->save($data);
Excuter les extraits de code ci-dessus devrait modifier larbre comme suit :
My Categories
Fun
Behaviors (Comportements)
523
Sport
Surfing
Extreme knitting
Skating New
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories New
Modification des donnes La modification des donnes est aussi transparente que laddition des donnes.
Si vous modifiez quelque chose, mais ne changez pas le champ de lid du parent (parent_id) - la structure de
vos donnes restera inchange. Par exemple :
// pseudo controller code
$this->Category->id = 5; // id of Extreme knitting
$this->Category->save(array('name' => 'Extreme fishing'));
Le code ci-dessus naffecterait pas le champ de lid du parent (parent_id) - mme si lid du parent (parent_id)
est inclue dans les donnes passes sauvegarder si les donnes ne changent pas, pas plus que la structure
de donnes. Donc larbre de donnes devrait maintenant ressembler :
My Categories
Fun
Sport
Surfing
Extreme fishing Updated
Skating
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories
Dplacer les donnes autour de votre arbre est aussi une affaire simple. Supposons que Extreme fishing
nappartienne pas Sport, mais devrait se trouver plutt sous Dautres catgories de gens. Avec le code
suivant :
524
525
International
Other Peoples Categories
Extreme fishing
Interroger et utiliser vos donnes Utiliser et manipuler des donnes hirarchises peut savrer assez
difficile. Cest pourquoi le behavior tree met votre disposition quelques mthodes de permutations en plus
des mthodes find de bases.
Note : La plupart des mthodes de tree se basent et renvoient des donnes tries en fonction du champ lft.
Si vous appelez find() sans trier en fonction de lft, ou si vous fates une demande de tri sur un tree,
vous risquez dobtenir des rsultats inattendus.
class TreeBehavior
children($id = null, $direct = false, $fields = null, $order = null, $limit = null, $page = 1,
$recursive = null)
Paramtres
$id Lid de lenregistrement rechercher.
$direct Defini true pour ne retourner que les descendants directs.
$fields Un simple champ texte ou un tableau de champs inclure dans le retour.
$order Chane SQL des conditions ORDER BY.
$limit SQL LIMIT dclaration.
$page pour accder aux resultats pagins.
$recursive Nombre du niveau de profondeur pour la rcursivit des models associs.
La mthode children prend la cl primaire (lid dune ligne) et retourne les enfants (children), par
dfaut dans lordre dapparition dans larbre. Le second paramtre optionnel definit si il faut ou non
retourner seulement les enfants directs. En utilisant lexemple des donnes de la section prcdente :
$allChildren = $this->Category->children(1); // un tableau plat 11 lments
// -- ou -$this->Category->id = 1;
$allChildren = $this->Category->children(); // un tableau plat 11 lments
526
Sortie :
array(
[1] =>
[2] =>
[3] =>
[4] =>
[16] =>
[6] =>
[7] =>
[8] =>
[9] =>
[13] =>
[14] =>
[15] =>
[17] =>
[5] =>
)
"My Categories",
"_Fun",
"__Sport",
"___Surfing",
"___Skating",
"__Friends",
"___Gerald",
"___Gwendolyn",
"_Work",
"__Trips",
"___National",
"___International",
"Other People's Categories",
"_Extreme fishing"
formatTreeList($results, $options=array())
Introduit dans la version 2.7.
Paramtres
$results Rsultats de lappel de find(all).
$options Options passer.
Cette mthode va retourner des donnes similaires find(list) mais avec un prfix imbriqu qui est
spcifi dans loption spacer pour montrer la structure de vos donnes.
Les options supportes sont :
keyPath : Un chemin vers la cl, par ex {n}.Post.id.
Behaviors (Comportements)
527
getParentNode()
Cette fonction comme son nom lindique, donne en retour le noeud parent dun nud, ou false si le
noeud na pas de parent (cest le nud racine). Par exemple :
$parent = $this->Category->getParentNode(2); //<- id de fun
// $parent contient toutes les catgories
Utilisation avance
Le behavior Tree ne fonctionne pas uniquement en tche de fond, il y a un certain nombre de mthodes
spcifiques dans le behavior Tree pour rpondre a vos besoins de donnes hierarchiques, et des problmes
inattendus qui pourraient survenir durant le processus.
528
TreeBehavior::moveDown()
Utilis pour dplacer un seul nud dans larbre. Vous devez fournir l ID de llment dplacer et un
nombre positif de combien de positions le noeud devrait tre dplac vers le bas. Tous les nuds enfants
pour le noeud spcifi seront galement dplacs.
Voici lexemple dune action dun controller (dans un controller nomm Category) qui dplace un noeud
spcifi vers le bas de larbre :
public function movedown($id = null, $delta = null) {
$this->Category->id = $id;
if (!$this->Category->exists()) {
throw new NotFoundException(__('Invalid category'));
}
if ($delta > 0) {
$this->Category->moveDown($this->Category->id, abs($delta));
} else {
$this->Session->setFlash(
'Please provide the number of positions the field should be' .
'moved down.'
);
}
return $this->redirect(array('action' => 'index'));
}
Par exemple, si vous souhaitez dplacer le Sport (id de 3) dune catgorie vers le bas, vous devriez requter : /categories/movedown/3/1.
TreeBehavior::moveUp()
Utilis pour dplacer un seul nud de larbre. Vous devez fournir lID de llment dplacer et un nombre
positif de combien de positions le noeud devrait tre dplac vers le haut. Tous les nuds enfants seront
galement dplacs.
Voici un exemple dun controller action (dans un controller categories) dplacant un noeud plus haut dans
un arbre :
public function moveup($id = null, $delta = null) {
$this->Category->id = $id;
if (!$this->Category->exists()) {
throw new NotFoundException(__('Invalid category'));
}
if ($delta > 0) {
$this->Category->moveUp($this->Category->id, abs($delta));
} else {
$this->Session->setFlash(
'Please provide a number of positions the category should' .
'be moved up.'
);
}
Behaviors (Comportements)
529
Par exemple, si vous souhaitez dplacer la catgory Gwendoline (id de 8) plus haut dune position vous
devriez requter : /categories/moveup/8/1. Maintenant lordre des Amis sera Gwendolyn, Grald.
TreeBehavior::removeFromTree($id = null, $delete = false)
En utilisant cette mthode, un neud sera supprime ou dplace, tout en conservant son sous-arbre, qui sera
apparent un niveau suprieur. Il offre plus de contrle que : ref : model-delete qui, pour un model en
utilisant le behavior tree supprimera le noeud spcifi et tous ses enfants.
Prenons larbre suivant au dbut :
My Categories
Fun
Sport
Surfing
Extreme knitting
Skating
En executant le code suivant avec lid de Sport :
$this->Node->removeFromTree($id);
Larbre deviendrait
My Categories
Fun
Surfing
Extreme knitting
Skating
Ceci dmontre lutilisation alternative de removeFromTree, les enfants ont t reparents et Sport a t
effac.
TreeBehavior::reorder(array(id => null, field => $Model->displayField, order =>
ASC, verify => true))
Rordonne les nuds (et nuds enfants) de larbre en fonction du champ et de la direction spcifie dans
les paramtres. Cette mthode ne changera pas le parent dun nud.
530
$model->reorder(array(
//id de l'enregistrement utiliser comme noeud haut pour rordonner, default: $Model->
'id' => ,
//champ utiliser pour rordonner, par dfaut: $Model->displayField
'field' => ,
//direction de l'ordonnement, par dfaut: 'ASC'
'order' => ,
//vrifier ou pas l'arbre avant de rordonner, par dfaut: true
'verify' =>
));
Note : Si vous avez sauvegard vos donnes ou fait dautres oprations sur le model, vous pouvez dfinir
$model->id = null avant dappeler reorder. Sinon, seuls les enfants du nud actuel et ses enfants
seront rordonns.
En raison de la nature complexe auto-rfrentielle de ces structures de donnes comme les arbres et les listes
chanes, elles peuvent parfois se rompre par un appel ngligent. Rassurez-vous, tout nest pas perdu ! Le
behavior Tree contient plusieurs fonctionnalits prcdemment non-documentes destines se remettre de
telles situations.
TreeBehavior::recover($mode = parent, $missingParentAction = null)
Le paramtre mode est utilis pour spcifier la source de linfo qui est correcte. La source oppose de
donnes sera peuple en fonction de cette source dinformation. Ex : si le champ MPTT est corrompu ou
vide, avec le $mode parent la valeur du champ parent_id sera utilise pour peupler les champs
gauche et droite.
Le paramtre missingParentAction sapplique uniquement aux parent mode et dtermine ce quil
faut faire si le champ parent contient un identifiant qui nest pas prsent.
Options $mode permises :
parent - utilise lactuelparent_idpour mettre jour les champs lft et rght.
tree - utilise les champs actuels lftetrghtpour mettre jour le champ
parent_id
Les options de missingParentActions autorises durant lutilisation de mode=parent :
null - ne fait rien et continue
return - ne fait rien et fait un return
delete - efface le noeud
int - definit parent_id cet id
Exemple :
// Reconstruit tous les champs gauche et droit en se basant sur parent_id
$this->Category->recover();
// ou
$this->Category->recover('parent');
Behaviors (Comportements)
531
// Reconstruit tous les parent_id en se basant sur les champs lft et rght
$this->Category->recover('tree');
TreeBehavior::reorder($options = array())
Rordonne les nuds (et nuds enfants) de larbre en fonction du champ et de la direction spcifis dans
les paramtres. Cette mthode ne change pas le parent dun nud.
La rorganisation affecte tous les nuds dans larborescence par dfaut, mais les options suivantes peuvent
influer sur le processus :
id - ne rordonne que les noeuds sous ce noeud.
field - champ utiliser pour le tri, par dfaut le displayField du model.
order - ASC pour tri ascendant, DESC pour tri descendant.
verify - avec ou sans vrification avant tri.
$options est utilis pour passer tous les paramtres supplmentaires, et les cls suivantes par dfaut,
toutes sont facultatives :
array(
'id' => null,
'field' => $model->displayField,
'order' => 'ASC',
'verify' => true
)
TreeBehavior::verify()
Retourne True si larbre est valide sinon un tableau derreurs, avec des champs pour le type, lindex, et le
message derreur.
Chaque enregistrement dans le tableau de sortie est un tableau de la forme (type, id,message)
type est soit index ou node
id est lid du noeud erron.
message dpend de lerreur rencontre
Exemple dutilisation :
$this->Category->verify();
Exemple de sortie :
Array
(
[0] => Array
(
[0] =>
[1] =>
[2] =>
)
[1] => Array
(
[0] =>
[1] =>
[2] =>
)
532
"node"
3
"left and right values identical"
"node"
2
"The parent node 999 doesn't exist"
"index"
123
"missing"
"node"
163
"left greater than right"
TreeBehavior::getLevel($id)
Introduit dans la version 2.7.
Si vous ne mettez pas en cache le niveau des noeuds en utilisant loption level dans les configurations,
vous pouvez utiliser cette mthode pour rcuprer le niveau dun noeud en particulier.
Components (Composants)
CakePHP a une slection de components pour aider soccuper de tches basiques dans vos controllers. Regardez la section sur Components (Composants) pour savoir comment configurer et utiliser les components.
Components (Composants)
CakePHP a une slection de components pour aider soccuper de tches basiques dans vos controllers. Regardez la section sur Components (Composants) pour savoir comment configurer et utiliser les components.
Pagination
class PaginatorComponent(ComponentCollection $collection, array $settings = array())
Components (Composants)
533
Un des principaux obstacles la cration dune application flexible et ergonomique est le design et une interface utilisateur intuitive. De nombreuses applications ont tendance augmenter en taille et en complexit
rapidement, et les designers ainsi que les programmeurs trouvent mme quils sont incapables de faire face
a laffichage des centaines ou des milliers denregistrements. Rcrire prend du temps, et les performances
et la satisfaction des utilisateurs peut en ptir.
Afficher un nombre raisonnable denregistrements par page a toujours t une partie critique dans toutes les
applications et cause rgulirement de nombreux maux de tte aux dveloppeurs. CakePHP allge le fardeau
des dveloppeurs en fournissant un moyen rapide et facile de paginer les donnes.
La pagination dans CakePHP est offerte par un Component dans le controller, pour rendre la cration des
requtes de pagination plus facile. Dans la Vue, PaginatorHelper est utilis pour rendre la gnration
de la pagination, des liens et des boutons simples.
Paramtrage des requtes
Dans le controller, nous commenons par dfinir les conditions de la requte de pagination qui seront utilises par dfaut dans la variable $paginate du controller. Ces conditions, vont servir de base vos requtes de pagination. Elles sont compltes par le tri, la direction, la limitation et les paramtres de page
passs depuis lURL. Ici, il est important de noter que lordre des cls doit tre dfini dans une structure en
tableau comme ci-dessous :
class PostsController extends AppController {
public $components = array('Paginator');
public $paginate = array(
'limit' => 25,
'order' => array(
'Post.title' => 'asc'
)
);
}
Dautres cls qui peuvent tre introduites dans le tableau $paginate sont similaires aux paramtres
de la mthode Model->find(all), qui sont : conditions, fields, order, limit, page,
534
contain,joins, et recursive. En plus des touches mentionnes ci dessus, chacune des cls peut
aussi tre pass la mthode find du model. a devient alors trs simple dutiliser les component comme
ContainableBehavior avec la pagination :
class RecipesController extends AppController {
public $components = array('Paginator');
public $paginate = array(
'limit' => 25,
'contain' => array('Article')
);
}
En plus de dfinir des valeurs de pagination gnrales, vous pouvez dfinir plus dun jeu de pagination
par dfaut dans votre controller, vous avez juste nommer les cls du tableau daprs le model que vous
souhaitez configurer :
class PostsController extends AppController {
public $paginate = array(
'Post' => array (...),
'Author' => array (...)
);
}
Les valeurs des cls Post et Author pourraient contenir toutes les proprits quun model/cl sans
$paginate pourraient contenir.
Une fois que la variable $paginate t dfinie, nous pouvons utiliser la mthode paginate() du
PaginatorComponent de laction de notre controller. Ceci retournera les rsultats du find() depuis le
model. Il dfinit galement quelques paramtres de pagination supplmentaires, qui sont ajouts lobjet request. Linformation supplmentaire est dfinie dans $this->request->params[paging], et est
utilise par PaginatorHelper pour la cration des liens. PaginatorComponent::paginate()
ajoute aussi PaginatorHelper la liste des helpers dans votre controller, si il na pas dj t ajout :
public function list_recipes() {
$this->Paginator->settings = $this->paginate;
// similaire un findAll(), mais rcupre les rsultats pagins
$data = $this->Paginator->paginate('Recipe');
$this->set('data', $data);
}
Vous pouvez filtrer les enregistrements en passant des conditions en second paramtre la fonction
paginate() :
$data = $this->Paginator->paginate(
'Recipe',
array('Recipe.title LIKE' => 'a%')
);
Components (Composants)
535
Ou vous pouvez aussi dfinir des conditions et dautres tableaux de configuration de pagination lintrieur de votre action :
public function list_recipes() {
$this->Paginator->settings = array(
'conditions' => array('Recipe.title LIKE' => 'a%'),
'limit' => 10
);
$data = $this->Paginator->paginate('Recipe');
$this->set(compact('data'));
}
Si vous ntes pas prts utiliser les options standards du find pour crer la requte daffichage de vos
donnes, il y a quelques options. Vous pouvez utiliser custom find type. Vous pouvez aussi implmenter les
mthodes paginate() et paginateCount() sur votre model, ou les inclure dans un behavior attach
votre model. Les behaviors qui implmentent paginate et/ou paginateCount devraient implmenter
les signatures de mthode dfinies ci-dessous avec le premier paramtre normal supplmentaire de $model :
// paginate et paginateCount implments dans le behavior.
public function paginate(Model $model, $conditions, $fields, $order, $limit,
$page = 1, $recursive = null, $extra = array()) {
// contenu de la mthode
}
public function paginateCount(Model $model, $conditions = null,
$recursive = 0, $extra = array()) {
// corps (body) de la mthode
}
Cest rare davoir besoin dimplmenter paginate() et paginateCount(). vous devriez vous assurer que vous
ne pouvez pas atteindre votre but avec les mthodes du noyau du model, ou avec un finder personnalis.
Pour paginer avec un type de find personnalis, vous devez dfinir le 0me element, ou la cl findType
depuis la version 2.3 :
public $paginate = array(
'popular'
);
Puisque le 0me index est difficile grer, dans 2.3 loption findType a t ajoute :
public $paginate = array(
'findType' => 'popular'
);
La mthode paginate() devrait implmenter les signatures de mthode suivantes. Pour utiliser vos propres mthodes/logiques, surchargez les dans le model dans lequel vous voulez rcuprer des donnes :
536
/**
* Surcharge de la mthode paginate - groupe par week, away_team_id et home_team_id
*/
public function paginate($conditions, $fields, $order, $limit, $page = 1,
$recursive = null, $extra = array()) {
$recursive = -1;
$group = $fields = array('week', 'away_team_id', 'home_team_id');
return $this->find('all', compact('conditions', 'fields', 'order',
'limit', 'page', 'recursive', 'group'));
}
Vous aurez aussi besoin de surcharger le paginateCount() du noyau, cette mthode sattend aux mmes
arguments que Model::find(count). Lexemple ci-dessous utilise quelques fonctionnalits PostgreSQL spcifiques, Veuillez ajuster en consquence en fonction de la base de donnes que vous utilisez :
/**
* Surcharge de la mthode paginateCount
*/
public function paginateCount($conditions = null, $recursive = 0,
$extra = array()) {
$sql = "SELECT
DISTINCT ON(
week, home_team_id, away_team_id
)
week, home_team_id, away_team_id
FROM
games";
$this->recursive = $recursive;
$results = $this->query($sql);
return count($results);
}
Le lecteur attentif aura not que la mthode paginate que nous avons dfinie ntait pas rellement ncessaire
- Tout ce que vous avez faire est dajouter le mot cl dans la variable de classe $paginate du controller :
/**
* Ajout d'une clause GROUP BY
*/
public $paginate = array(
'MyModel' => array(
'limit' => 20,
'order' => array('week' => 'desc'),
'group' => array('week', 'home_team_id', 'away_team_id')
)
);
/**
* Ou la vole depuis l'intrieur de l'action
*/
public function index() {
$this->Paginator->settings = array(
'MyModel' => array(
'limit' => 20,
'order' => array('week' => 'desc'),
Components (Composants)
537
Dans CakePHP 2.0, vous navez plus besoin dimplmenter paginateCount() quand vous utilisez des
clauses de groupe. Le find(count) du groupe comptera correctement le nombre total de lignes.
Contrle du champ utiliser pour ordonner
Par dfaut le classement peut tre effectu pour nimporte quelle colonne dans un model. Cest parfois indsirable comme permettre aux utilisateurs de trier des colonnes non indexes, ou des champs
virtuels ce qui peut tre coteux en temps de calculs. Vous pouvez utiliser le 3me paramtre de
PaginatorComponent::paginate() pour restreindre les colonnes trier en faisant ceci :
$this->Paginator->paginate('Post', array(), array('title', 'slug'));
Ceci permettrait le tri uniquement sur les colonnes title et slug. Un utilisateur qui paramtre le tri dautres
valeurs sera ignor.
Limitation du nombre maximum de lignes qui peuvent tre recherches
Le nombre de rsultats qui sont retourns lutilisateur est reprsent par le paramtre limit. Il est
gnralement indsirable de permettre lutilisateur de retourner toutes les lignes dans un ensemble pagin. Par dfaut CAKEPHP limite le nombre de lignes retournes 100. Si cette valeur par dfaut nest pas
approprie pour votre application, vous pouvez lajuster dans une partie des options de pagination :
public $paginate = array(
// d'autre cls ici.
'maxLimit' => 10
);
Si le paramtre de limitation de la requte est suprieur cette valeur, il sera rduit la valeur de maxLimit.
Pagination avec des paramtres GET
Dans les versions prcdentes de CAKEPHP vous ne pouviez gnrer des liens de pagination quen utilisant des paramtres nomms. Mais si les pages taient recherches avec des paramtres GET elle continueraient fonctionner. Pour la version 2.0, nous avons dcids de rendre la faon de gnrer les paramtres
de pagination plus contrlable et plus cohrente. Vous pouvez choisir dutiliser une chane de requte ou
bien des paramtre nomms dans le component. Les requtes entrantes devront accepter le type choisi, et
PaginatorHelper gnrera les liens avec les paramtres choisis :
public $paginate = array(
'paramType' => 'querystring'
);
538
Ce qui est au-dessus permet un paramtre de recherche sous forme de chane de caractres, dtre pars et
dtre gnr. Vous pouvez aussi modifier les proprits de $settings du Component Paginator (PaginatorComponent) :
$this->Paginator->settings['paramType'] = 'querystring';
Par dfaut tous les paramtres de pagination typiques seront convertis en arguments GET.
Note : Vous pouvez rentrer dans une situation o assigner une valeur dans une proprit inexistante retournera des erreurs :
$this->paginate['limit'] = 10;
Retournera lerreur Notice : Indirect modification of overloaded property $paginate has no effect. (Notice : Une modification indirect dune surcharge de la proprit $paginate na aucun effet.). En assignant
une valeur initiale la proprit, cela rsout le problme :
$this->paginate = array();
$this->paginate['limit'] = 10;
//ou
$this->paginate = array('limit' => 10);
Depuis la version 2.3, PaginatorComponent va lancer une NotFoundException quand il essaiera daccder
une page qui nexiste pas, par ex le nombre de la page requte est plus grand que le total du nombre de
pages.
Ainsi vous pouvez soit laisser la page derreur normal tre rendu ou bien vous pouvez utiliser un block try
catch et renvoyer vers laction approprie quand une exception NotFoundException est attrape :
public function index() {
try {
$this->Paginator->paginate();
} catch (NotFoundException $e) {
//Faire quelque chose ici comme rediriger la premire ou dernire page.
//$this->request->params['paging'] va vous donner l'info ncessaire.
Components (Composants)
539
}
}
Pagination AJAX
Cest trs simple dincorporer les fonctionnalits AJAX dans la pagination. en utilisant JsHelper et
RequestHandlerComponent vous pouvez facilement ajouter des paginations AJAX votre application. Voir La Pagination AJAX pour plus dinformation.
Pagination dans la vue
Regardez la documentation du PaginatorHelper pour voir comment crer des liens de navigation pagins.
Flash
class FlashComponent(ComponentCollection $collection, array $config = array())
FlashComponent est un moyen de dfinir des messages de notifications afficher aprs avoir envoy un
formulaire ou des donnes connus. CakePHP appelle ces messages des messages flash. FlashComponent
crit les messages flash dans $_SESSION pour tre affichs dans une View en utilisant FlashHelper.
FlashComponent remplace la mthode setFlash() de SessionComponent et doit tre utilis la
place de cette mthode.
Dfinir les Messages Flash
FlashComponent fournit deux faons pour dfinir les messages flash : sa mthode magique __call et sa
mthode set().
Pour utiliser le gestionnaire de message flash par dfaut, vous pouvez utiliser la mthode set() :
$this->Flash->set('Ceci est un message');
Pour crer des elements Flash personnaliss, la mthode magique __call de FlashComponent vous
permet dutiliser un nom de mthode qui est li un element qui se trouve dans le rpertoire
app/View/Elements/Flash. Par convention, les mthodes en camelcase vont tre lies un nom
delement en minuscule et avec des underscores (_) :
// Utilise app/View/Elements/Flash/success.ctp
$this->Flash->success('C\'tait un succs');
// Utilise app/View/Elements/Flash/great_success.ctp
$this->Flash->greatSuccess('C\'tait un grand succs');
key Par dfaut flash. La cl du tableau trouv sous la cl Flash dans la session.
element Par dfaut null, mais il va automatiquement tre dfini lors de lutilisation de la mthode
magique __call. Le nom delement utiliser pour le rendu.
params Un tableau en option de cls/valeurs pour rendre disponible des variables dans un element.
Un exemple de lutilisation de ces options :
// Dans votre Controller
$this->Flash->success('The user has been saved', array(
'key' => 'positive',
'params' => array(
'name' => $user['User']['name'],
'email' => $user['User']['email']
)
));
// Dans votre Vue
<?php echo $this->Flash->render('positive') ?>
Si vous utilisez la mthode magique __call(), loption element sera toujours remplace. Afin de
rcuprer un element spcifique dun plugin, vous devez dfinir le paramtre plugin. Par exemple :
// Dans votre Controller
$this->Flash->warning('My message', array('plugin' => 'PluginName'));
Components (Composants)
541
Le component Session est utilis pour interagir avec les informations de session. Il inclut les fonctions
CRUD basiques, mais aussi des fonctionnalits pour crer des messages de feedback aux utilisateurs.
Il est important de noter que ces structures en tableaux peuvent tre cres dans la session en utilisant la
notation avec points. Par exemple, User.username se rfrera au tableau suivant
array('User' =>
array('username' => 'clark-kent@dailyplanet.com')
);
Les points sont utiliss pour indiquer les tableaux imbriqus. Cette notation est utilise pour toutes les
mthodes du component Session quelques soient le nom/la cl utilis.
SessionComponent::write($name, $value)
crit dans la Session, en mettant $value dans $name. $name peut-tre un tableau spar par un point.
Par exemple
$this->Session->write('Person.eyeColor', 'Green');
Cela crit la valeur Green dans la session sous Person => eyeColor.
SessionComponent::read($name)
Retourne la valeur de $name dans la Session. Si $name vaut null, la session entire sera retourne.
Par ex
$green = $this->Session->read('Person.eyeColor');
SessionComponent::destroy()
La mthode destroy supprimera le cookie de session et toutes les donnes de session stockes dans
le fichier temporaire du systme. Cela va dtruire la session PHP et ainsi en crer une nouvelle. :
542
$this->Session->destroy();
Ceci crera un message instantan qui peut tre affich lutilisateur, en utilisant le Helper Session
SessionHelper :
// Dans la vue.
echo $this->Session->flash();
// Ce qui gnrera en sortie.
<div id="flashMessage" class="message">
Votre travail a t sauvegard !
</div>
Vous pouvez utiliser des paramtres supplmentaires de setFlash() pour crer diffrentes sortes
de messages flash. Par exemple, les erreurs et les notifications positives peuvent avoir des apparences
diffrentes. CakePHP vous donne un moyen de le faire. En utilisant le paramtre $key vous pouvez
stocker diffrents messages, qui peuvent tre sparment rcuprer en sortie.
// dfinit le message que ca va mal
$this->Session->setFlash('Ca va mal.', 'default', array(), 'mal');
// dfinit le message que ca va bien
$this->Session->setFlash('Ca va bien', 'default', array(), 'bien');
Components (Composants)
543
Ensuite nous crons le fichier app/View/Elements/flash_custom.ctp et crons notre lment flash personnalis :
<div id="myCustomFlash"><?php echo h($message); ?></div>
$params vous permet de passer des variables de vue supplmentaires au layout de rendu.
Les paramtres peuvent tre passs en affectant la div de rendu, par exemple en ajoutant
class dans le tableau $params qui appliquera une classe la div de sortie en utilisant
$this->Session->flash() dans votre layout ou vue.
$this->Session->setFlash(
'Message Exemple',
'default',
array('class' => 'classe_exemple')
);
Note : Par dfaut, CakePHP nchappe pas le HTML des messages flash. Si vous utilisez une requte
ou une donne dutilisateur dans vos messages flash, vous devrez les chapper avec h quand vous
formatez vos messages.
Authentification
class AuthComponent(ComponentCollection $collection, array $settings = array())
Identifier, authentifier et autoriser des utilisateurs constitue une partie courante de nombreuses applications
Web. Le component Auth de CakePHP fournit un moyen modulaire daccomplir cette tche. Le component
Auth vous permet de combiner lauthentification des objets, lautorisation des objets pour crer un moyen
souple pour permettre lidentification et le contrle des autorisations de lutilisateur.
Lectures Suggres Avant de Continuer
La Configuration de lauthentification ncessite quelques tapes, notamment la dfinition dune table users,
la cration dun model, du controller et des vues, etc..
Tout ceci est couvert tape par tape dans le Blog Tutorial.
544
Authentification
Lauthentification est le processus didentification des utilisateurs par des identifiants de connexion dfinis
et permet de sassurer que lutilisateur est bien celui quil prtend tre. En gnral, cela se fait travers un
nom dutilisateur et un mot de passe, qui sont compars une liste dutilisateurs connus. Dans CakePHP, il
y a plusieurs faons intgres pour lauthentification des utilisateurs enregistrs dans votre application.
FormAuthenticate vous permet dauthentifier les utilisateurs sur la base de formulaire de donne
POST. Habituellement il sagit dun formulaire de connexion ou les utilisateurs entrent des informations.
BasicAuthenticate vous permet didentifier les utilisateurs en utilisant lauthentification Basic
HTTP.
DigestAuthenticate vous permet didentifier les utilisateurs en utilisant lauthentification Digest
HTTP.
Par dfaut Le component Auth (AutComponent) utilise FormAuthenticate.
Choisir un type dAuthentification En gnral, vous aurez envie doffrir lauthentification par formulaire. Cest le plus facile pour les utilisateurs utilisant un navigateur Web. Si vous construisez une API ou un
service web, vous aurez peut-tre envisager lutilisation de lauthentification de base ou lauthentification
Digest. Llment cl qui diffrencie lauthentification digest de lauthentification basic est la plupart du
temps lie la faon dont les mots de passe sont grs. Avec lauthentification basic, le nom dutilisateur
et le mot de passe sont transmis en clair sur le serveur. Cela rend lauthentification de base non approprie
pour des applications sans SSL, puisque vous exposeriez sensiblement vos mots de passe. Lauthentification
Digest utilise un hachage condens du nom dutilisateur, mot de passe, et quelques autres dtails. Cela rend
lauthentification Digest plus appropri pour des applications sans cryptage SSL.
Vous pouvez galement utiliser des systmes dauthentification comme OpenID, mais openid ne fait pas
parti du cur de CakePHP.
Configuration des gestionnaires dauthentification Vous configurez les gestionnaires dauthentification
en utilisant $this->Auth->authenticate. Vous pouvez configurer un ou plusieurs gestionnaires
pour lauthentification. Lutilisation de plusieurs gestionnaires dauthentification vous permet de supporter
les diffrentes mthodes de connexion des utilisateurs. Quand les utilisateurs se connectent, les gestionnaires dauthentification sont utiliss dans lordre auquel ils ont t dclars. Une fois quun gestionnaire est
capable didentifier un utilisateur, les autres gestionnaires ne seront pas utiliss. Inversement, vous pouvez
mettre un terme tous les authentifications en levant une exception.Vous pourrez traiter toutes les exceptions
leves, et les grer comme dsir.
Vous pouvez configurer le gestionnaire dauthentification dans les tableaux beforeFilter ou
$components. Vous pouvez passer linformation de configuration dans chaque objet dauthentification
en utilisant un tableau :
// Configuration de base
$this->Auth->authenticate = array('Form');
// Passer la configuration
$this->Auth->authenticate = array(
'Basic' => array('userModel' => 'Membre'),
'Form' => array('userModel' => 'Membre')
);
Components (Composants)
545
Dans le deuxime exemple vous pourrez noter que nous avons dclarer la cl userModel deux fois.
Pour vous aider garder un code propre, vous pouvez utiliser la cl all. Cette cl spciale vous permet
de dfinir les rglages qui sont passs chaque objet attach. La cle all est aussi utilise comme cela
AuthComponent::ALL :
// Passer la configuration en utilisant 'all'
$this->Auth->authenticate = array(
AuthComponent::ALL => array('userModel' => 'Membre'),
'Basic',
'Form'
);
Dans lexemple ci-dessus, la fois Form et Basic prendront les paramtrages dfinis dans la cl all.
Tous les paramtres transmis un objet dauthentification particulier remplaceront la cl correspondante
dans la cl all. Les objets dauthentification supportent les cls de configuration suivante.
fields Les champs utiliser pour identifier un utilisateur.
userModel Le nom du model de lutilisateur, par dfaut User.
scope Des conditions supplmentaires utiliser lors de la recherche et lauthentification des utilisateurs,
ex array(User.is_active => 1).
contain options de Containable lorsque lenregistrement de lutilisateur est charg. Si vous souhaitez
utiliser cette option, vous devrez vous assurer que votre model a le behavior Containable attach.
Introduit dans la version 2.2.
passwordHasher Classe de hash de mot de passe. Par dfaut Simple.
Introduit dans la version 2.4.
userFields La liste des champs rcuprer depuis le userModel. Cette option est utile lorsque vous
avez une large table dutilisateurs et que vous navez pas besoin de toutes les colonnes dans la session.
Par dfaut tous les champs sont rcuprs.
Introduit dans la version 2.6.
Configurer diffrents champs pour lutilisateur dans le tableau $components :
// Passer la configuration dans le tableau $components
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
)
)
)
);
Ne mettez pas dautre cls de configuration de Auth(comme authError, loginAction etc). Ils doivent se
trouver au mme niveau que la cl dauthentification. La configuration ci-dessus avec dautres configurations
ressemblerait quelque chose comme.
// Passage de paramtre dans le tableau $components
public $components = array(
'Auth' => array(
'loginAction' => array(
'controller' => 'users',
'action' => 'login',
'plugin' => 'users'
546
),
'authError' => 'Pensiez-vous rellement que vous tiez autoriss voir cela ?',
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'mon_champ_username_personnalise', // 'username' par dfa
'password' => 'mon_champ_password_personnalise' // 'password' par dfa
)
)
)
)
);
En plus de la configuration courante, lauthentification de base prend en charge les cls suivantes :
realm Le domaine en cours dauthentification. Par dfaut env(SERVER_NAME).
En plus de la configuration courante, lauthentification Digest prend en charge les cls suivantes :
realm Le domaine en cours dauthentification. Par dfaut servername
nonce Un nonce utiliser pour lauthentification. Par dfaut uniqid().
qop Par dfaut auth, pas dautre valeur supporte pour le moment.
opaque Une chane qui doit tre retourn lidentique par les clients. Par Dfaut
md5($settings[realm]).
Identifier les utilisateurs et les connecter Par le pass le component Auth AuthComponent connectait
les utilisateurs automatiquement. Ctait un peu droutant pour certain, et rendait la cration au travers du
component Auth AuthComponent par moment un peu difficile. Avec la version 2.0, vous avez besoin
dappeler manuellement $this->Auth->login() pour connecter un utilisateur.
Quand les utilisateurs sidentifient, les objets didentification sont vrifis dans lordre o ils ont t attachs.
Une fois quun objet peut identifier un utilisateur, les autres objets ne sont pas vrifis. Une simple fonction
de connexion pourrait ressembler cela
public function login() {
if ($this->request->is('post')) {
// Important: Utilisez login() sans argument! Voir warning ci-dessous.
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
// Avant 2.3, utilisez
// `return $this->redirect($this->Auth->redirect());`
}
$this->Flash->error(
__('Username ou password incorrect')
);
// Avant 2.7, utilisez
// $this->Session->setFlash(__('Username ou password incorrect'));
}
}
Le code ci-dessus (sans aucune donne transmise la mthode login), tentera de connecter un utilisateur en utilisant les donnes POST, et sera redirig en cas de succs sur la dernire page visite, ou
AuthComponent::$loginRedirect. Si le login est en chec, un message flash est dfini.
Components (Composants)
547
Utilisation de lauthentification Digest et Basic pour la connexion Puisque les authentifications basic
et digest ne ncessitent pas un POST initial ou un form, ainsi si vous utilisez seulement les authentificators basic / digest, vous navez pas besoin daction login dans votre controller. Aussi, vous pouvez dfinir
AuthComponent::$sessionKey false pour vous assurer que AuthComponent nessaie pas de lire les
infos de luser partir des sessions. Lauthentification stateless va re-vrifier les certificats de luser chaque
requte, cela cre un petit montant de charges supplmentaires, mais permet aux clients de se connecter sans
utiliser les cookies.
Note : Avant 2.4, vous avez toujours besoin de laction login puisque vous tes redirigs vers login quand
un user non authentifi essaie daccder une page protge mme en utilisant seulement lauth basic ou
digest. Aussi configurer AuthComponent::$sessionKey false va causer une erreur avant 2.4.
Crer des objets dauthentification personnaliss Comme les objets dauthentification sont
modulaires, vous pouvez crer des objets dauthentification personnaliss pour votre application ou plugins. Si par exemple vous vouliez crer un objet dauthentification OpenID. Dans
app/Controller/Component/Auth/OpenidAuthenticate.php vous pourriez mettre ce qui
suit :
App::uses('BaseAuthenticate', 'Controller/Component/Auth');
class OpenidAuthenticate extends BaseAuthenticate {
public function authenticate(CakeRequest $request, CakeResponse $response) {
// Faire les trucs d'OpenID ici.
// Retourne un tableau de l\'user si ils peuvent authentifier
// l\'user
// retourne false dans le cas contraire
}
}
Les objets dauthentification devraient retourner false si ils ne peuvent identifier lutilisateur. Et un tableau
dinformation utilisateur si ils le peuvent.Il nest pas utile dtendre (extend) BaseAuthenticate,
simplement votre objet didentification doit implmenter la mthode authenticate(). La class
BaseAuthenticate fournie un nombre de mthode trs utiles communment utilises. Vous pouvez
aussi implmenter une mthode getUser() si votre objet didentification doit supporter des authentifications sans cookie ou sans tat (stateless). Regardez les sections portant sur lauthentification digest et basic
plus bas pour plus dinformation.
Utilisation dobjets dauthentification personnaliss Une fois votre objet dauthentification crer, vous
pouvez les utiliser en les incluant dans le tableau dauthentification AuthComponents :
548
$this->Auth->authenticate = array(
'Openid', // objet d'authentification app
'AuthBag.Combo', // plugin objet d'identification.
);
Cration de systmes dauthentification stateless Les objets dauthentification peuvent implmenter une
mthode getUser() qui peut tre utilise pour supporter les systmes de connexion des utilisateurs qui
ne reposent pas sur les cookies. Une mthode getUser typique regarde lenvironnement de la requte (request/environnement) et y utilise les informations didentification de lutilisateur. Lauthentification HTTP
Basic utilise par exemple $_SERVER[PHP_AUTH_USER] et $_SERVER[PHP_AUTH_PW] pour
les champs username et password. Pour chaque requte, si un client ne supporte pas les cookies, ces valeurs
sont utilises pour r-identifier lutilisateur et sassurer que cest un utilisateur valide. Comme avec les
mthodes dauthentification de lobjet authenticate(), la mthode getuser() devrait retourner un
tableau dinformation utilisateur en cas de succs, et false en cas dechec.
public function getUser($request) {
$username = env('PHP_AUTH_USER');
$pass = env('PHP_AUTH_PW');
if (empty($username) || empty($pass)) {
return false;
}
return $this->_findUser($username, $pass);
}
Le contenu ci-dessus montre comment vous pourriez mettre en uvre la mthode getUser pour les authentifications HTTP Basic. La mthode _findUser() fait partie de BaseAuthenticate et identifie un
utilisateur en se basant sur un nom dutilisateur et un mot de passe.
Gestion des requtes non authentifies Quand un user non authentifi essaie daccder une page protge en premier, la mthode unauthenticated() du dernier authenticator dans la chane est appele. Lobjet
dauthentification peut grer la rponse denvoi ou la redirection approprie et retourne true pour indiquer
quaucune action suivante nest ncessaire. Du fait de lordre dans lequel vous spcifiez lobjet dauthentification dans les proprits de AuthComponent : :$authenticate.
Si authenticator retourne null, AuthComponent redirige luser vers laction login. Si cest une requte ajax
et AuthComponent : :$ajaxLogin est spcifie, cet element est rendu, sinon un code de statut HTTP 403 est
retourn.
Note : Avant 2.4, les objets dauthentification ne fournissent pas de mthode unauthenticated().
Afficher les messages flash de Auth Pour afficher les messages derreur de session que Auth gnre,
vous devez ajouter les lignes de code suivante dans votre layout. Ajoutez les deux lignes suivantes au
fichier app/View/Layouts/default.ctp dans la section body de prfrence avant la ligne content_for_layout :
Components (Composants)
549
// CakePHP 2.7+
echo $this->Flash->render();
echo $this->Flash->render('auth');
// Avant 2.7
echo $this->Session->flash();
echo $this->Session->flash('auth');
Vous pouvez personnaliser les messages derreur, et les rglages que le component Auth AuthComponent
utilise. En utilisant $this->Auth->flash vous pouvez configurer les paramtres que le component
Auth utilise pour envoyer des messages flash. Les cls disponibles sont :
element - Llment utiliser , default par dfaut.
key - La cl a utiliser , auth par dfaut
params - Le tableau des paramtres additionnels utiliser, array() par dfaut
En plus des paramtres de message flash, vous pouvez personnaliser dautres messages derreurs que le
component AuthComponent utilise. Dans la partie beforeFilter de votre controller, ou dans le paramtrage du
component vous pouvez utiliser authError pour personnaliser lerreur utiliser quand lauthentification
choue
Modifi dans la version 2.4 : Parfois, vous voulez seulement afficher lerreur dautorisation aprs que luser
se soit dja connect. Vous pouvez supprimer ce message en configurant sa valeur avec le bolen false.
Dans le beforeFilter() de votre controller, ou les configurations du component :
if (!$this->Auth->loggedIn()) {
$this->Auth->authError = false;
}
Hachage des mots de passe Le component Auth ne fait fait plus automatiquement le hachage de tous
les mots de passe quil rencontre. Ceci t enlev parce quil rendait un certain nombre de tches communes comme la validation difficile. Vous ne devriez jamais stocker un mot de passe en clair, et avant de
sauvegarder un utilisateur vous devez toujours hacher le mot de passe.
Depuis 2.4, la gnration et la vrification des hashs de mot de passe a t dlgue des classes de hasher de
mot de passe. Les objets dauthentification utilisent un nouveau paramtre passwordHasher qui spcifie
la classe de hasher de mot de passe utiliser. Cela peut tre une chane en spcifiant un nom de classe ou
un tableau avec la cl className faisant tat du nom de la classe et toutes autres cls supplmentaires
seront passes au constructeur de hasher de mot de passe en configuration. Le classe de hasher par dfaut
Simple peut tre utilise pour le hashage sha1, sha256, md5. Par dfaut, le type de hash dfini dans la
classe Security sera utilis. Vous pouvez utiliser un type de hash spcifique comme ceci :
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'passwordHasher' => array(
'className' => 'Simple',
'hashType' => 'sha256'
550
)
)
)
)
);
Lors de la cration de nouveaux enregistrements dutilisateurs, vous pouvez hasher un mot de passe dans le
callback beforeSave de votre model en utilisant la classe de hasher de mot de passe approprie :
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public function beforeSave($options = array()) {
if (!empty($this->data[$this->alias]['password'])) {
$passwordHasher = new SimplePasswordHasher(array('hashType' => 'sha256'));
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}
}
Vous navez pas besoin de hacher le mot de passe avant dappeler $this->Auth->login(). Les diffrents objets dauthentification hacherons les mots de passe individuellement.
Utiliser bcrypt pour les mots de passe Dans CakePHP 2.3, la classe BlowfishAuthenticate a t
introduite pour permettre lutilisation de bcrypt 8 cest--dire Blowfish pour les mots de passe hashs. Les
hashes Bcrypt sont plus difficiles forcer sauvagement par rapport aux mots de passe stocks avec sha1.
Mais BlowfishAuthenticate a t dprci dans 2.4 et la place BlowfishPasswordHasher a
t ajoute.
Un hasher de mot de passe blowfish peut tre utilis avec toute classe dauthentification. Tout ce que vous
avez faire est de spcifier la configuration passwordHasher pour lobjet dauthentification :
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'passwordHasher' => 'Blowfish'
)
)
)
);
Hachage de mots de passe pour lauthentification Digest Puisque lauthentification Digest ncessite
un mot de passe hach dans un format dfini par la RFC. Respectivement pour hacher correctement
un mot de passe pour lutilisation de lauthentification Digest vous devriez utilisez la fonction spciale
8. https ://en.wikipedia.org/wiki/Bcrypt
Components (Composants)
551
DigestAuthenticate. Si vous vous apprtez combiner lauthentification Digest avec dautres stratgies dauthentifications, il est aussi recommand de stocker le mot de passe Digest dans une colonne spare,
pour le hachage normal de mot de passe :
App::uses('DigestAuthenticate', 'Controller/Component/Auth');
Les mots de passe pour lauthentification Digest ont besoin dun peu plus dinformation que pour dautres
mots de passe hachs. Si vous utilisez le component AuthComponent : :password() pour le hachage Digest
vous ne pourrez pas vous connecter.
Note : le troisime paramtre de DigestAuthenticate : :password() doit correspondre la valeur de la configuration realm dfinie quand DigestAuthentication tait configur dans AuthComponent : :$authenticate.
Par dfaut env(SCRIPT_NAME). Vous devez utiliser une chane statique si vous voulez un hachage
permanent dans des environnements multiples.
Cration
de
classes
de
hachage
de
mots
de
passe
personnalises Les
classes de hachage de mots de passe personnalises doivent tendre la classe
AbstractPasswordHasher et implmenter les mthodes abstraites hash() et check(). Dans
app/Controller/Component/Auth/CustomPasswordHasher.php, vous pourriez mettre
ceci :
App::uses('AbstractPasswordHasher', 'Controller/Component/Auth');
class CustomPasswordHasher extends AbstractPasswordHasher {
public function hash($password) {
// choses ici
}
public function check($password, $hashedPassword) {
// choses ici
}
}
Connecter les utilisateurs manuellement Parfois, le besoin se fait sentir de connecter un utilisateur
manuellement, par exemple juste aprs quil se soit enregistr dans votre application. Vous pouvez faire
cela en appelant $this->Auth->login() avec les donnes utilisateur que vous voulez pour la connexion :
552
Accder lutilisateur connect Une fois que lutilisateur est connect, vous avez souvent besoin dinformations particulires propos de lutilisateur courant. Vous pouvez accder ce dernier en utilisant
AuthComponent::user(). Cette mthode est statique, et peut tre utilise globalement aprs le chargement du component Auth. Vous pouvez y accder la fois avec une mthode dinstance ou une mthode
statique :
// Utilisez n'importe o
AuthComponent::user('id')
// Depuis l'intrieur du controler
$this->Auth->user('id');
Dconnexion des utilisateurs ventuellement vous aurez besoin dun moyen rapide pour ds-authentifier
les utilisateurs et les rediriger o ils devraient aller. Cette mthode est aussi trs pratique si vous voulez
fournir un lien Dconnecte-moi lintrieur de la zone membres de votre application :
public function logout() {
$this->redirect($this->Auth->logout());
}
La dconnexion des utilisateurs connects avec lauthentification Basic ou Digest est difficile accomplir
pour tous les clients. La plupart des navigateurs retiennent les autorisations pendant quil restent ouvert. Certains navigateurs peuvent tre forcs en envoyant un code 401. Le changement du realm de lauthentification
est une autre solution qui fonctionne pour certain clients.
Components (Composants)
553
Autorisation
Lautorisation est le processus qui permet de sassurer quun utilisateur identifi/authentifi est autoris
accder aux ressources quil demande. Sil est activ, AuthComponent peut vrifier automatiquement
des gestionnaires dautorisations et veiller ce que les utilisateurs connects soient autoriss accder aux
ressources quils demandent. Il y a plusieurs gestionnaires dautorisations intgrs, et vous pouvez crer vos
propres gestionnaires dans un plugin par exemple.
ActionsAuthorize Utilise le Component AclComponent pour vrifier les permissions dun niveau
daction.
CrudAuthorize Utilise le Component Acl et les action -> CRUD mappings pour vrifier les permissions pour les ressources.
ControllerAuthorize appelle isAuthorized() sur le controller actif, et utilise ce retour pour
autoriser un utilisateur. Cest souvent le moyen le plus simple dautoriser les utilisateurs.
Configurer les gestionnaires dautorisation Vous configurez les gestionnaires dautorisations via
$this->Auth->authorize. Vous pouvez configurer un ou plusieurs gestionnaires. Lutilisation de
plusieurs gestionnaires vous donne la possibilit dutiliser plusieurs moyens de vrifier les autorisations.
Quand les gestionnaires dautorisation sont vrifis, ils sont appels dans lordre dans lequel ils sont dclars.
Les gestionnaires devraient retourner false sils ne sont pas capables de vrifier les autorisations, ou bien
si la vrification a chou. Ils devraient retourner true sils sont capables de vrifier correctement les autorisations. Les gestionnaires seront appels dans lordre jusqu ce que lun dentre eux retourne true. Si
toutes les vrifications chouent, lutilisateur sera redirig vers la page do il vient. Vous pouvez galement
stopper les autorisations en levant une exception. Vous aurez besoin de traiter toutes les exceptions leves,
et de les manipuler.
Vous pouvez configurer les gestionnaires dautorisations dans le beforeFilter de votre controller ou
dans le tableau $components. Vous pouvez passer les informations de configuration dans chaque objet
dautorisation, en utilisant un tableau :
// paramtrage Basique
$this->Auth->authorize = array('Controller');
// passage de paramtre
$this->Auth->authorize = array(
'Actions' => array('actionPath' => 'controllers/'),
'Controller'
);
554
Dans lexemple ci-dessus, la fois lAction et le Controller auront les paramtres dfinis pour la cl
all. Chaque paramtre pass un objet dautorisation spcifique remplacera la cl correspondante dans la
cl all. Le noyau authorize objects supporte les cls de configuration suivantes.
actionPath Utilis par ActionsAuthorize pour localiser le controller action ACOs dans larborescence ACO.
actionMap Action -> CRUD mappings. Utilis par CrudAuthorize et les objets dautorisation qui
veulent mapper les actions aux rles CRUD.
userModel Le nom du nud ARO/Model dans lequel linformation utilisateur peut tre trouv. Utilis
avec ActionsAuthorize.
Cration dobjets Authorize personnaliss Parce que les objets authorize sont modulables, vous pouvez
crer des objets authorize personnaliss dans votre application, ou plugins. Si par exemple vous voulez crer
un objet authorize LDAP. Dans app/Controller/Component/Auth/LdapAuthorize.php,
vous pourriez mettre cela :
App::uses('BaseAuthorize', 'Controller/Component/Auth');
class LdapAuthorize extends BaseAuthorize {
public function authorize($user, CakeRequest $request) {
// Faire les trucs pour le LDAP ici.
}
}
Lobjet Authorize devrait retourner false si lutilisateur se voit refuser laccs, ou si lobjet est incapable
de faire un contrle. Si lobjet est capable de vrifier les accs de lutilisateur, true devrait tre retourn. a
nest pas ncessaire dtendre BaseAuthorize, il faut simplement que votre objet authorize implmente
la mthode authorize(). La classe BaseAuthorize fournit un nombre intressant de mthodes utiles
qui sont communment utilises.
Utilisation dobjets Authorize personnaliss Une fois que vous avez cr votre objet authorize personnalis, vous pouvez lutiliser en lincluant dans le tableau authorize :
$this->Auth->authorize = array(
'Ldap', // objet app authorize .
'AuthBag.Combo', // objet authorize du plugin.
);
Ne pas utiliser dautorisation Si vous souhaitez ne pas utiliser les objets dautorisation intgrs, et
que vous voulez grer les choses entirement lextrieur du Component Auth (AuthComponent) vous
pouvez dfinir $this->Auth->authorize = false;. Par dfaut le component Auth dmarre avec
authorize = false. Si vous nutilisez pas de schma dautorisation, assurez-vous de vrifier les autorisations vous-mme dans la partie beforeFilter de votre controller ou avec un autre component.
Rendre des actions publiques Il y a souvent des actions de controller que vous souhaitez laisser entirement publiques, ou qui ne ncessitent pas de connexion utilisateur. Le component Auth (AuthComponnent)
est pessimiste, et par dfaut interdit laccs. Vous pouvez marquer des actions comme publique en utilisant
Components (Composants)
555
Avertissement : Si vous utilisez le scaffolding, permettre tout ne va identifier et autoriser les mthodes
scaffoldes. Vous devez spcifier les noms des actions.
Vous pouvez fournir autant de nom daction dont vous avez besoin allow(). Vous pouvez aussi fournir
un tableau contenant tous les noms daction.
Fabriquer des actions qui requirent des autorisations Par dfaut, toutes les actions ncessitent une
authorisation. Cependant, si aprs avoir rendu les actions publiques, vous voulez rvoquer les accs publics.
Vous pouvez le faire en utilisant AuthComponent::deny() :
// retire une action
$this->Auth->deny('add');
// retire toutes les actions .
$this->Auth->deny();
// retire un groupe d'actions.
$this->Auth->deny('add', 'edit');
$this->Auth->deny(array('add', 'edit'));
Vous pouvez fournir autant de noms daction que vous voulez deny(). Vous pouvez aussi fournir un
tableau contenant tous les noms daction.
Utilisation de ControllerAuthorize ControllerAuthorize vous permet de grer les vrifications dautorisation dans le callback dun controller. Cest parfait quand vous avez des autorisations trs simples, ou que
vous voulez utiliser une combinaison models + components faire pour vos autorisations, et ne voulez pas
crer un objet authorize personnalis.
Le callback est toujours appel isAuthorized() et devrait retourner un boolen pour indiquer si lutilisateur est autoris ou pas accder aux ressources de la requte. Le callback est pass lutilisateur actif,
il peut donc tre vrifi :
class AppController extends Controller {
public $components = array(
'Auth' => array('authorize' => 'Controller'),
556
);
public function isAuthorized($user = null) {
// Chacun des utilisateur enregistr peut accder aux fonctions publiques
if (empty($this->request->params['admin'])) {
return true;
}
// Seulement les administrateurs peuvent accder aux fonctions d'administration
if (isset($this->request->params['admin'])) {
return (bool)($user['role'] === 'admin');
}
// Par dfaut n'autorise pas
return false;
}
}
Le callback ci-dessus fournirait un systme dautorisation trs simple o seuls les utilisateurs ayant le rle
dadministrateur pourraient accder aux actions qui ont le prfixe admin.
Utilisation de ActionsAuthorize ActionsAuthorize sintgre au component ACL, et fournit une vrification ACL trs fine pour chaque requte. ActionsAuthorize est souvent jumel avec DbAcl pour apporter un
systme de permissions dynamique et flexible qui peuvent tre dites par les utilisateurs administrateurs au
travers de lapplication. Il peut en outre tre combin avec dautres implmentations Acl comme IniAcl et
des applications Acl backends personnalises.
Utilisation de CrudAuthorize CrudAuthorize sintgre au component Acl, et fournit la possibilit
de mapper les requtes aux oprations CRUD. Fournit la possibilit dautoriser lutilisation du mapping
CRUD. Les rsultats mapps sont alors vrifis dans le component Acl comme des permissions spcifiques.
Par exemple, en prenant la requte /posts/index. Le mapping par dfaut pour index est une vrification de la permission de read. La vrification dAcl se ferait alors avec les permissions de read pour le
controller posts. Ceci vous permet de crer un systme de permission qui met davantage laccent sur ce
qui est en train dtre fait aux ressources, plutt que sur laction spcifique en cours de visite.
Mapper les actions en utilisant CrudAuthorize Quand vous utilisez CrudAuthorize ou dautres objets
authorize qui utilisent le mapping daction, il peut tre ncessaire de mapper des mthodes supplmentaires.
vous pouvez mapper des actions > CRUD permissions en utilisant mapAction(). En lappelant dans le
component Auth vous dlguerez toutes les actions aux objets authorize configurs, ainsi vous pouvez tre
sr que le paramtrage sera appliqu partout :
$this->Auth->mapActions(array(
'create' => array('register'),
'view' => array('show', 'display')
));
La cl pour mapActions devra tre les permissions CRUD que vous voulez dfinir, tandis que les valeurs
devront tre un tableau de toutes les actions qui sont mappes vers les permissions CRUD.
Components (Composants)
557
API de AuthComponent
Le component Auth est linterface primaire la construction de mcanisme dautorisation et dauthentification intgre dans CakePHP.
property AuthComponent::$ajaxLogin
Le nom dune vue optionnelle dun lment rendre quand une requte AJAX est faite avec une
session expire invalide.
property AuthComponent::$authenticate
Dfini comme un tableau dobjets didentifications que vous voulez utiliser quand les utilisateurs de
connectent. Il y a plusieurs objets dauthentification dans le noyau, cf la section Lectures Suggres
Avant de Continuer
property AuthComponent::$authError
Erreur afficher quand les utilisateurs font une tentative daccs un objet ou une action laquelle
ils nont pas accs.
Modifi dans la version 2.4 : You can suppress authError message from being displayed by setting
this value to boolean false.
property AuthComponent::$authorize
Dfini comme un tableau dobjets dautorisation que vous voulez utiliser quand les utilisateurs sont
autoriss sur chaque requte, cf la section Autorisation
property AuthComponent::$components
Dautre components utiliss par le component Auth.
property AuthComponent::$flash
Paramtrage utiliser quand Auth besoin de faire un message
FlashComponent::set(). Les cls disponibles sont :
element - Llment utiliser , par dfaut default.
key - La cl utiliser, par dfaut auth.
params - Un tableau de paramtres supplmentaires utiliser par dfaut array()
flash
avec
property AuthComponent::$loginAction
Une URL (dfinie comme une chane de caractres ou un tableau) pour laction du controller qui gre
les connexions. Par dfaut /users/login.
property AuthComponent::$loginRedirect
L URL (dfinie comme une chane de caractres ou un tableau) pour laction du controller o les
utilisateurs doivent tre redirigs aprs la connexion. Cette valeur sera ignore si lutilisateur une
valeur Auth.redirect dans sa session.
property AuthComponent::$logoutRedirect
Laction par dfaut pour rediriger lutilisateur quand il se dconnecte. Alors que le component Auth ne gre pas les redirection post-logout, une URL de redirection sera retourne depuis
AuthComponent::logout(). Par dfaut AuthComponent::$loginAction.
property AuthComponent::$unauthorizedRedirect
Contrle la gestion des accs non autoriss. Par dfaut, un utilisateur non autoris est redirig vers
lURL rfrente ou vers AuthComponent::$loginRedirect ou /. Si dfini false, une exception ForbiddenException est lance au lieu de la redirection.
558
property AuthComponent::$request
Objet Requte
property AuthComponent::$response
Objet Rponse
property AuthComponent::$sessionKey
Le nom de la cl de session o les enregistrements de lutilisateur actuel sont enregistrs. Si a nest
pas spcifi, ce sera Auth.User.
AuthComponent::allow($action[, $action, ... ])
Dfinit une ou plusieurs actions comme publiques, cela signifie quaucun contrle dautorisation ne
sera effectu pour les actions spcifies. La valeur spciale * marquera les actions du controller
actuelle comme publique. Sera mieux utilis dans la mthode beforeFilter de votre controller.
AuthComponent::constructAuthenticate()
Charge les objets dauthentification configurs.
AuthComponent::constructAuthorize()
Charge les objets dautorisation configurs.
AuthComponent::deny($action[, $action, ... ])
Basculer une ou plusieurs actions prcdemment dclares comme publique en mthodes non
publiques. Ces mthodes requirent une authorization. Sera mieux utilis dans la mthode beforeFilter de votre controller.
AuthComponent::identify($request, $response)
Paramtres
$request (CakeRequest) La requte utiliser.
$response (CakeResponse) La rponse utiliser, les en-tte peuvent tre envoyes
si lauthentification choue.
Cette mthode est utilise par le component Auth pour identifier un utilisateur en se basant sur les
informations contenues dans la requte courante.
AuthComponent::initialize($Controller)
Initialise le component Auth pour une utilisation dans le controller.
AuthComponent::isAuthorized($user = null, $request = null)
Utilise les adaptateurs dautorisation configurs pour vrifier quun utilisateur est configur ou non.
Chaque adaptateur sera vrifi dans lordre, si chacun deux retourne true, alors lutilisateur sera
autoris pour la requte.
AuthComponent::loggedIn()
Retourne true si le client actuel est un utilisateur connect, ou false si il ne lest pas.
AuthComponent::login($user)
Paramtres
$user (array) Un tableau de donnes dutilisateurs connects.
Prends un tableau de donnes de lutilisateur pour se connecter. Permet la connexion manuelle des
utilisateurs. Lappel de user() va renseigner la valeur de la session avec les informations fournies. Si
aucun utilisateur nest fourni, le component Auth essaiera didentifier un utilisateur en utilisant les
informations de la requte en cours. cf AuthComponent::identify().
Components (Composants)
559
AuthComponent::logout()
Retourne Une chane URL o rediriger lutilisateur dconnect.
Dconnecte lutilisateur actuel.
AuthComponent::mapActions($map = array())
Mappe les noms daction aux oprations CRUD. Utilis par les authentifications bases sur le controller. Assurez-vous davoir configure la proprit authorize avant dappeler cette mthode. Ainsi
cela dlguera $map tous les objets autorize attachs.
static AuthComponent::password($pass)
Obsolte depuis la version 2.4.
AuthComponent::redirect($url = null)
Obsolte depuis la version 2.3.
AuthComponent::redirectUrl($url = null)
Si il ny a pas de paramtre pass, elle obtient lauthentification de redirection de lURL. Passe une
URL pour dfinir la destination ou un utilisateur devrait tre redirig lors de la connexion. Se repliera
vers AuthComponent::$loginRedirect si il ny a pas de valeur de redirection stocke.
Introduit dans la version 2.3.
AuthComponent::shutdown($Controller)
Component shutdown. Si un utilisateur est connect, liquide la redirection.
AuthComponent::startup($Controller)
Mthode dexcution principale. Gre la redirection des utilisateurs invalides et traite les donnes des
formulaires de connexion.
static AuthComponent::user($key = null)
Paramtres
$key (string) La cl des donnes utilisateur que vous voulez rcuprer.Si elle
est null, tous les utilisateurs seront retourns. Peut aussi tre appele comme une
instance de mthode.
Prend les donnes concernant de lutilisateur connect, vous pouvez utiliser une cl propritaire pour
appeler une donne spcifique propos dun utilisateur :
$id = $this->Auth->user('id');
Si lutilisateur courant nest pas connect ou que la cl nexiste pas null sera retourn.
Security (Scurit)
class SecurityComponent(ComponentCollection $collection, array $settings = array())
Le component Security offre une manire simple dinclure une scurit renforce votre application. Il
fournit des mthodes pour diverses tches comme :
Restreindre les mthodes HTTP que votre application accepte.
Protection CSRF.
Protection contre la falsification de formulaire.
560
Si une action est restreinte par le component Security, elle devient un trou noir, comme une requte invalide
qui aboutira une erreur 404 par dfaut. Vous pouvez configurer ce comportement, en dfinissant la proprit
$this->Security->blackHoleCallback par une fonction de rappel (callback) dans le controller.
SecurityComponent::blackHole(object $controller, string $error)
Met en trou noir (black-hole) une requte invalide, avec une erreur 404 ou un callback personnalis.
Sans callback, la requte sera abandonne. Si un callback de controller est dfini pour SecurityComponent : :blackHoleCallback, il sera appel et passera toute information sur lerreur.
property SecurityComponent::$blackHoleCallback
La fonction de rappel (callback) du controller qui va grer et requter ce qui doit tre mis dans un
trou noir (blackholed). La fonction de rappel de mise en trou noir (blackhole callback) peut tre nimporte quelle mthode publique dun controller. La fonction de rappel doit sattendre a un paramtre
indiquant le type derreur :
public function beforeFilter() {
$this->Security->blackHoleCallback = 'blackhole';
}
public function blackhole($type) {
// gestions des erreurs.
}
9. http ://en.wikipedia.org/wiki/Cross-site_request_forgery
Components (Composants)
561
SecurityComponent::requirePost()
Dfinit les actions qui ncessitent une requte POST. Prend un nombre indfini de paramtres. Peut
tre appel sans argument, pour forcer toutes les actions requrir un POST.
SecurityComponent::requireGet()
Dfinit les actions qui ncessitent une requte GET. Prend un nombre indfini de paramtres. Peut-tre
appel sans argument, pour forcer toutes les actions requrir un GET.
SecurityComponent::requirePut()
Dfinit les actions qui ncessitent une requte PUT. Prend un nombre indfini de paramtres. Peut-tre
appel sans argument, pour forcer toutes les actions requrir un PUT.
SecurityComponent::requireDelete()
Dfinit les actions qui ncessitent une requte DELETE. Prend un nombre indfini de paramtres.
Peut-tre appel sans argument, pour forcer toutes les actions requrir un DELETE.
Restreindre les actions SSL
SecurityComponent::requireSecure()
Dfinit les actions qui ncessitent une requte SSL-securise. Prend un nombre indfini de paramtres.
Peut-tre appel sans argument, pour forcer toutes les actions requrir une SSL-securise.
SecurityComponent::requireAuth()
Dfinit les actions qui ncessitent un jeton valide gnr par le component Security. Prend un nombre
indfini de paramtres. Peut-tre appel sans argument, pour forcer toutes les actions requrir une
authentification valide.
Restreindre les demandes croises de controller
property SecurityComponent::$allowedControllers
Une liste de controllers qui peuvent envoyer des requtes vers ce controller. Ceci peut tre utilis pour
contrler les demandes croises de controller.
property SecurityComponent::$allowedActions
Une liste des actions qui peuvent envoyer des requtes vers les actions de ce controller. Ceci peut tre
utilis pour contrler les demandes croises de controller.
562
property SecurityComponent::$csrfCheck
Si vous utilisez les formulaires de protection CSRF. Dfinit false pour dsactiver la protection
CSRF sur les formulaires.
property SecurityComponent::$csrfExpires
La dure avant expiration dun jeton CSRF. Chaque requte formulaire/page va gnrer un nouveau
jeton qui ne pourra tre soumis quune seule fois avant son expiration. Peut tre une valeur compatible
avec strtotime(). Par dfaut 30 minutes.
property SecurityComponent::$csrfUseOnce
Contrle si oui ou non les jetons CSRF sont utiliss et brls. Dfinit false pour ne pas gnrer de
nouveau jetons sur chaque requte. Un jeton pourra tre rutilis jusqu ce quil expire. Ceci rduit
les chances des utilisateurs davoir des requtes invalides en raison de la consommation de jeton. Cela
pour effet de rendre CSRF moins scuris, et les jetons rutilisables.
Components (Composants)
563
Utilisation
Le component Security est gnralement utilis dans la mthode beforeFilter() de votre controller.
Vous pouvez spcifier les restrictions de scurit que vous voulez et le component Security les forcera au
dmarrage :
class WidgetController extends AppController {
public $components = array('Security');
public function beforeFilter() {
$this->Security->requirePost('delete');
}
}
Dans cette exemple, laction delete peut tre effectue avec succs si celui ci reoit une requte POST :
class WidgetController extends AppController {
public $components = array('Security');
public function beforeFilter() {
if (isset($this->request->params['admin'])) {
$this->Security->requireSecure();
}
}
}
Cette exemple forcera toutes les actions qui proviennent de la route Admin tre effectues via des
requtes scurises SSL :
class WidgetController extends AppController {
public $components = array('Security');
public function beforeFilter() {
if (isset($this->params['admin'])) {
$this->Security->blackHoleCallback = 'forceSSL';
$this->Security->requireSecure();
}
}
public function forceSSL() {
$this->redirect('https://' . env('SERVER_NAME') . $this->here);
}
}
Cet exemple forcera toutes les actions qui proviennent de la route admin requrir des requtes scuriss
SSL. Quand la requte est place dans un trou noir, elle appellera le callback forceSSL() qui redirigera
les requtes non scurises vers les requtes scurises automatiquement.
564
protection CSRF
CSRF ou Cross Site Request Forgery est une vulnrabilit courante pour les applications Web. Cela permet
un attaquant de capturer et de rejouer une requte, et parfois de soumettre des demandes de donnes en
utilisant les balises images ou des ressources sur dautres domaines.
Les doubles soumissions et les attaques replay sont gres par les fonctionnalits CSRF du component
Security. Elles fonctionnent en ajoutant un jeton spcial pour chaque requte de formulaire. Ce jeton utilis
quune fois ne peut pas tre utilis nouveau. Si une tentative est fate pour r-utiliser un jeton expir la
requte sera mise dans le trou noir (blackholed)
Utilisation de la protection CSRF En ajoutant simplement la SecurityComponent votre tableau de
component, vous pouvez bnficier de la protection CSRF fournie. Par dfaut les jetons CSRF sont valides
30 minutes et expire lutilisation. Vous pouvez contrler la dure des jetons en paramtrant csrfExpires
dans le component.
public $components = array(
'Security' => array(
'csrfExpires' => '+1 hour'
)
);
Vous pouvez aussi dfinir cette proprit dans la partie beforeFilter de votre controller.
public function beforeFilter() {
$this->Security->csrfExpires = '+1 hour';
// ...
}
La valeur de la proprit csrfExpires peut tre nimporte quelle valeur compatible la proprit strtotime() 10 . Par dfaut le Helper Form FormHelper ajoutera une data[_Token][key] contenant le
jeton CSRF pour tous les formulaires quand le component est activ.
Grer les jetons manquants ou prims Les jetons manquants ou prims sont grs de la mme faon
que dautres violations de scurit. Le blackHoleCallback du component Security sera appel avec
un paramtre csrf. Ceci vous aide filtrer en sortie les problmes de jeton CSRF, des autres erreurs.
Utilisation de jeton par-session au lieu de jeton usage unique Par dfaut un nouveau jeton est gnr
chaque requte, et chaque jeton ne peut tre utilis quune seule fois. Si un jeton est utilis une nouvelle fois,
il sera mis dans le trou noir. Parfois , ce comportement est indsirable, et peut crer des problmes avec les
applications une page. Vous pouvez activer la multi-utilisation des jetons en paramtrant csrfUseOnce
false. Ceci peut tre effectu dans le tableau components, ou dans la partie beforeFilter de votre
controller :
10. http ://php.net/manual/en/function.strtotime.php
Components (Composants)
565
Cela dira au component que vous voulez r-utiliser un jeton CSRF jusqu ce que la requte expire - Cest
contrl par les valeurs de csrfExpires. Si vous avez des problmes avec les jetons expirs, ceci peut
tre une bon quilibrage entre la scurit et la facilit dutilisation.
Dsactiver la protection CSRF Il peut y avoir des cas o vous souhaitez dsactiver la protection CSRF sur vos formulaires. Si vous voulez dsactiver cette fonctionnalit, vous pouvez dfinir
$this->Security->csrfCheck = false; dans votre beforeFilter ou utiliser le tableau
components. Par dfaut la protection CSRF est active, et paramtre pour lutilisation de jetons usage
unique.
Dsactiver CSRF et la Validation des Donnes Post pour des Actions Spcifiques
Il peut arriver que vous souhaitiez dsactiver toutes les vrifications de scurit pour
une action (ex. ajax request). Vous pouvez dlocker ces actions en les listant dans
$this->Security->unlockedActions
dans
votre
beforeFilter.
La
proprit
unlockedActions ne va pas avoir deffets sur les autres fonctionnalits de SecurityComponent.
Introduit dans la version 2.3.
Request Handling (Gestion des requtes)
class RequestHandlerComponent(ComponentCollection $collection, array $settings = array())
Le component Request Handler est utilis dans CakePHP pour obtenir des informations supplmentaires
au sujet des requtes HTTP qui sont faites votre application. Vous pouvez lutiliser pour informer vos
controllers des processus AJAX, autant que pour obtenir des informations complmentaires sur les types de
contenu que le client accepte et modifie automatiquement dans le layout appropri, quand les extensions de
fichier sont disponibles.
Par dfaut, le RequestHandler dtectera automatiquement les requtes AJAX bases sur le header HTTPX-Requested-With, qui est utilis par de nombreuses librairies JavaScript. Quand il est utilis conjointement avec Router::parseExtensions(), RequestHandler changera automatiquement le layout et
les fichiers de vue par ceux qui correspondent au type demand. En outre, sil existe un helper avec le mme
nom que lextension demande, il sera ajout au tableau des helpers des Controllers. Enfin, si une donne XML/JSON est POSTe vers vos Controllers, elle sera dcompose dans un tableau qui est assign
$this->request->data, et pourra alors tre sauvegarde comme une donne de model. Afin dutiliser
le Request Handler, il doit tre inclu dans votre tableau $components :
class WidgetController extends AppController {
public $components = array('RequestHandler');
566
// suite du controller
}
Request Handler contient plusieurs mthodes qui fournissent des informations propos du client et de ses
requtes.
RequestHandlerComponent::accepts($type = null)
$type peut tre une chane, un tableau, ou null. Si cest une chane, la mthode accepts() renverra true si le
client accepte ce type de contenu. Si cest un tableau, accepts() renverra true si un des types du contenu est
accept par le client. Si cest null, elle renverra un tableau des types de contenu que le client accepte. Par
exemple :
class PostsController extends AppController {
public $components = array('RequestHandler');
public function beforeFilter () {
if ($this->RequestHandler->accepts('html')) {
// Ce code est excut uniquement si le client accepte
// les rponses HTML (text/html)
} elseif ($this->RequestHandler->accepts('xml')) {
// execut seulement si le client accepte seulement
// les rponses XML
}
if ($this->RequestHandler->accepts(array('xml', 'rss', 'atom'))) {
// Execut si le client accepte l'un des suivants: XML, RSS ou Atom
}
}
}
Components (Composants)
567
Fennec
iPad
iPhone
iPod
J2ME
MIDP
NetFront
Nokia
Opera Mini
Opera Mobi
PalmOS
PalmSource
portalmmm
Plucker
ReqwirelessWeb
SonyEricsson
Symbian
UP.Browser
webOS
Windows CE
Windows Phone OS
Xiino
RequestHandlerComponent::isWap()
Retourne true si le client accepte le contenu WAP.
Toutes les mthodes de dtection des requtes prcdentes peuvent tre utilises dans un contexte similaire
pour filtrer les fonctionnalits destines du contenu spcifique. Par exemple, au moment de rpondre
aux requtes AJAX, si vous voulez dsactiver le cache du navigateur, et changer le niveau de dbogage.
Cependant, si vous voulez utiliser le cache pour les requtes non-AJAX., le code suivant vous permettra de
le faire :
if ($this->request->is('ajax')) {
$this->disableCache();
}
// Continue l'action du controller
RequestHandlerComponent::getAjaxVersion()
Rcupre la version de la librairie Prototype si la requte est de type AJAX ou une chane de caractres vide dans le cas contraire. La librairie Prototype envoie une entte HTTP spciale Prototype
version.
Dcoder automatiquement les donnes de la requte
RequestHandlerComponent::addInputType($type, $handler)
568
Paramtres
$type (string) Lalias du type de contenu auquel ce dcodeur est attach. ex. json
ou xml
$handler (array) Linformation de gestionnaire pour le type.
Ajoute une requte de dcodage de donnes. Le gestionnaire devrait contenir un callback, et tour
autre argument supplmentaire pour le callback. Le callback devrait retourner un tableau de donnes
contenues dans la requte. Par exemple, ajouter un gestionnaire de CSV dans le callback beforeFilter
de votre controller pourrait ressembler ceci
$parser = function ($data) {
$rows = str_getcsv($data, "\n");
foreach ($rows as &$row) {
$row = str_getcsv($row, ',');
}
return $rows;
};
$this->RequestHandler->addInputType('csv', array($parser));
Lexemple ci-dessus ncessite PHP 5.3, cependant vous pouvez utiliser nimporte quel callback 11
pour la fonction de gestion. Vous pouvez aussi passer des arguments supplmentaires au callback,
cest trs utile pour les callbacks comme json_decode :
$this->RequestHandler->addInputType('json', array('json_decode', true));
En plus de la dtection de requtes, RequestHandler fournit galement une solution simple pour modifier la
sortie de faon ce que le type de contenu corresponde votre application.
RequestHandlerComponent::setContent($name, $type = null)
Paramtres
$name (string) Le nom ou lextension du fichier (Content-type), par ex : html,
css, json, xml.
$type (mixed)
Le(s) type(s) mime(s) auquel se rfre Content-type.
setContent ajoute/dfinit les Content-types pour le nom prcis. Permet aux content-types dtre associs des alias simplifis et/ou des extensions. Ceci permet RequestHandler de rpondre automatiquement aux requtes de chaque type dans sa mthode startup. Si vous utilisez Router : :parseExtension, vous devriez utiliser lextension de fichier comme le nom du Content-type. De plus, ces types de
contenu sont utiliss par prefers() et accepts().
setContent est bien mieux utilis dans le beforeFilter() de vos controllers, parce quil tirera un meilleur
profit de lautomagie des alias de content-type.
Les correspondances par dfaut sont :
javascript text/javascript
11. http ://php.net/callback
Components (Composants)
569
js text/javascript
json application/json
css text/css
html text/html, */*
text text/plain
txt text/plain
csv application/vnd.ms-excel, text/plain
form application/x-www-form-urlencoded
file multipart/form-data
xhtml application/xhtml+xml, application/xhtml, text/xhtml
xhtml-mobile application/vnd.wap.xhtml+xml
xml application/xml, text/xml
rss application/rss+xml
atom application/atom+xml
amf application/x-amf
wap text/vnd.wap.wml, text/vnd.wap.wmlscript, image/vnd.wap.wbmp
wml text/vnd.wap.wml
wmlscript text/vnd.wap.wmlscript
wbmp image/vnd.wap.wbmp
pdf application/pdf
zip application/x-zip
tar application/x-tar
RequestHandlerComponent::prefers($type = null)
Dtermine quels content-types le client prfre. Si aucun paramtre nest donn, le type de contenu le plus approchant est retourn. Si $type est un tableau, le premier type que le client accepte
sera retourn. La prfrence est dtermine, premirement par lextension de fichier analyse par
Router, si il y en avait une de fournie et secondairement, par la liste des content-types dfinis dans
HTTP_ACCEPT.
RequestHandlerComponent::renderAs($controller, $type)
Paramtres
$controller (Controller) Rfrence du controller
$type (string) nom simplifi du type de contenu rendre, par exemple : xml, rss.
Change le mode de rendu dun controller pour le type spcifi. Ajoutera aussi le helper appropri au
tableau des helpers du controller, sil est disponible et quil nest pas dj dans le tableau.
RequestHandlerComponent::respondAs($type, $options)
Paramtres
$type (string) nom simplifi du type de contenu rendre, par exemple : xml, rss
ou un content-type complet, tel que application/x-shockwave
$options (array) Si $type est un nom simplifi de type, qui a plus dune association avec des contenus, $index est utilis pour slectionner le type de contenu.
Dfinit len-tte de rponse bas sur la correspondance content-type/noms.
RequestHandlerComponent::responseType()
Retourne len-tte Content-type du type de rponse actuel ou null sil y en a dj un de dfini.
570
Components (Composants)
571
Cookie
class CookieComponent(ComponentCollection $collection, array $settings = array())
Le component Cookie est un conteneur de la mthode native de PHP setcookie. Il inclut galement
toutes sortes de fonctionnalits pour rendre lcriture de code pour les cookies trs pratique. Avant de tenter
dutiliser le component Cookie, vous devez vous assurer que Cookie est list dans la partie $components
de votre controller.
Paramtrage du controller
Voici un certain nombre de variables du controller qui vous permettent de configurer la manire dont les
cookies sont crs et grs. Dfinir ces variables spciales dans la mthode beforeFilter() de votre controller
vous permet de modifier le fonctionnement du component Cookie.
variable
Cookie
string
$name
string
$key
par
dfaut
CakeCookie
null
string
$domain
int or
string
$time
string
$path
boolean
$secure
false
5
Days
boolean
false
$httpOnly
description
Le nom du cookie
Cette chane de caractres est utilise pour chiffrer la valeur crite dans le cookie.
Cette chane devrait tre alatoire et difficile deviner. Quand on utilise le
chiffrement Rijndael ou le chiffrement AES, cette valeur doit tre plus grande que
32 bytes.
Le nom de domaine autoris accder au cookie. Utilisez par exemple
.votredomaine.com pour autoriser les accs depuis tous vos sous-domaines.
Le moment o votre cookie expirera. Les entiers sont interprts comme des
secondes et une valeur de 0 est indique quil sagit dun cookie de session : il
expirera lors de la fermeture du navigateur. Si une chane est dfinie, elle sera
interprte avec la fonction PHP strtotime(). Vous pouvez dfinir cela lintrieur
de la mthode write().
Le chemin daccs au server sur lequel le cookie sera appliqu. Si $path est
paramtr /foo/, il ne sera disponible que dans le rpertoire /foo/ et tous les
sous-rpertoires comme /foo/bar/ de votre domaine. La valeur par dfaut est le
domaine entier. Vous pouvez dfinir cela directement lintrieur de la mthode
write().
Indique que le cookie ne devrait tre transmis quau travers une connexion
HTTPS scurise. Quand cela est dfini true, le cookie ne sera dfini que si une
connexion scuris existe.Vous pouvez dfinir cela directement lintrieur de la
mthode write()
Dfini true pour fabriquer uniquement des cookies HTTP. Les cookies
seulement HTTP ne sont pas disponibles en JavaScript
Les extraits de code de controller suivants montrent comment inclure le component Cookie et paramtrer les
variables du controller ncessaires pour crire un cookie nomm baker_id pour le domaine example.com
qui a besoin dune connexion scurise, qui est disponible au chemin /bakers/preferences/, qui expire dans
une heure, et est uniquement en HTTP.
572
Le Component Cookie offre plusieurs mthodes pour travailler avec les Cookies.
CookieComponent::write(mixed $key, mixed $value = null, boolean $encrypt = true, mixed
$expires = null)
La mthode write() est le cur du composant Cookie, $key est le nom de la variable dsire, et $value
est linformation stocker :
$this->Cookie->write('nom', 'Rmy');
Vous pouvez galement grouper vos variables en utilisant la notation point . dans les paramtres de
cl :
$this->Cookie->write('User.name', 'Larry');
$this->Cookie->write('User.role', 'Lead');
Si vous voulez crire plus dune valeur dans le cookie en une fois, vous pouvez passer un tableau :
$this->Cookie->write('User',
array('name' => 'Larry', 'role' => 'Lead')
);
Toutes les valeurs dans le cookie sont chiffres par dfaut. Si vous voulez stocker vos valeurs en
texte clair, dfinissez le troisime paramtre de la mthode write() false. Vous devriez vous rappeler
de dfinir le mode de chiffrement aes pour vous assurer que les valeurs sont chiffres de faon
scurise :
$this->Cookie->write('name', 'Larry', false);
Le dernier paramtre crire est $expires - le nombre de secondes avant que le cookie nexpire.
Par convention, ce paramtre peut aussi tre pass comme une chane de caractres que la fonction
strtotime() de PHP comprend :
// Les deux cookies expirent dans une heure.
$this->Cookie->write('first_name', 'Larry', false, 3600);
$this->Cookie->write('last_name', 'Masters', false, '1 hour');
Components (Composants)
573
CookieComponent::check($key)
Paramtres
$key (string) La cl vrifier.
Utilis pour vrifier si une cl/chemin existe et a une valeur non null.
Introduit dans la version 2.3 : CookieComponent::check() a t ajoute dans la version 2.3
CookieComponent::delete(mixed $key)
Efface une variable de cookie dont le nom est dfini dans $key. Fonctionne avec la notation par point :
// Efface une variable
$this->Cookie->delete('bar');
// Efface la variable bar du cookie, mais seulement dans foo.
$this->Cookie->delete('foo.bar');
CookieComponent::destroy()
Dtruit le cookie actuel.
CookieComponent::type($type)
Vous permet de changer le schma de chiffrement. Par dfaut, le schma cipher est utilis pour une
compatibilit rtroactive. Cependant, vous devriez toujours utiliser les schmas rijndael ou aes.
Modifi dans la version 2.2 : Le type rijndael a t ajout.
Introduit dans la version 2.5 : Le type aes a t ajout.
Liste de contrle daccs (ACL)
class AclComponent(ComponentCollection $collection, array $settings = array())
Comprendre le fonctionnement des ACL
Les choses importantes requirent un contrle daccs. Les listes de contrles daccs sont une faon de
grer les permissions dune application dune manire trs prcise et pourtant facilement maintenable et
manipulable.
574
Les listes de contrles daccs, ou ACL (Access Control Lists), manipulent deux choses principales : les
choses qui veulent accder des trucs et celles qui sont recherches. Dans le jargon ACL, les choses qui
veulent accder des trucs (le plus souvent les utilisateurs) sont reprsentes par des access request objects
(objets requte daccs) ou AROs. Les choses du systme qui sont recherches (le plus souvent les actions
ou les donnes) sont appeles access control objects (objets contrle daccs) ou ACOs. Les entits sont
appeles objets, parce que parfois, lobjet demand nest pas une personne - des fois, vous pourriez vouloir
limiter laccs certains controllers de CakePHP qui doivent initier leur logique dans dautres parties de
votre application. Les ACOs pourraient tre nimporte quoi que vous voudriez contrler, dune action de
controller un service Web, en passant par une case de lagenda en ligne de votre Mamy.
Rappel :
ACO - Objet Contrle dAccs - Reprsente quelque chose qui est recherch
ARO - Objet Requte dAccs - Reprsente quelque chose qui veut quelque chose
Gnralement, les ACL sont utilises pour dcider quand un ARO peut obtenir laccs un ACO.
Afin de vous aider comprendre comment toutes les choses travaillent ensemble, utilisons un exemple semifonctionnel. Imaginons un moment, un ordinateur utilis par un clbre groupe daventuriers tirs du roman
fantastique le Seigneur des Anneaux. Le chef du groupe, Gandalf, veut grer les biens du groupe, tout en
maintenant un bon niveau de confidentialit et de scurit entre les autres membres de lquipe. La premire
chose dont il a besoin est de crer une liste dAROs (requteurs) qui comprend :
Gandalf
Aragorn
Bilbo
Frodo
Gollum
Legolas
Gimli
Pippin
Merry
Note : Comprenez que lACL nest pas la mme chose que lauthentification. LACL est ce qui vient aprs
quun utilisateur ait t authentifi. Par contre, les deux sont habituellement utiliss de paire, il est important
de faire la distinction entre savoir qui est quelquun (authentification) et savoir ce quil peut faire (ACL).
La chose suivante que Gandalf doit faire, cest de crer une liste initiale des choses, ou ACOs, que le systme
va contrler. Sa liste devrait ressembler quelque chose comme a :
Les armes
LAnneau
Le porc sal
La diplomatie
La bire
Traditionnellement, les systmes taient grs en utilisant une sorte de matrice, qui prsentait un ensemble
basique dutilisateurs et de permissions en relation avec les objets. Si ces informations taient stockes dans
un tableau, il ressemblerait a :
Components (Composants)
575
x
Gandalf
Aragorn
Bilbo
Frodo
Gollum
Legolas
Gimli
Pippin
Merry
Les armes
Lanneau
Autoris
Le porc sal
Autoris
Autoris
La diplomacie
Autoris
Autoris
La bire
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
Autoris
A premire vue, il semble que ce systme pourrait trs bien fonctionner. Les affectations peuvent tre mises
en place des fin de scurit (seul Frodo peut accder lAnneau) et pour viter les accidents (en gardant
les hobbits distance du porc sal et des armes). Cela parat suffisamment complet et assez facile lire,
nest-ce pas ?
Pour un petit systme comme celui-ci, peut-tre quune configuration en matrice pourrait fonctionner. Mais
pour un systme volutif ou un systme avec un fort pourcentage de ressources (ACOs) et dutilisateurs
(AROs), un tableau peut devenir plus lourd que rapide.
Imaginez une tentative de contrler laccs des centaines de camps militaires et de grer cela par unit. Un
autre inconvnient des matrices est que vous ne pouvez par vraiment regrouper logiquement des sections
dutilisateurs ou faire des changements de permissions en cascade, pour des groupes dutilisateurs bass sur
ces regroupements logiques. Par exemple, il serait certainement plus chouette dautoriser automatiquement
les hobbits accder la bire et au porc une fois que le combat est fini : faire a sur une base dutilisateurs
grs individuellement pourrait tre fastidieux et source derreur. Faire des changements de permissions en
cascade pour tous les hobbits serait plus facile.
Les ACL sont trs souvent implments dans une structure en arbre. Il y a gnralement un arbre dAROs
et un arbre dACOs. En organisant vos objets en arbres, les permissions peuvent toujours tre distribues
dune faon granulaire, tout en maintenant encore une bonne cohrence de lensemble. En chef raisonnable
quil est, Gandalf choisit dutiliser lACL dans son nouveau systme et dorganiser ses objets de la manire
suivante :
La Communaut de lAnneau
Les Guerriers
Aragorn
Legolas
Gimli
Les Magiciens
Gandalf
Les Hobbits
Frodo
Bilbo
Merry
Pippin
Les Visiteurs
Gollum
Lutilisation dune structure en arbre pour les AROs permet Gandalf, de dfinir en une fois des autorisations
qui sappliquent un groupe entier dutilisateurs. Ainsi, en utilisant notre arbre ARO, Gandalf peut ajouter,
aprs coup, quelques permissions de groupe :
576
Permission Info
Deny all
Allow ale
Result
Denying access to ale.
Allowing access to ale !
Still allowing ale !
Note : Puisque le nud Pippin dans larbre dACL ne refuse pas spcifiquement laccs lACO bire,
le rsultat final est que nous donnons laccs cet ACO.
Larbre nous permet aussi de faire des ajustements plus fins pour un meilleur contrle granulaire, tout en
conservant encore la capacit de faire de grands changements pour les groupes dAROs :
Communaut de lAnneau (Refuser : tout)
Guerriers (Autoriser : Armes, Bire, Rations pour les Elfes, Porc sal)
Aragorn (Autoriser : Diplomatie)
Legolas
Gimli
Magiciens (Autoriser : Porc sal, Diplomatie, Bire)
Gandalf
Hobbits (Autoriser : Bire)
Frodo (Autoriser : Anneau)
Bilbo
Merry (Refuser : Bire)
Pippin (Autoriser : Diplomatie)
Visiteurs (Autoriser : Porc sal)
Gollum
Cette approche nous donne plus de possibilits pour faire des changements de permissions de grande ampleur, mais aussi des ajustements plus prcis. Cela nous permet de dire que tous les hobbits peuvent accder
la bire, avec une exception Merry. Pour voir si Merry peut accder la bire, nous aurions trouv son
chemin dans larbre : Communaut->Hobbits->Merry et appliqu notre principe, en gardant une trace des
permissions lies la bire :
Components (Composants)
577
Nud de lARO Information sur la permission Rsultat Communaut de lAnneau Refuse tout Refuser
laccs la bire. Hobbits Autorise la bire Autoriser laccs la bire ! Merry Refuse la bire Refuser la
bire
Nud de lARO
Communaut de lAnneau
Hobbits
Merry
Rsultat
Refuser laccs la bire.
Autoriser laccs la bire !
Refuser la bire.
Dfinir les permissions : ACL de CakePHP bases sur des fichiers INI
La premire implmentation dACL sur CakePHP tait base sur des fichiers INI stocks dans linstallation
de CakePHP. Bien quelle soit stable et pratique, nous recommandons dutiliser plutt les solutions dACL
bases sur les bases de donnes, surtout pour leur capacit crer de nouveaux ACOs et AROs la vole.
Nous recommandons son utilisation dans de simples applications - et spcialement pour ceux qui ont une
raison plus ou moins particulire de ne pas vouloir utiliser une base de donnes.
Par dfaut, les ACL de CakePHP sont grs par les bases de donnes. Pour activer les ACL bass sur les
fichiers INI, vous devez dire CakePHP quel systme vous utilisez en mettant jour les lignes suivantes
dans app/config/core.php
// Changer ces lignes :
Configure::write('Acl.classname', 'DbAcl');
Configure::write('Acl.database', 'default');
// Pour qu'elles ressemblent :
Configure::write('Acl.classname', 'IniAcl');
//Configure::write('Acl.database', 'default');
Les permissions des ARO/ACO sont spcifies dans /app/config/acl.ini.php. Lide de base est que les AROs
sont spcifis dans une section INI qui a trois proprits : groups, allow et deny.
groups : nom du groupe dont lARO est membre. allow : nom des ACOs auxquels lARO a
accs. deny : nom des ACOs auxquels lARO ne devrait pas avoir accs.
Les ACOs sont spcifis dans des sections INI qui incluent seulement les proprits allow et deny.
Par exemple, voyons quoi la structure ARO de la Communaut que nous avions faonne pourrait ressembler dans une syntaxe INI :
;------------------------------------; AROs
;------------------------------------[aragorn]
groups = guerriers
allow = diplomatie
[legolas]
groups = guerriers
[gimli]
groups = guerriers
[gandalf]
578
groups = magiciens
[frodo]
groups = hobbits
allow = anneau
[bilbo]
groups = hobbits
[merry]
groups = hobbits
deny = ale
[pippin]
groups = hobbits
[gollum]
groups = visiteurs
;------------------------------------; ARO Groups
;------------------------------------[guerriers]
allow = armes, biere, porc_sale
[magiciens]
allow = porc_sale, diplomatie, biere
[hobbits]
allow = biere
[visiteurs]
allow = porc_sale
Maintenant que vous avez dfini vos permissions, vous pouvez passer la section sur la vrification des
permissions en utilisant le component ACL.
Dfinir les permissions : ACL de CakePHP via une base de donnes
Maintenant que nous avons vu les permissions ACL bases sur les fichiers INI, voyons les ACL via une base
de donnes (les plus communment utilises).
Pour commencer Limplmentation par dfaut des permissions ACL est propuls par les bases de donnes. La base de donnes CakePHP pour les ACL est compose dun ensemble de models du cur et dune
application en mode console qui sont crs lors de votre installation de CakePHP. Les models sont utiliss
par CakePHP pour interagir avec votre base de donnes, afin de stocker et de retrouver les nuds sous forme
darbre. Lapplication en mode console est utilise pour initialiser votre base de donnes et interagir avec
vos arbres dACO et dARO.
Pour commencer, vous devrez dabord tre sr que votre /app/config/database.php est prsent
Components (Composants)
579
et correctement configur. Voir la section 4.1 pour plus dinformation sur la configuration dune base de
donnes.
Une fois que vous lavez fait, utilisez la console de CakePHP pour crer vos tables dACL :
$ cake schema create DbAcl
Lancer cette commande va supprimer et recrer les tables ncessaires au stockage des informations des ACO
et des ARO sous forme darbre. La sortie console devrait ressembler quelque chose comme a :
--------------------------------------------------------------Cake Schema Shell
--------------------------------------------------------------The following tables will be dropped.
acos
aros
aros_acos
Are you sure you want to drop the tables? (y/n)
[n] > y
Dropping tables.
acos updated.
aros updated.
aros_acos updated.
The following tables will be created.
acos
aros
aros_acos
Are you sure you want to create the tables? (y/n)
[y] > y
Creating tables.
acos updated.
aros updated.
aros_acos updated.
End create.
580
Maintenant que nous avons tout configur, attelons-nous la cration de quelques arbres ARO et ACO.
Crer des Objet Contrle dAccs (ACOs) et des Objet Requte dAccs (AROs) Pour la cration de
nouveaux objets (ACOs et AROs), il y a deux principales faons de nommer et daccder aux noeuds. La
premire mthode est de lier un objet ACL directement un enregistrement dans votre base de donnes en
spcifiant le nom du model et la cl trangre. La seconde mthode peut tre utilise quand un objet nest
pas en relation directe avec un enregistrement de votre base de donnes - vous pouvez fournir un alias textuel
pour lobjet.
Note : Gnralement, quand vous crez un groupe ou un objet de niveau suprieur, nous recommandons
dutiliser un alias. Si vous grez laccs un enregistrement ou un article particulier de la base de donnes,
nous recommandons dutiliser la mthode du model/cl trangre.
Vous voulez crer de nouveaux objets ACL en utilisant le model ACL du coeur de CakePHP. Pour ce faire, il
y a un nombre de champs que vous aurez utiliser pour enregistrer les donnes : model, foreign_key,
alias, et parent_id.
Les champs model et foreign_key pour un objet ACL vous permettent de crer un lien entre les objets
qui correspondent lenregistrement du model (sil en est). Par exemple, un certain nombre dAROs correspondraient aux enregistrements User de la base de donnes. Il faut configurer la foreign_key pour
que lID du User vous permette de lier les informations de lARO et de lUser avec un seul appel find() au
model User avec la bonne association. Rciproquement, si vous voulez grer les oprations ddition sur un
article spcifique dun blog ou dune liste de recette, vous devez choisir de lier un ACO cet enregistrement
spcifique du model.
Un alias est un simple label lisible pour un humain que vous pouvez utiliser pour identifier un objet ACL
qui nest pas en relation directe avec un enregistrement dun model. Les alias sont couramment utiliss pour
nommer les groupes dutilisateurs ou les collections dACOs.
Le parent_id dun objet ACL vous permet de remplir la structure de larbre. Il fournit lID du noeud
parent dans larbre pour crer un nouvel enfant.
Avant que vous ne puissiez crer de nouveaux objets ACL, nous devront charger leurs classes respectives. La
faon la plus facile de le faire est dinclure les components ACL de CakePHP dans le tableau $composents
du controller :
public $components = array('Acl');
Quand ce sera fait, nous verrons quelques exemples de cration de ces objets. Le code suivant pourrait tre
plac quelque part dans laction dun controller :
Note : Tant que les exemples que nous voyons ici nous montrent la cration dARO, les mmes techniques
pourront tre utilises pour la cration dun arbre dACO.
Pour rester dans notre configuration de Communaut, nous allons dabord crer nos groupes dARO. Comme
nos groupes nont pas rellement denregistrements spcifiques qui leurs soient relis, nous allons utiliser
les alias pour crer ces objets ACL. Ce que nous faisons ici est en perspective dune action du controller
mais pourrait tre fait ailleurs. Ce que nous allons aborder ici est un peu une approche artificielle, mais vous
devriez trouver ces techniques plus confortables utiliser pour crer des AROs et des ACOs la vole.
Components (Composants)
581
Ceci ne devrait rien avoir de radicalement nouveau - nous sommes juste en train dutiliser les models pour
enregistrer les donnes comme nous le faisons toujours :
public function touteslesActions() {
$aro =& $this->Acl->Aro;
// Ici ce sont toutes les informations sur le tableau de notre groupe
// que nous pouvons itrer comme ceci
$groups = array(
0 => array(
'alias' => 'guerriers'
),
1 => array(
'alias' => 'magiciens'
),
2 => array(
'alias' => 'hobbits'
),
3 => array(
'alias' => 'visiteurs'
),
);
//Faisons une itration et crons les groupes d'ARO
foreach($groups as $data) {
//Pensez faire un appel create() au moment d'enregistrer dans
//la boucle...
$aro->create();
//Enregistrement des donnes
$aro->save($data);
}
//Les autres actions logiques seront placer ici...
}
Une fois que nous avons cela, nous pouvons utiliser la console dapplication ACL pour vrifier la structure
de larbre.
$ cake acl view aro
Arbre d'Aro:
--------------------------------------------------------------[1]guerriers
[2]magiciens
[3]hobbits
[4]visiteurs
---------------------------------------------------------------
Je suppose quil ny en a pas beaucoup dans larbre ce niveau, mais au minimum quelques vrifications
que nous avons faites aux quatres noeuds de niveaux suprieurs. Ajoutons quelques enfants ces noeuds
ARO en ajoutant nos AROs utilisateurs dans ces groupes. Tous les bons citoyens de la Terre du Milieu ont un
582
accompte dans notre nouveau systme, nous allons alors lier les enregistrements dARO aux enregistrements
spcifiques du model de notre base de donnes.
Note : Quand nous ajouterons un noeud enfant un arbre, nous devrons nous assurer dutiliser les ID des
noeuds ACL, plutt que dutiliser la valeur de la foreign_key (cl trangre).
public function anyAction(){
$aro = new Aro();
//Ici nous avons les enregistrement de nos utilisateurs prts tre lis aux
//nouveaux enregistrements d'ARO. Ces donnes peuvent venir d'un model et
//modifies, mais nous utiliserons des tableaux statiques pour les besoins de la
//dmonstration.
$users = array(
0 => array(
'alias' => 'Aragorn',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 2356,
),
1 => array(
'alias' => 'Legolas',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 6342,
),
2 => array(
'alias' => 'Gimli',
'parent_id' => 1,
'model' => 'User',
'foreign_key' => 1564,
),
3 => array(
'alias' => 'Gandalf',
'parent_id' => 2,
'model' => 'User',
'foreign_key' => 7419,
),
4 => array(
'alias' => 'Frodo',
'parent_id' => 3,
'model' => 'User',
'foreign_key' => 7451,
),
5 => array(
'alias' => 'Bilbo',
'parent_id' => 3,
'model' => 'User',
'foreign_key' => 5126,
),
6 => array(
'alias' => 'Merry',
'parent_id' => 3,
'model' => 'User',
Components (Composants)
583
Note : Typiquement vous naurez pas fournir et un alias, et un model/cl_trangre, mais nous les utiliserons ici pour faire une structure darbre plus facile lire pour les besoins de la dmonstrations.
La sortie console de cette commande peut maintenant nous intresser un peu plus. Nous allons faire un
essai :
$ cake acl view aro
Arbre d'Aro:
--------------------------------------------------------------[1]guerriers
[5]Aragorn
[6]Legolas
[7]Gimli
[2]magiciens
[8]Gandalf
[3]hobbits
[9]Frodo
584
[10]Bilbo
[11]Merry
[12]Pippin
[4]visiteurs
[13]Gollum
--------------------------------------------------------------
Maintenant que nous avons notre arbre dARO configur proprement, revenons sur une possible approche
de structure darbre dACO. Alors que nous pouvons structurer plus dune reprsentation abstraite de nos
ACOs, il est parfois plus pratique de modliser un arbre ACO aprs le paramtrage du Controller/Action
de CakePHP. Nous avons cinq principaux objets manipuler dans le scnario de la Communaut, et la
configuration naturelle pour cela dans une application CakePHP est un groupe de models, et tout la fin les
controllers qui les manipulent. A ct des controllers eux-mmes, nous allons vouloir contrler laccs des
actions spcifiques dans ces controllers.
Nous allons configurer un arbre dACO qui va imiter une configuration dapplication CakePHP. Depuis nos
cinq ACOs, nous allons crer un arbre dACO qui devra ressembler a :
Armes
Anneaux
MorceauxPorc
EffortsDiplomatiques
Bires
Une bonne chose concernant la configuration des ACL et que chaque ACO va automatiquement contenir
quatre proprits relatives aux actions CRUD (crer, lire, mettre jour et supprimer). Vous pouvez crer
des noeuds enfants sous chacun de ces cinq principaux ACOs, mais lutilisation des actions de management
intgres CakePHP permet daborder les oprations basiques de CRUD sur un objet donn. Gardez
lesprit quil faudra faire vos arbres dACO plus petits et plus faciles maintenir. Nous allons voir comment
ils sont utiliss plus tard quand nous parlerons de la faon dassigner les permissions.
Nous sommes maintenant des pros de lajout dAROs et de lutilisation des techniques de cration darbres
dACO. La cration de groupes dun niveau suprieur utilise le model Aco du coeur.
Assigner les Permissions Aprs la cration de nos ACOs et AROs, nous pouvons finalement assigner des
permissions entre les deux groupes. Ceci est ralis en utilisant le component Acl du cur de CakePHP.
Continuons avec notre exemple.
Ici nous travaillerons dans un contexte dune action de controller. Nous faisons cela parce que les permissions sont manages par le component Acl.
class SomethingsController extends AppController {
// Vous pourriez placer dans AppController
// mais cela fonctionne bien ici aussi.
public $components = array('Acl');
Components (Composants)
585
Configurons quelques permissions de base, en utilisant le Component Acl dans une action lintrieur de
ce controller.
public function index() {
//Autorise un accs complet aux armes pour les guerriers
//Ces exemples utilisent tous deux la syntaxe avec un alias
$this->Acl->allow('guerriers', 'Armes');
//Encore que le Roi pourrait ne pas vouloir laisser n'importe qui
//disposer d'un accs sans limites
$this->Acl->deny('guerrier/Legolas', 'Armes', 'delete');
$this->Acl->deny('guerrier/Gimli',
'Armes', 'delete');
die(print_r('done', 1));
}
Le premier appel que nous faisons au component Acl donne, tout utilisateur appartenant au groupe ARO
guerriers, un accs total tout ce qui appartient au groupe ACO Armes. Ici nous adressons simplement
les ACOs et AROs daprs leurs alias.
Avez-vous not lusage du troisime paramtre ? Cest l o nous utilisons ces actions bien pratiques qui
sont intgres tous les ACOs de CakePHP. Les options par dfaut pour ce paramtre sont create, read,
update et delete, mais vous pouvez ajouter une colonne dans la table aros_acos de la base de donnes (prfixe avec _ - par exemple _admin) et lutiliser en parallle de celles par dfaut.
Le second ensemble dappels est une tentative daffiner les permissions. Nous voulons quAragorn conserve
ses privilges de plein accs, mais nous refusons aux autres guerriers du groupe, la capacit de supprimer
les enregistrements de la table Armes. Nous utilisons la syntaxe avec un alias pour adresser les AROs cidessus, mais vous pourriez utiliser votre propre syntaxe model/cl trangre. Ce que nous avons ci-dessus
est quivalent ceci :
// 6342 = Legolas
// 1564 = Gimli
$this->Acl->deny(
array('model' => 'User', 'foreign_key' => 6342),
'Weapons',
'delete'
);
$this->Acl->deny(
array('model' => 'User', 'foreign_key' => 1564),
'Weapons',
'delete'
);
Note : Ladressage dun nud en utilisant la syntaxe avec un alias, ncessite une chane dlimite par des slashs (/utilisateurs/salaries/developpeurs). Ladressage dun nud en utilisant la syntaxe model/cl trangre ncessite un tableau avec deux paramtres : array(model => User,
foreign_key => 8282).
586
La prochaine section nous aidera valider notre configuration, en utilisant le component Acl pour contrler
les permissions que nous venons de dfinir.
Vrification des Permissions : le Component ACL Utilisons le Component Acl pour nous assurer que
les nains et les elfes ne peuvent dplacer des choses depuis larmurerie. Maintenant, nous devrions tre en
mesure dutiliser le Component Acl, pour faire une vrification entre les ACOs et les AROs que nous avons
crs. La syntaxe de base pour faire une vrification des permissions est :
$this->Acl->check($aro, $aco, $action = '*');
'Armes');
'Armes', 'create');
'Armes', 'read');
'Armes', 'update');
'Armes', 'delete');
Lusage fait ici est dmonstratif, mais vous pouvez sans doute voir comment une telle vrification peut tre
utilise, pour dcider quel moment autoriser, ou pas, quelque chose se produire, pour afficher un message
derreur ou rediriger lutilisateur vers un login.
Helpers (Assistants)
CakePHP dispose dun certain nombre de helpers qui aident la cration de vues. Ils aident la cration
dun balisage bien form (y compris les formulaires), laide au formatage du texte, des temps et des nombres,
et peut mme intgrer des bibliothques JavaScript populaires. Voici un rsum des helpers intgrs.
Lire Helpers (Assistants) pour en apprendre plus sur les helpers, leur API, et comment vous pouvez crer et
utiliser vos propres helpers.
Helpers (Assistants)
587
Helpers (Assistants)
CakePHP dispose dun certain nombre de helpers qui aident la cration de vues. Ils aident la cration
dun balisage bien form (y compris les formulaires), laide au formatage du texte, des temps et des nombres,
et peut mme intgrer des bibliothques JavaScript populaires. Voici un rsum des helpers intgrs.
Lire Helpers (Assistants) pour en apprendre plus sur les helpers, leur API, et comment vous pouvez crer et
utiliser vos propres helpers.
CacheHelper
class CacheHelper(View $view, array $settings = array())
Le helper Cache permet la mise en cache des layouts (mises en page) et des vues permettant de gagner du
temps pour la rcupration de donnes rptitives. Le systme de cache des vues de CakePHP parse les
layout et les vues comme de simple fichier PHP + HTML. Il faut noter que le helper Cache fonctionne de
faon assez diffrente des autres helpers. Il ne possde pas de mthodes appeles directement. A la place,
une vue est marque de tags, indiquant quels blocs de contenus ne doivent pas tre mis en cache. Le Helper
Cache utilise alors les callbacks du helper pour traiter le fichier et ressortir pour gnrer le fichier de cache.
Quand une URL est appele, CakePHP vrifie si cette requte a dj t mise en cache. Si cest le cas, le
processus de distribution de lURL est abandonn. Chacun des blocs non mis en cache sont rendus selon le
processus normal, et la vue est servie. Cela permet de gagner beaucoup de temps pour chaque requte vers
une URL mise en cache, puisquun minimum de code est excut. Si CakePHP ne trouve pas une vue mise
en cache, ou si le cache a expir pour lURL appele, le processus de requte normal se poursuit.
Utilisation du Helper
Il y a deux tapes franchir avant de pouvoir utiliser le Helper Cache. Premirement dans votre
APP/Config/core.php d-commenter lappel Configure write pour Cache.check. Ceci dira
CakePHP de regarder dans le cache, et de gnrer laffichage des fichiers en cache lors du traitement des
demandes.
Une fois que vous avez dcomment la ligne Cache.check vous devez ajouter le helper votre tableau
$helpers de votre controller :
class PostsController extends AppController {
public $helpers = array('Cache');
}
Vous devrez aussi ajouter CacheDispatcher vos filtres de dispatcher dans votre bootstrap :
Configure::write('Dispatcher.filters', array(
'CacheDispatcher'
));
Introduit dans la version 2.3 : Si vous avez une configuration avec des domaines ou des langages multiples,
vous pouvez utiliser Configure : :write(Cache.viewPrefix, YOURPREFIX) ; pour stocker les fichiers de
vue prfixs mis en cache.
588
Ceci mettra en cache laction view 10 heures et laction index 13 heures. En plaant une valeur usuelle de
strtotime() dans $cacheAction vous pouvez mettre en cache toutes les actions dans le controller :
public $cacheAction = "1 hour";
Vous pouvez aussi activer les callbacks controller/component pour les vues caches cres avec
CacheHelper. Pour faire cela, vous devez utiliser le format de tableau pour $cacheAction et crer
un tableau comme ceci :
public $cacheAction = array(
'view' => array('callbacks' => true, 'duration' => 21600),
'add' => array('callbacks' => true, 'duration' => 36000),
'index' => array('callbacks' => true, 'duration' => 48000)
);
En paramtrant callbacks => true vous dites au CacheHelper (Assistant Cache) que vous voulez que
les fichiers gnrs crent les components et les models pour le controller. De manire additionnelle, lance la
mthode initialize du component, le beforeFilter du controller, et le dmarrage des callbacks de component.
Note : Dfinir callbacks => true fait chouer en partie le but de la mise en cache. Cest aussi la raison pour
laquelle ceci est dsactiv par dfaut.
Il y aura des fois o vous ne voudrez par mettre en cache une vue intgrale. Par exemple, certaines parties
dune page peuvent tre diffrentes, selon que lutilisateur est actuellement identifi ou quil visite votre site
en tant quinvit.
Pour indiquer que des blocs de contenu ne doivent pas tre mis en cache, entourez-les par < !nocache>
< !/nocache> comme ci-dessous :
<!--nocache-->
<?php if ($this->Session->check('User.name')) : ?>
Bienvenue, <?php echo h($this->Session->read('User.name')); ?>.
<?php else: ?>
Helpers (Assistants)
589
Note : Vous ne pouvez pas utiliser les tags nocache dans les lments. Puisquil ny a pas de callbacks
autour des lments, ils ne peuvent tre cachs.
Il est noter, quune fois une action mise en cache, la mthode du controller correspondante ne sera plus
appele. Quand un fichier cache est cr, lobjet request, et les variables de vues sont srialises avec
serialize() de PHP.
Avertissement : Si vous avez des variables de vues qui contiennent des contenus inserialisable comme
les objets SimpleXML, des gestionnaires de ressource (resource handles), ou des classes closures Il se
peut que vous ne puissiez pas utiliser la mise en cache des vues.
Nettoyer le Cache
Il est important de se rappeler que CakePHP va nettoyer le cache si un model utilis dans la vue mise en
cache a t modifi. Par exemple, si une vue mise en cache utilise des donnes du model Post et quil y a
eu une requte INSERT, UPDATE, ou DELETE sur Post, le cache de cette vue est nettoy, et un nouveau
contenu sera gnr la prochaine requte.
Note : Ce systme de nettoyage automatique requiert que le nom du controller/model fasse partie de lURL.
Si vous avez utilis le routing pour changer vos URLs cela ne fonctionnera pas.
Si vous avez besoin de nettoyer le cache manuellement, vous pouvez le faire en appelant Cache : :clear().
Cela nettoiera toutes les donnes mises en cache, lexception des fichiers de vues mis en cache. Si vous
avez besoin de nettoyer les fichiers de vues, utilisez clearCache().
Flash
class FlashHelper(View $view, array $config = array())
FlashHelper fournit une faon de rendre les messages flash qui sont dfinis dans $_SESSION par FlashComponent. FlashComponent et FlashHelper utilisent principalement des elements pour rendre les messages
flash. Les elements flash se trouvent dans le rpertoire app/View/Elements/Flash. Vous remarquerez
que le template de lApp de CakePHP est livr avec deux elements flash : success.ctp et error.ctp.
FlashHelper remplace la mthode flash() de SessionHelper et doit tre utilis la place de cette
mthode.
Rendre les Messages Flash
Pour afficher un message flash, vous pouvez simplement utiliser la mthode render() du FlashHelper :
590
Par dfaut, CakePHP utilise une cl flash pour les messages flash dans une session. Mais si vous spcifiez
une cl lors de la dfinition du message flash dans FlashComponent, vous pouvez spcifier la cl flash
rendre :
<?php echo $this->Flash->render('other') ?>
Vous pouvez aussi surcharger toutes les options qui sont dfinies dans FlashComponent :
// Dans votre Controller
$this->Flash->set('The user has been saved.', array(
'element' => 'success'
));
// Dans votre View: Va utiliser great_success.ctp au lieu de success.ctp
<?php echo $this->Flash->render('flash', array(
'element' => 'great_success'
));
Note : Par dfaut, CakePHP nchappe pas le HTML dans les messages flash. Si vous utilisez une requte
ou des donnes dutilisateur dans vos messages flash, vous devez les chapper avec h lors du formatage de
vos messages.
Pour plus dinformations sur le tableau doptions disponibles, consultez la section FlashComponent.
FormHelper
class FormHelper(View $view, array $settings = array())
Le Helper Form prend en charge la plupart des oprations lourdes en cration du formulaire. Le Helper
Form se concentre sur la possibilit de crer des formulaires rapidement, dune manire qui permettra de
rationaliser la validation, la re-population et la mise en page (layout). Le Helper Form est aussi flexible
- Il va faire peu prs tout pour vous en utilisant les conventions, ou vous pouvez utiliser des mthodes
spcifiques pour ne prendre uniquement que ce dont vous avez besoin.
Cration de Formulaire
La premire mthode dont vous aurez besoin dutiliser pour prendre pleinement avantage du Helper Form
(Helper Formulaire) est create(). Cette mthode affichera un tag douverture de formulaire.
FormHelper::create(string $model = null, array $options = array())
Tous les paramtres sont optionnels. Si create() est appele sans paramtres, CakePHP supposera
que vous voulez crer un formulaire en rapport avec le controller courant, ou lURL actuelle. La
mthode par dfaut pour les formulaires est POST. Llment du formulaire est galement renvoy
avec un DOM ID. Cet identifiant est cr partir du nom du model, et du nom du controller en
notation CamelCase (les majuscules dlimitent les mots). Si jappelle create() dans une vue de
UsersController, jobtiendrai ce genre de rendu dans ma vue :
Helpers (Assistants)
591
Note :
Vous pouvez aussi passer false pour $model. Ceci placera vos donne de formulaire dans le tableau : $this->request->data (au lieu du sous
tableau :$this->request->data[Model]). Cela peut tre pratique pour des formulaires courts qui ne reprsenteraient rien dans votre base de donnes.
La mthode create() nous permet galement de personnaliser plusieurs paramtres. Premirement,
vous pouvez spcifier un nom de model. Ce faisant, vous modifiez le contexte de ce formulaire. Tous
les champs seront supposs dpendre de ce model (sauf si spcifi), et tous les models devront tre
lis lui. Si vous ne spcifiez pas de model, CakePHP supposera que vous utilisez le model par dfaut
pour le controller courant.
// si vous tes sur /recipes/add
echo $this->Form->create('Recipe');
Affichera :
<form id="RecipeAddForm" method="post" action="/recipes/add">
Affichera :
<form id="RecipeEditForm" method="post" action="/recipes/edit/5">
<input type="hidden" name="_method" value="PUT" />
Note : Comme cest un formulaire de modification, un champ cach (hidden) est cr pour rcrire
la mthode HTTP par dfaut
592
A la cration de formulaires pour les models dans des plugins. Nous devrons toujours utiliser la
syntaxe de plugin la cration dun formulaire. Cela assurera que le formulaire est correctement
gnr :
echo $this->Form->create('ContactManager.Contact');
Le tableau $options est lendroit o la plupart des paramtres de configurations sont stocks. Ce
tableau spcial peut contenir un certain nombre de paires cl-valeur qui peuvent affecter la manire
dont le formulaire sera cr.
Modifi dans la version 2.0.
LUrl par dfaut pour tous les formulaires, est maintenant lUrl incluant passed, named, et les
paramtres de requte (querystring). Vous pouvez redfinir cette valeur par dfaut en fournissant
$options[url] en second paramtre de $this->Form->create().
Options pour create() Il y plusieurs options pour create() :
$options[type] Cette cl est utilise pour spcifier le type de formulaire crer. Les valeurs que
peuvent prendre cette variable sont post, get, file, put et delete.
Choisir post ou get changera la mthode de soumission du formulaire en fonction de votre choix.
echo $this->Form->create('User', array('type' => 'get'));
Affichera :
<form id="UserAddForm" method="get" action="/users/add">
Affichera :
<form id="UserAddForm" enctype="multipart/form-data"
method="post" action="/users/add">
Quand vous utilisez put ou delete, votre formulaire aura un fonctionnement quivalent un formulaire
de type post, mais quand il sera envoy, la mthode de requte HTTP sera respectivement rcrite avec
PUT ou DELETE. Cela permettra CakePHP de crer son propre support REST dans les navigateurs
web.
$options[action] La cl action vous permet de dfinir vers quelle action de votre controller
pointera le formulaire. Par exemple, si vous voulez que le formulaire appelle laction login() de votre
controller courant, vous creriez le tableau $options comme ceci
echo $this->Form->create('User', array('action' => 'login'));
Affichera :
<form id="UserLoginForm" method="post" action="/users/login">
</form>
Helpers (Assistants)
593
$options[url] Si laction que vous dsirez appeler avec le formulaire nest pas dans le controller
courant, vous pouvez spcifier une URL dans le formulaire en utilisant la cl url de votre tableau $options. LURL ainsi fournie peut tre relative votre application CakePHP
echo $this->Form->create(null, array(
'url' => array('controller' => 'recipes', 'action' => 'add')
));
Affichera :
<form method="post" action="/recipes/add">
Affichera :
<form method="get" action="http://www.google.com/search">
Regardez aussi la mthode HtmlHelper::url() pour plus dexemples sur les diffrents types
dURLs.
$options[default] Si la variable default est dfinie false, laction de soumission du formulaire est change de telle manire que le bouton submit (de soumission) ne soumet plus le formulaire.
Si le formulaire a t cr pour tre soumis par AJAX, mettre la variable default FALSE supprime
le comportement par dfaut du formulaire, ainsi vous pouvez collecter les donnes et les soumettre par
AJAX la place.
$options[inputDefaults] Vous pouvez dclarer un jeu doptions par dfaut pour input()
avec la cl inputDefaults pour personnaliser vos input par dfaut :
echo $this->Form->create('User', array(
'inputDefaults' => array(
'label' => false,
'div' => false
)
));
Tous les input crs partir de ce point hriteraient des options dclares dans inputDefaults. Vous pouvez
redfinir le defaultOptions en dclarant loption dans lappel input() :
// Pas de div, Pas de label
echo $this->Form->input('password');
// a un lment label
echo $this->Form->input('username', array('label' => 'Username'));
Fermer le Formulaire
594
permet galement au FormHelper dajouter les champs caches dont le component Security
SecurityComponent besoin. :
<?php echo $this->Form->create(); ?>
<!-- Ici les lments de Formulaire -->
<?php echo $this->Form->end(); ?>
Si une chane est fournie comme premier argument end(), le FormHelper affichera un bouton submit
nomm en consquence en mme temps que la balise de fermeture du formulaire.
echo $this->Form->end('Termine');
Affichera :
<div class="submit">
<input type="submit" value="Termine" />
</div>
</form>
Affichera :
<div class="glass-pill"><input type="submit" value="Update!" name="Update"></div>
Il y a plusieurs faons pour crer des Forms inputs (entre de formulaire) Commenons par regarder
input(). Cette mthode inspecte automatiquement le champ du model qui lui est fourni afin de crer
une entre approprie pour ce champ. En interne input() dlgue aux autre mthode du FormHelper.
FormHelper::input(string $fieldName, array $options = array())
Cre les lments suivants en donnant un Model.field particulier :
div enveloppante (wrapping div).
label de llment (Label element)
12. http ://api.cakephp.org/2.4/class-FormHelper.html
Helpers (Assistants)
595
//text
//password
//day, month, year, hour, minute,
//meridian
//textarea
echo $this->Form->end('Add');
596
Outre les options spcifique pour input() vu ci-dessus, vous pouvez spcifier nimporte quelle
options pour le type dinput et nimporte quel attribut HTML (actuellement dans le focus). Pour plus
dinformation sur les $options et $htmlAttributes voir HTMLHelper.
Supposons un User hasAndBelongsToMany Group. Dans votre controller, dfinissez une variable
camelCase au pluriel (groupe -> groupes dans cette exemple, ou ExtraFunkyModele -> extraFunkyModeles) avec les options de slections. Dans laction du controller vous pouvez dfinir
$this->set('groups', $this->User->Group->find('list'));
Et dans la vue une slection multiple peut tre cre avec ce simple code :
echo $this->Form->input('Group');
Si vous voulez un champ de slection utilisant une relation belongsTo ou hasOne, vous pouvez ajouter
ceci dans votre controller Users (en supposant que lUser belongsTo Group) :
$this->set('groups', $this->User->Group->find('list'));
Si votre nom de model est compos de deux mots ou plus, ex. UserGroup, quand vous passez les
donnes en utilisant set() vous devrez nommer vos donnes dans un format CamelCase (les Majuscules sparent les mots) et au pluriel comme ceci
$this->set('userGroups', $this->UserGroup->find('list'));
// ou bien
$this->set(
'reallyInappropriateModelNames',
$this->ReallyInappropriateModelName->find('list')
);
Note : Essayez dviter lutilisation de FormHelper : :input() pour gnrer les boutons submit.
Utilisez plutt FormHelper::submit().
FormHelper::inputs(mixed $fields = null, array $blacklist = null, $options = array())
Gnre un ensemble dinputs (entres) pour $fields. Si $fields est null, tous les champs, sauf ceux
dfinis dans $blacklist, du model courant seront utiliss.
En plus de laffichage des champs de controller, $fields peut tre utilis pour contrler legend et fieldset (jeu de champs) rendus avec les cls fieldset et legend.
$form->inputs(array(legend => Ma lgende)); Gnrera un jeu de champs input avec une lgende personnalise. Vous pouvez personnaliser des champs input individuels a travers
$fields comme ceci.
echo $form->inputs(array(
'name' => array('label' => 'label perso')
));
Helpers (Assistants)
597
En plus des champs de contrle (fields control), inputs() permet dutiliser quelques options supplmentaires.
fieldset Mis false pour dsactiver le jeu de champs (fieldset). Si une chane est fournit, elle
sera utilise comme nom de classe (classname) pour llment fieldset.
legend Mis false pour dsactiver la lgende (legend) pour le jeu de champs input (input set)
gnr. Ou fournit une chane pour personnaliser le texte de la lgende (legend).
Conventions de nommage des champs Le Helper Form est assez volu. Lorsque vous dfinissez un
nom de champ avec les mthodes du Helper Form, celui-ci gnre automatiquement une balise input base
sur le nom de model courant, selon le format suivant :
<input type="text" id="ModelnameFieldname" name="data[Modelname][fieldname]">
Ceci permet domettre le nom du model lors de la gnration des inputs du model pour lequel le formulaire
t cr. Vous pouvez crez des inputs pour des models associs , ou des models arbitraires en passant
dans Modelname.fieldname comme premier paramtre :
echo $this->Form->input('Modelname.fieldname');
Si vous avez besoin de spcifier de multiples champs en utilisant le mme nom de champ, crant ainsi un
tableau qui peut tre sauver en un coup avec saveAll(), utilisez les conventions suivantes :
echo $this->Form->input('Modelname.0.fieldname');
echo $this->Form->input('Modelname.1.fieldname');
Affichera :
<input type="text" id="Modelname0Fieldname"
name="data[Modelname][0][fieldname]">
<input type="text" id="Modelname1Fieldname"
name="data[Modelname][1][fieldname]">
Le Helper Form utilise plusieurs suffixes de champ en interne pour la cration de champ input datetime. Si
vous utilisez des champs nomms year, month, day, hour, minute, or meridian et rencontrez des
problmes pour obtenir un input correct, vous pouvez dfinir le nom name de lattribut pour remplacer le
behavior par dfaut :
echo $this->Form->input('Model.year', array(
'type' => 'text',
'name' => 'data[Model][year]'
));
598
Affichera :
<div class="input file">
<label for="UserField">Field</label>
<input type="file" name="data[User][field]" value="" id="UserField" />
</div>
<div class="input email">
<label for="UserEmail">Email</label>
<input type="email" name="data[User][email]" value="" id="UserEmail" />
</div>
$options[div] Utilisez cette option pour dfinir les attributs de la div contentant linput. En utilisant une valeur chane configurera le nom de classe de la div. Un tableau cls/valeurs paramtrera les
attributs de la div. Alternativement, vous pouvez dfinir cet cl false pour dsactiver le rendu de la div.
Dfinir le nom de classe :
echo $this->Form->input('User.name', array(
'div' => 'class_name'
));
Affichera :
<div class="class_name">
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
<div class="input text" id="mainDiv" title="Div Title"
style="display:block">
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
Helpers (Assistants)
599
$options[label] Dfinissez cette cl la chane que vous voudriez afficher dans le label qui
accompagne le input :
echo $this->Form->input('User.name', array(
'label' => "Alias de l'user"
));
Affichera :
<div class="input">
<label for="UserName">Alias de l'user</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Affichera :
<div class="input">
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
Dfinissez ceci dans un tableau pour fournir des options supplmentaires pour llment label. Si vous
faites cela, vous pouvez utiliser une cl text dans le tableau pour personnaliser le texte du label :
echo $this->Form->input('User.name', array(
'label' => array(
'class' => 'bidule',
'text' => 'le traducteur est fou hihaaarrrr!!!'
)
));
Affichera :
<div class="input">
<label for="UserName" class="bidule">le traducteur est fou hihaaarrrr!!!</label>
<input name="data[User][name]" type="text" value="" id="UserName" />
</div>
$options[error] En utilisant cette cl vous permettra de transformer les messages de model par
dfaut et de les utiliser, par exemple, pour dfinir des messages i18n. (cf internationalisation). comporte
un nombre de sous-options qui contrles lenveloppe de llment (wrapping) . Le nom de classe de
llment envelopp, ainsi que les messages derreurs qui contiennent du HTML devront tre chapps.
Pour dsactiver le rendu des messages derreurs dfinissez la cl error false :
$this->Form->input('Model.field', array('error' => false));
Pour viter que le code HTML soit automatiquement chapp dans le rendu du message derreur, dfinissez la sous-option escape false :
600
$this->Form->input('Model.field', array(
'error' => array(
'attributes' => array('escape' => false)
)
));
Pour surcharger les messages derreurs du model utilisez un tableau avec les cls respectant les rgles de
validation :
$this->Form->input('Model.field', array(
'error' => array('tooShort' => __("Ceci n'est pas assez long"))
));
Comme vu ci-dessus vous pouvez dfinir les messages derreurs pour chacune des rgles de validation de
vos models. Vous pouvez de plus fournir des messages i18n pour vos formulaires.
Introduit dans la version 2.3 : Support pour loption errorMessage a t ajout dans 2.3
$options[before],
$options[between],
$options[separator],
et
$options[after]
Utilisez ces cls si vous avez besoin dinjecter quelques balises la sortie de la mthode input().
echo $this->Form->input('field', array(
'before' => '--avant--',
'after' => '--aprs--',
'between' => '--entre---'
));
Affichera :
<div class="input">
--avant-<label for="UserField">Field</label>
--entre--<input name="data[User][field]" type="text" value="" id="UserField" />
--aprs-</div>
Pour les input de type radio lattribut separator peut tre utilis pour injecter des balise pour sparer
input/label.
echo $this->Form->input('field', array(
'before' => '--avant--',
'after' => '--aprs--',
'between' => '--entre---',
'separator' => '--sparateur--',
'options' => array('1', '2')
));
Affichera :
<div class="input">
--avant-<input name="data[User][field]" type="radio" value="1" id="UserField1" />
<label for="UserField1">1</label>
--sparateur-<input name="data[User][field]" type="radio" value="2" id="UserField2" />
Helpers (Assistants)
601
<label for="UserField2">2</label>
--entre----aprs-</div>
Pour un lment de type date et datetime lattribut separator peut tre utilis pour modifier la chane
entre les select. Par dfaut -.
$options[format] Lordre du code HTML gnr par FormHelper est contrlable comme vous le
souhaitez. loption format supporte un tableau de chane dcrivant le model de page que vous voudriez
que llment suive. Les cls de tableau supportes sont :
array('before', 'input', 'between', 'label', 'after','error')
$options[inputDefaults] Sil vous semble rpter la mme option dans de multiples appels
input(), vous pouvez utiliser inputDefaults pour garder un code propre.
echo $this->Form->create('User', array(
'inputDefaults' => array(
'label' => false,
'div' => false
)
));
Tous les inputs crs a partir de ce point hriterons des valeurs dclares dans inputDefaults. Vous pouvez
redfinir defaultOptions en dclarant loption dans lappel de linput() :
// Pas de div, ni label
echo $this->Form->input('password');
// a un lment label
echo $this->Form->input('username', array('label' => 'Username'));
Si vous avez besoin de changer plus tard les valeurs par dfaut, vous pourrez utiliser
FormHelper::inputDefaults().
GET Form Inputs Quand vous utilisez FormHelper pour gnrer des inputs pour les formulaires GET,
les noms dinput seront automatiquement raccourcis pour que les noms soient plus lisibles pour les humains.
Par exemple :
// Cre <input name="email" type="text" />
echo $this->Form->input('User.email');
// Cre <select name="Tags" multiple="multiple">
echo $this->Form->input('Tags.Tags', array('multiple' => true));
Si vous voulez surcharger les attributs name gnrs, vous pouvez utiliser loption name :
// Cre le plus habituel <input name="data[User][email]" type="text" />
echo $this->Form->input('User.email', array('name' => 'data[User][email]'));
602
En plus de la mthode gnrique input(), le FormHelper des mthodes spcifiques pour gnrer
diffrents types dinputs. Ceci peut tre utilis pour gnrer juste un extrait de code input, et combin avec
dautres mthodes comme label() et error() pour gnrer des layouts (mise en page) compltements
personnalises.
Options Communes Beaucoup des diffrentes mthodes dinput supportent un jeu doptions communes.
Toutes ses options sont aussi supports par input(). Pour rduire les rptitions les options communes
partages par toutes les mthodes input sont :
$options[class] Vous pouvez dfinir le nom de classe pour un input :
echo $this->Form->input('title', array('class' => 'class-perso'));
$options[id] Dfinir cette cl pour forcer la valeur du DOM id pour cet input.
$options[default] Utilis pour dfinir une valeur par dfaut au champ input. La valeur est
utilise si les donnes passes au formulaire ne contiennent pas de valeur pour le champ (ou si aucune
donne nest transmise)
Exemple dutilisation :
echo $this->Form->input('ingredient', array('default' => 'Sucre'));
Exemple avec un champ slectionn (Taille Moyen sera slectionn par dfaut) :
$sizes = array('s' => 'Small', 'm' => 'Medium', 'l' => 'Large');
echo $this->Form->input('size', array('options' => $sizes, 'default' => 'm'));
Note : Vous ne pouvez pas utiliser default pour slectionner une chekbox - vous devez plutt dfinir
cette valeur dans $this->request->data dans votre controller, ou dfinir loption checked de
input true.
La valeur par dfaut des champs Date et datetime peut tre dfinie en utilisant la cl selected.
Attention lutilisation de false pour assigner une valeur par dfaut. Une valeur false est utilis pour
dsactiver/exclure les options dun champ, ainsi default => false ne dfinirait aucune valeur.
A la place, utilisez default => 0.
En plus des options ci-dessus, vous pouvez mixer nimporte quel attribut HTML que vous souhaitez utiliser.
Chacun des nom doptions non-special sera trait comme un attribut HTML, et appliqu a llment HTML
gnr.
Les options pour select, checkbox et inputs radio
$options[selected] Utilis en combinaison avec un input de type select (ex. Pour les types
select, date, heure, datetime) . Dfinissez selected pour dfinir llment que vous souhaiteriez dfinir
par dfaut au rendu de linput :
echo $this->Form->input('heure_fermeture', array(
'type' => 'time',
'selected' => '13:30:00'
));
Helpers (Assistants)
603
Note : La cl selected pour les inputs de type date et datetime peuvent aussi tre des timestamps UNIX.
$options[empty] Est dfini true, pour forcer linput rester vide.
Quand pass une list select (liste de selection), ceci crera une option vide avec une valeur vide dans la
liste droulante. Si vous voulez une valeur vide avec un texte affich ou juste une option vide, passer une
chane pour vider :
echo $this->Form->input('field', array(
'options' => array(1, 2, 3, 4, 5),
'empty' => '(choisissez)'
));
Sortie:
.. code-block:: html
<div class="input">
<label for="UserField">Field</label>
<select name="data[User][field]" id="UserField">
<option value="">(choisissez)</option>
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
<option value="3">4</option>
<option value="4">5</option>
</select>
</div>
Note : Si vous avez besoin de dfinir la valeur par dfaut dun champ password vide, utilisez value=>
(deux fois simple cote) la place.
Une liste de paire de cl-valeur peut tre fournie pour un champ de type date ou datetime :
echo $this->Form->dateTime('Contact.date', 'DMY', '12',
array(
'empty' => array(
'day' => 'DAY', 'month' => 'MONTH', 'year' => 'YEAR',
'hour' => 'HOUR', 'minute' => 'MINUTE', 'meridian' => false
)
)
);
Affiche :
<select name="data[Contact][date][day]" id="ContactDateDay">
<option value="">DAY</option>
<option value="01">1</option>
// ...
<option value="31">31</option>
</select> - <select name="data[Contact][date][month]" id="ContactDateMonth">
<option value="">MONTH</option>
<option value="01">January</option>
604
// ...
<option value="12">December</option>
</select> - <select name="data[Contact][date][year]" id="ContactDateYear">
<option value="">YEAR</option>
<option value="2036">2036</option>
// ...
<option value="1996">1996</option>
</select> <select name="data[Contact][date][hour]" id="ContactDateHour">
<option value="">HOUR</option>
<option value="01">1</option>
// ...
<option value="12">12</option>
</select>:<select name="data[Contact][date][min]" id="ContactDateMin">
<option value="">MINUTE</option>
<option value="00">00</option>
// ...
<option value="59">59</option>
</select> <select name="data[Contact][date][meridian]" id="ContactDateMeridian">
<option value="am">am</option>
<option value="pm">pm</option>
</select>
$options[hiddenField] Pour certain types d input (checkboxes, radios) un input cach est
cr ainsi la cl dans $this->request->data existera mme sans valeur spcifie :
<input type="hidden" name="data[Post][Published]" id="PostPublished_" value="0" />
<input type="checkbox" name="data[Post][Published]" value="1" id="PostPublished" />
Retournera :
<input type="checkbox" name="data[Post][Published]" value="1" id="PostPublished" />
Si vous voulez crer de multiples blocs dentrs regroups ensemble dans un formulaire, vous devriez
utiliser ce paramtre sur tous les inputs except le premier. Si le input cach est en place diffrents
endroits cest seulement le dernier groupe de valeur dinput qui sera sauvegard.
Dans cet exemple , seules les couleurs tertiaires seront passes, et les couleurs primaires seront rcrite :
<h2>Couleurs Primaires</h2>
<input type="hidden" name="data[Color][Color]" id="Couleurs_" value="0" />
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursRouges" />
<label for="CouleursRouges">Rouge</label>
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursBleus" />
<label for="CouleursBleus">Bleu</label>
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursJaunes" />
<label for="CouleursJaunes">Jaune</label>
<h2>Couleurs Tertiaires</h2>
<input type="hidden" name="data[Color][Color]" id="Couleurs_" value="0" />
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursVertes" />
<label for="CouleursVertes">Vert</label>
<input type="checkbox" name="data[Color][Color][]" value="5" id="CouleursPourpres" />
Helpers (Assistants)
605
<label for="CouleursPourpres">Pourpre</label>
<input type="checkbox" name="data[Addon][Addon][]" value="5" id="CouleursOranges" />
<label for="CouleursOranges">Orange</label>
En dsactivant le champ cach hiddenField dans le second groupe dinput empchera ce behavior.
Vous pouvez dfinir une valeur diffrente pour le champ cach autre que 0 comme N :
echo $this->Form->checkbox('published', array(
'value' => 'Y',
'hiddenField' => 'N',
));
Crera 4 options dans la select box minute. Une toute les 15 minutes.
$options[round] Peut tre dfini up ou down pour forcer larrondi dans quelque soit la direction. Par dfaut null qui arrondit la moiti suprieure selon interval.
Introduit dans la version 2.4.
lments de Formulaire-Mthodes spcifiques
Tous les elements sont crs dans un form pour le model User comme dans les exemples ci-dessous.
Pour cette raison, le code HTML gnr contiendra des attributs qui font rfrence au model User Ex :
name=data[User][username], id=UserUsername
FormHelper::label(string $fieldName, string $text, array $options)
Cre un lment label. $fieldName est utilis pour gnrer le Dom id. Si $text nest pas dfini,
$fieldName sera utilis pour dfinir le texte du label :
echo $this->Form->label('User.name');
echo $this->Form->label('User.name', 'Your username');
Affichera :
606
<label for="UserName">Name</label>
<label for="UserName">Your username</label>
$options peut soit tre un tableau dattributs HTML, ou une chane qui sera utilise comme nom
de classe :
echo $this->Form->label('User.name', null, array('id' => 'user-label'));
echo $this->Form->label('User.name', 'Your username', 'highlight');
Affichera :
<label for="UserName" id="user-label">Name</label>
<label for="UserName" class="highlight">Your username</label>
Affichera :
<input name="data[User][username]" type="text" class="users" id="UserUsername" />
Affichera :
<input name="data[User][password]" value="" id="UserPassword" type="password">
Affichera :
<input name="data[User][id]" id="UserId" type="hidden">
Si le form est dit (qui est le tableau $this->request->data va contenir les informations
sauvegardes pour le model User), la valeur correspondant au champ id sera automatiquement
ajoute au HTML gnr. Exemple pour data[User][id] = 10 :
<input name="data[User][id]" id="UserId" type="hidden" value="10" />
Modifi dans la version 2.0 : Les champs cachs nenlvent plus la classe attribute. Cela signifie que
si il y a des erreurs de validation sur les champs cachs, le nom de classe error-field sera appliqu.
FormHelper::textarea(string $fieldName, array $options)
Cre un champ input textarea (zone de texte).
Helpers (Assistants)
607
echo $this->Form->textarea('notes');
Affichera :
<textarea name="data[User][notes]" id="UserNotes"></textarea>
Si le form est dit (ainsi, le tableau $this->request->data va contenir les informations sauvegardes pour le model User), la valeur correspondant au champs notes sera automatiquement
ajoute au HTML gnr. Exemple :
<textarea name="data[User][notes]" id="UserNotes">
Ce texte va tre dit.
</textarea>
Note : Le type dinput textarea permet lattribut $options dchapper escape lequel
dtermine si oui ou non le contenu du textarea doit tre chapp. Par dfaut true.
echo $this->Form->textarea('notes', array('escape' => false);
// OU....
echo $this->Form->input('notes', array('type' => 'textarea', 'escape' => false);
Options
En plus de Options Communes, textarea() supporte quelques options spcifiques :
$options[rows], $options[cols] Ces deux cls spcifient le nombre de lignes et
de colonnes :
echo $this->Form->textarea('textarea', array('rows' => '5', 'cols' => '5'));
Affichera :
<textarea name="data[Form][textarea]" cols="5" rows="5" id="FormTextarea">
</textarea>
Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />
Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />
608
Affichera :
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />
Affichera :
<input
<input
<label
<input
<label
Si pour quelque raisons vous ne voulez pas du input cach, dfinissez $attributes[value]
une valeur slectionne ou le boolen false
Modifi dans la version 2.1 : Loption dattribut $attributes[disabled] a t ajoute dans
CakePHP 2.1.
FormHelper::select(string $fieldName, array $options, array $attributes)
Cre un menu de slection, rempli des lments compris dans $options, avec loption spcifie
par $attributes[value] sera montr comme slectionn par dfaut. Dfinir false la cl
empty dans la variable $attributes pour empcher loption empty par dfaut :
$options = array('H' => 'Homme', 'F' => 'Femme');
echo $this->Form->select('genre', $options)
Affichera :
<select name="data[User][genre]" id="UserGenre">
<option value=""></option>
<option value="H">Homme</option>
<option value="F">Femme</option>
</select>
Linput de type select permet un attribut $option spcial appele escape qui accepte un
boolen et dtermine si il faut que lentit HTML encode le contenu des options slectionnes. Par
dfaut true :
Helpers (Assistants)
609
Affichera :
<select name="data[User][field]" id="UserField">
<option value="0">1</option>
<option value="1">2</option>
<option value="2">3</option>
<option value="3">4</option>
<option value="4">5</option>
</select>
Les options peuvent aussi tre fournies comme des paires cl-valeur :
echo $this->Form->select('field', $options, array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2',
'Value 3' => 'Label 3'
));
Affichera :
<select name="data[User][field]" id="UserField">
<option value="Value 1">Label 1</option>
<option value="Value 2">Label 2</option>
<option value="Value 3">Label 3</option>
</select>
Si vous souhaitez gnrer un select avec des groupes optionnels, passez les donnes dans un format
hirarchique. Ceci fonctionnera avec les checkboxes multiples et les boutons radios galement, mais
au lieu des groupes optionnels enveloppez les lments dans des fieldsets :
$options = array(
'Group 1' => array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
),
'Group 2' => array(
'Value 3' => 'Label 3'
)
);
echo $this->Form->select('field', $options);
Affichera :
<select name="data[User][field]" id="UserField">
<optgroup label="Group 1">
<option value="Value 1">Label 1</option>
<option value="Value 2">Label 2</option>
610
</optgroup>
<optgroup label="Group 2">
<option value="Value 3">Label 3</option>
</optgroup>
</select>
$attributes[multiple] Si multiple a t dfini true pour un input select, celui ci autorisera les slections multiples :
echo $this->Form->select('Model.field', $options, array('multiple' => true));
Vous pouvez galement dfinir checkbox multiple pour afficher une liste de check boxes relis :
$options = array(
'Value 1' => 'Label 1',
'Value 2' => 'Label 2'
);
echo $this->Form->select('Model.field', $options, array(
'multiple' => 'checkbox'
));
Affichera :
Output :
<div class="input select">
<label for="ModelField">Field</label>
<input name="data[Model][field]" value="" id="ModelField"
type="hidden">
<div class="checkbox">
Helpers (Assistants)
611
Modifi dans la version 2.3 : Le support pour les tableaux dans $attributes[disabled] a
t ajoute dans 2.3.
FormHelper::file(string $fieldName, array $options)
Pour ajouter un champ upload un formulaire, vous devez vous assurer que le enctype du formulaire
est dfinit a multipart/form-data, donc commenons avec une fonction create comme ci-dessous :
echo $this->Form->create('Document', array(
'enctype' => 'multipart/form-data'
));
// OU
echo $this->Form->create('Document', array('type' => 'file'));
Ensuite ajoutons lune ou lautre des deux lignes dans le fichier de vue de votre formulaire :
echo $this->Form->input('Document.submittedfile', array(
'between' => '<br />',
'type' => 'file'
));
// OU
echo $this->Form->file('Document.submittedfile');
En raisons des limitations du code HTML lui mme, il nest pas possible de placer des valeurs par
dfauts dans les champs inputs de type file. A chacune des fois ou le formulaire sera affich, la valeur
sera vide.
Lors de la soumission, le champ file fournit un tableau tendu de donnes au script recevant les
donnes de formulaire.
Pour lexemple ci-dessus, les valeurs dans le tableau de donnes soumis devraient tre organises
comme la suite, si CakePHP t install sur un server Windows .tmp_name aura un chemin
diffrent dans un environnement Unix :
$this->request->data['Document']['submittedfile'] = array(
'name' => conference_schedule.pdf,
'type' => application/pdf,
'tmp_name' => C:/WINDOWS/TEMP/php1EE.tmp,
'error' => 0,
'size' => 41737,
);
612
Ce tableau est gnr par PHP lui-mme, pour plus de dtails sur la faon dont PHP gre les donnes
passes a travers les champs files. lire la section file uploads du manuel de PHP 13 .
Validation des Uploads Ci dessous lexemple dune mthode de validation dfinit dans votre model pour
valider si un fichier t uploader avec succs :
public function isUploadedFile($params) {
$val = array_shift($params);
if ((isset($val['error']) && $val['error'] == 0) ||
(!empty( $val['tmp_name']) && $val['tmp_name'] != 'none')
) {
return is_uploaded_file($val['tmp_name']);
}
return false;
}
Affichera :
<form enctype="multipart/form-data" method="post" action="/users/add">
<input name="data[User][avatar]" value="" id="UserAvatar" type="file">
Affichera :
<div class="submit"><input value="Submit" type="submit"></div>
Vous pouvez aussi passer une URL relative ou absolue vers une image pour le paramtre caption au
lieu dun caption text :
echo $this->Form->submit('ok.png');
13. http ://php.net/features.file-upload
Helpers (Assistants)
613
Affichera :
<div class="submit"><input type="image" src="/img/ok.png"></div>
$this->Form->button('Un bouton');
$this->Form->button('Un autre Bouton', array('type' => 'button'));
$this->Form->button('Initialise le Formulaire', array('type' => 'reset'));
$this->Form->button('Soumettre le Formulaire', array('type' => 'submit'));
Affichera :
<button
<button
<button
<button
type="submit">Un bouton</button>
type="button">Un autre Bouton</button>
type="reset">Initialise le Formulaire</button>
type="submit">Soumettre le Formulaire</button>
Le input de type button supporte loption escape qui accepte un boolen et dtermine si oui ou
non lentit HTML encode le $title du bouton. Par dfaut false :
echo $this->Form->button('Submit Form', array('type' => 'submit', 'escape' => true));
Affichera :
<select
<option
<option
<option
<option
<option
<option
<option
<option
name="data[User][purchased][annee]" id="UserPurchasedYear">
value=""></option>
value="2009">2009</option>
value="2008">2008</option>
value="2007">2007</option>
value="2006">2006</option>
value="2005">2005</option>
value="2004">2004</option>
value="2003">2003</option>
<option value="2002">2002</option>
<option value="2001">2001</option>
<option value="2000">2000</option>
</select>
Affichera :
<select
<option
<option
<option
<option
<option
<option
<option
<option
name="data[User][mob][month]" id="UserMobMonth">
value=""></option>
value="01">January</option>
value="02">February</option>
value="03">March</option>
value="04">April</option>
value="05">May</option>
value="06">June</option>
value="07">July</option>
Helpers (Assistants)
615
<option value="08">August</option>
<option value="09">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
Vous pouvez passer votre propre tableau des mois utiliser en paramtrant lattribut monthNames,
ou avoir les mois affichs comme des nombres en passant false. (Note : les mois par dfaut sont
internationaliss et peuvent tre traduits en utilisant la localisation) :
echo $this->Form->month('mob', array('monthNames' => false));
Affichera :
<select name="data[User][created][day]" id="UserCreatedDay">
<option value=""></option>
<option value="01">1</option>
<option value="02">2</option>
<option value="03">3</option>
...
<option value="31">31</option>
</select>
616
FormHelper::isFieldError(string $fieldName)
Retourne true si le champ $fieldName fourni a une erreur de validation en cours :
if ($this->Form->isFieldError('genre')) {
echo $this->Form->error('genre');
}
Tous les champs crs partir ce point de retour vont hriter des options dclares dans inputDefaults. Vous
pouvez surcharger les options par dfaut en dclarant loption dans lappel input() :
SecurityComponent offre plusieurs fonctionnalits qui rendent vos formulaires plus sres et plus
scuriss. En incluant simplement le component scurit SecurityComponent dans votre controller,
vous bnficierez automatiquement de CSRF (Cross-site request forgery) et des fonctionnalits pour viter
la falsification.
Quand vous utilisez le SecurityComponent (component de scurit), vous devez toujours fermer vos formulaires en utilisant FormHelper::end(). Ceci assurera que les inputs jeton spciaux _Token seront
gnrs.
FormHelper::unlockField($name)
Dverrouille un champ en le rendant exempt du hachage (hashing) du SecurityComponent. Ceci
permet galement au champ dtre manipul par Javascript. Le paramtre $name devra tre le nom
dentit de linput :
Helpers (Assistants)
617
$this->Form->unlockField('User.id');
618
Note : Le Helper html est disponible dans toutes les vues par dfaut. Si vous recevez une erreur vous
informant quil nest pas disponible, cest habituellement d a son nom qui a t oubli de la configuration
manuelle de la variable $helpers du controller.
La tche la plus importante que le Helper Html accomplit est la cration dun balisage bien form. Nayez
pas peur de lutiliser souvent - vous pouvez cacher les vues dans cakePHP pour conomiser du temps CPU
quand les vues sont rendues et dlivres. Cette section couvrira les mthodes du Helper Html et comment
les utiliser.
HtmlHelper::charset($charset=null)
Paramtres
$charset (string) Jeu de caractre dsir. Sil est null, la valeur de
App.encoding sera utilise.
Utilis pour crer une balise meta spcifiant le jeu de caractres du document. UTF-8 par dfaut.
Exemple dutilisation :
echo $this->Html->charset();
Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Sinon :
echo $this->Html->charset('ISO-8859-1');
Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
619
echo $this->Html->css('forms');
Affichera :
<link rel="stylesheet" type="text/css" href="/css/forms.css" />
Le premier paramtre peut tre un tableau pour inclure des fichiers multiples.
echo $this->Html->css(array('forms', 'tables', 'menu'));
Affichera :
<link rel="stylesheet" type="text/css" href="/css/forms.css" />
<link rel="stylesheet" type="text/css" href="/css/tables.css" />
<link rel="stylesheet" type="text/css" href="/css/menu.css" />
Vous pouvez inclure un fichier CSS depuis un plugin charg en utilisant syntaxe de plugin. Pour
inclure app/Plugin/DebugKit/webroot/css/toolbar.css, vous pouvez utiliser ce qui
suit :
echo $this->Html->css('DebugKit.toolbar.css');
Si vous voulez inclure un fichier CSS qui partage un nom avec un plugin charg vous pouvez faire ce qui suit. Par exemple vous avez un plugin Blog, et souhaitez inclure galement
app/webroot/css/Blog.common.css :
.. versionchanged:: 2.4
620
<?php
echo $this->Html->meta(
'favicon.ico',
'/favicon.ico',
array('type' => 'icon')
);
?>
// Output (line breaks added)
<link
href="http://example.com/favicon.ico"
title="favicon.ico" type="image/x-icon"
rel="alternate"
/>
<?php
echo $this->Html->meta(
'Comments',
'/comments/index.rss',
array('type' => 'rss')
);
?>
// Output (line breaks added)
<link
href="http://example.com/comments/index.rss"
title="Comments"
type="application/rss+xml"
rel="alternate"
/>
Cette mthode peut aussi tre utilise pour ajouter les balises de mots cls et les descriptions. Exemple :
<?php
echo $this->Html->meta(
'keywords',
'enter any meta keyword here'
);
?>
// Sortie
<meta name="keywords" content="enter any meta keyword here" />
<?php
echo $this->Html->meta(
'description',
'enter any meta description here'
);
?>
// Sortie
<meta name="description" content="enter any meta description here" />
Si vous voulez ajouter une balise personnalise alors le premier paramtre devra tre un tableau. Pour
ressortir une balise de robots noindex, utilisez le code suivant :
echo $this->Html->meta(array('name' => 'robots', 'content' => 'noindex'));
621
Modifi dans la version 2.1 : La valeur par dfaut de doctype est HTML5 avec la version 2.1.
HtmlHelper::style(array $data, boolean $oneline = true)
Paramtres
$data (array) Un ensemble de cl => valeurs avec des proprits CSS.
$oneline (boolean) Le contenu sera sur une seule ligne.
Construit les dfinitions de style CSS en se basant sur les cls et valeurs du tableau pass la mthode.
Particulirement pratique si votre fichier CSS est dynamique.
echo $this->Html->style(array(
'background' => '#633',
'border-bottom' => '1px solid #000',
'padding' => '10px'
));
Affichera
background:#633; border-bottom:1px solid #000; padding:10px;
622
Affichera :
<img src="/img/cake_logo.png" alt="CakePHP" />
Pour crer un lien dimage, spcifiez le lien de destination en utilisant loption url dans
$htmlAttributes.
echo $this->Html->image("recipes/6.jpg", array(
"alt" => "Brownies",
'url' => array('controller' => 'recipes', 'action' => 'view', 6)
));
Affichera :
<a href="/recipes/view/6">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Si vous crez des images dans des mails, ou voulez des chemins absolus pour les images,
vous pouvez utiliser loption fullBase :
echo $this->Html->image("logo.png", array('fullBase' => true));
Affichera :
<img src="http://example.com/img/logo.jpg" alt="" />
Vous pouvez inclure des fichiers images depuis un plugin charg en utilisant la syntaxe
de plugin. Pour inclure app/Plugin/DebugKit/webroot/img/icon.png, vous
pouvez faire cela :
echo $this->Html->image('DebugKit.icon.png');
Si vous voulez inclure un fichier image qui partage un nom avec un plugin charg vous pouvez faire ce qui suit. Par exemple si vous avez in plugin Blog, et voulez inclure galement
app/webroot/js/Blog.icon.png :
echo $this->Html->image('Blog.icon.png', array('plugin' => false));
Helpers (Assistants)
623
echo $this->Html->link(
'Enter',
'/pages/home',
array('class' => 'button', 'target' => '_blank')
);
Affichera :
<a href="/pages/home" class="button" target="_blank">Enter</a>
Affichera :
<a href="http://www.yourdomain.com/dashboards/index">Dashboard</a>
Affichera :
Affichera :
<a href="/images/view/1?height=400&width=500">View image</a>
Quand il y a utilisation de paramtres nomms, utilisez la syntaxe en tableau et incluez les noms
pour TOUS les paramtres dans lURL. En utilisant la syntaxe en chane pour les paramtres (par ex
recipes/view/6/comments :false va rsulter ce que les caractres seront chapps du HTML et le
lien ne fonctionnera pas comme souhait.
624
<?php
echo $this->Html->link(
$this->Html->image("recipes/6.jpg", array("alt" => "Brownies")),
array(
'controller' => 'recipes',
'action' => 'view',
'id' => 6,
'comments' => false
)
);
Affichera :
<a href="/recipes/view/id:6/comments:false">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Les caractres spciaux HTML de $title seront convertis en entits HTML. Pour dsactiver cette
conversion, dfinissez loption escape false dans le tableau $options :
<?php
echo $this->Html->link(
$this->Html->image("recipes/6.jpg", array("alt" => "Brownies")),
"recipes/view/6",
array('escape' => false)
);
Affichera :
<a href="/recipes/view/6">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
Dfinir escape false va aussi dsactiver lchappement des attributs du lien. Puisque depuis 2.4,
vous pouvez utiliser loption escapeTitle pour juste dsactiver lchappement du titre et pas des
attributs.
<?php
echo $this->Html->link(
$this->Html->image('recipes/6.jpg', array('alt' => 'Brownies')),
'recipes/view/6',
array('escapeTitle' => false, 'title' => 'hi "howdy"')
);
Affichera :
<a href="/recipes/view/6" title="hi "howdy"">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>
625
Paramtres
$path (string|array) Chemin du fichier vido, relatif au rpertoire webroot/{$options[pathPrefix]}. Ou un tableau ou chaque lment peut tre la chane
dun chemin ou un tableau associatif contenant les cls src et type.
$options (array) Un tableau dattributs HTML, et doptions spciales.
Options :
type Type dlments mdia gnrer, les valeurs valides sont audio ou
video. Si le type nest pas fourni le type de mdia se basera sur le mime type
du fichier.
text Texte inclure dans la balise vido.
pathPrefix Prfixe du chemin utiliser pour les URLs relatives, par dfaut
files/.
fullBase Si il est fourni lattribut src prendra ladresse complte incluant le nom
de domaine.
Introduit dans la version 2.1.
Retourne une balise formate audio/video :
<?php echo $this->Html->media('audio.mp3'); ?>
// Sortie
<audio src="/files/audio.mp3"></audio>
<?php echo $this->Html->media('video.mp4', array(
'fullBase' => true,
'text' => 'Fallback text'
)); ?>
// Sortie
<video src="http://www.somehost.com/files/video.mp4">Fallback text</video>
<?php echo $this->Html->media(
array(
'video.mp4',
array(
'src' => 'video.ogg',
'type' => "video/ogg; codecs='theora, vorbis'"
)
),
array('autoplay')
); ?>
// Sortie
<video autoplay="autoplay">
<source src="/files/video.mp4" type="video/mp4"/>
<source src="/files/video.ogg" type="video/ogg;
codecs='theora, vorbis'"/>
</video>
< ?php echo $this->Html->tag(span, Bonjour le Monde, array(class => welcome)) ; ?>
// Affichera <span class=welcome>Bonjour le Monde</span>
// Pas de texte spcifi. < ?php echo $this->Html->tag(span, null, array(class => welcome)) ; ?>
// Affichera <span class=welcome>
Note :
Le texte nest pas chapp par dfaut mais vous pouvez utiliser
$htmlOptions[escape] = true pour chapper votre texte. Ceci remplace un quatrime paramtre boolean $escape = false qui tait prsent dans les prcdentes versions.
HtmlHelper::div(string $class, string $text, array $options)
Paramtres
$class (string) Le nom de classe de la div.
$text (string) Le contenu de la div.
$options (array) Un tableau dattributs attributs html.
Utilis pour les sections de balisage envelopps dans des div. Le premier paramtre spcifie une
classe CSS, et le second est utilis pour fournir le texte envelopper par les balises div. Si le dernier
paramtre t dfini true, $text sera affich en HTML-chapp.
Si aucun texte nest spcifi, seulement une balise div douverture est retourne. :
<?php
echo $this->Html->div('error', 'Entrez votre numro de carte bleue S.V.P');
?>
// Affichera
<div class="error">Entrez votre numro de carte bleue S.V.P</div>
Helpers (Assistants)
627
Affichera :
<script type="text/javascript" href="/js/scripts.js"></script>
Vous pouvez lier des fichiers avec des chemins absolus tant quils ne se trouvent pas dans
app/webroot/js :
echo $this->Html->script('/autrerep/fichier_script');
Affichera :
<script type="text/javascript" href="http://code.jquery.com/jquery.min.js"></script>
Le premier paramtre peut tre un tableau pour inclure des fichiers multiples.
echo $this->Html->script(array('jquery', 'wysiwyg', 'scripts'));
Affichera :
<script type="text/javascript" href="/js/jquery.js"></script>
<script type="text/javascript" href="/js/wysiwyg.js"></script>
<script type="text/javascript" href="/js/scripts.js"></script>
Vous pouvez insrer dans la balise script un bloc spcifique en utilisant loption block.
echo $this->Html->script('wysiwyg', array('block' => 'scriptBottom'));
Dans votre layout, vous pouvez ressortir toutes les balises script ajoutes dans scriptBottom :
628
echo $this->fetch('scriptBottom');
Vous pouvez inclure des fichiers de script depuis un plugin en utilisant la syntaxe syntaxe de plugin.
Pour inclure app/Plugin/DebugKit/webroot/js/toolbar.js vous devriez faire cela :
echo $this->Html->script('DebugKit.toolbar.js');
Si vous voulez inclure un fichier de script qui partage un nom de fichier avec un plugin charg
vous pouvez faire cela. Par exemple si vous avez Un plugin Blog, et voulez inclure galement
app/webroot/js/Blog.plugins.js, vous devriez :
echo $this->Html->script('Blog.plugins.js', array('plugin' => false));
Modifi dans la version 2.1 : Loption block a t ajout. Le support de la syntaxe syntaxe de plugin
a t ajout.
HtmlHelper::scriptBlock($code, $options = array())
Paramtres
$code (string) Le code placer dans la balise script.
$options (array) Un tableau dattributs attributs html.
Gnre un bloc de code contenant des options $options[inline] dfinies de $code
mettre false pour voir le bloc de script apparatre dans le bloc de script de
la vue. Dautres options dfinies seront ajoutes comme attributs dans les balises de
script. $this->Html->scriptBlock(stuff, array(defer => true)); crera
une balise script avec lattribut defer="defer".
HtmlHelper::scriptStart($options = array())
Paramtres
$options (array) Un tableau d attributs HTML utiliser quand scriptEnd est
appel.
Dbute la mise en mmoire tampon dun bloc de code. Ce bloc de code va capturer toutes les sorties
entre scriptStart() et scriptEnd() et cre une balise script. Les options sont les mmes que
celles de scriptBlock()
HtmlHelper::scriptEnd()
Termine la mise en mmoire tampon dun bloc de script, retourne llment script gnr ou null si le
bloc de script t ouvert avec inline=false.
Un exemple de lutilisation de scriptStart() et scriptEnd() pourrait tre :
$this->Html->scriptStart(array('inline' => false));
echo $this->Js->alert('je suis dans le JavaScript');
$this->Html->scriptEnd();
HtmlHelper::nestedList(array $list, array $options = array(), array $itemOptions = array(), string $tag = ul)
Paramtres
$list (array) Ensemble dlments lister.
$options (array) Attributs HTML supplmentaires des balises de listes (ol/ul) ou
si ul/ol utilise cela comme une balise.
Helpers (Assistants)
629
Sortie :
// Affichera (sans les espaces blancs)
<ul>
<li>Languages
<ul>
<li>English
<ul>
<li>American</li>
<li>Canadian</li>
<li>British</li>
</ul>
</li>
<li>Spanish</li>
<li>German</li>
</ul>
</li>
</ul>
// Affichera
<tr>
<th>Date</th>
<th>Title</th>
<th>Active</th>
</tr>
630
echo $this->Html->tableHeaders(
array('Date','Title','Active'),
array('class' => 'status'),
array('class' => 'product_table')
);
Sortie :
<tr class="status">
<th class="product_table">Date</th>
<th class="product_table">Title</th>
<th class="product_table">Active</th>
</tr>
Modifi dans la version 2.2 : tableHeaders() accepte maintenant les attributs par cellule, regardez ci-dessous.
Depuis 2.2 vous pouvez dfinir des attributs par colonne, ceux-ci sont utiliss la place de ceux par
dfaut dans $thOptions :
echo $this->Html->tableHeaders(array(
'id',
array('Name' => array('class' => 'highlight')),
array('Date' => array('class' => 'sortable'))
));
Sortie :
<tr>
<th>id</th>
<th class="highlight">Name</th>
<th class="sortable">Date</th>
</tr>
Sortie :
Helpers (Assistants)
631
echo $this->Html->tableCells(array(
array('Jul 7th, 2007', array('Best Brownies', array('class' => 'highlight')) , 'Ye
array('Jun 21st, 2007', 'Smart Cookies', 'Yes'),
array('Aug 1st, 2006', 'Anti-Java Cake', array('No', array('id' => 'special'))),
));
// Sortie
<tr><td>Jul 7th, 2007</td><td class="highlight">Best Brownies</td><td>Yes</td></tr>
<tr><td>Jun 21st, 2007</td><td>Smart Cookies</td><td>Yes</td></tr>
<tr><td>Aug 1st, 2006</td><td>Anti-Java Cake</td><td id="special">No</td></tr>
echo $this->Html->tableCells(
array(
array('Red', 'Apple'),
array('Orange', 'Orange'),
array('Yellow', 'Banana'),
),
array('class' => 'darker')
);
Output :
<tr class="darker"><td>Red</td><td>Apple</td></tr>
<tr><td>Orange</td><td>Orange</td></tr>
<tr class="darker"><td>Yellow</td><td>Banana</td></tr>
632
echo $this->Html->url(array(
"controller" => "posts",
"action" => "view",
"foo" => "bar"
));
// Restituera
/posts/view/foo:bar
Output :
<form action="http://example.com" method="post" class="myform">
14. http ://api.cakephp.org/2.4/class-Router.html#_url
Helpers (Assistants)
633
Vous
pouvez
alors
charger
ces
balises
$this->Html->loadConfig(html5_tags);.
dfinis
en
appelant
Loption $startText peut aussi accepter un tableau. Cela donne plus de contrle travers le premier lien gnr :
echo $this->Html->getCrumbs(' > ', array(
'text' => $this->Html->image('home.png'),
'url' => array('controller' => 'pages', 'action' => 'display', 'home'),
'escape' => false
));
Une cl qui nest pas text ou url sera passe link() comme paramtre $options.
Modifi dans la version 2.1 : Le paramtre $startText accepte maintenant un tableau.
HtmlHelper::addCrumb(string $name, string $link = null, mixed $options = null)
Maintenant, dans votre vue vous allez devoir ajouter ce qui suit pour dmarrer le fil dAriane sur
chacune de vos pages.
$this->Html->addCrumb('Users', '/users');
$this->Html->addCrumb('Add User', array('controller' => 'users', 'action' => 'add'));
Ceci ajoutera la sortie Home > Users > Add User dans votre layout o le fil dAriane a t ajout.
HtmlHelper::getCrumbList(array $options = array(), mixed $startText)
634
Paramtres
$options (array) Un tableau d attributs HTML pour les elements contenant
<ul>. Peut aussi contenir les options separator, firstClass, lastClass et escape.
$startText (string|array) Le texte ou lelment qui prcde ul.
Retourne le fil dAriane comme une liste (x)html.
Cette mthode utilise HtmlHelper::tag() pour gnrer la liste et ces lments. Fonctionne de
la mme manire que getCrumbs(), il utilise toutes les options que chacun des fils a ajout. Vous
pouvez utiliser le paramtre $startText pour fournir le premier lien de fil. Cest utile quand vous
voulez inclure un lien racine. Cette option fonctionne de la mme faon que loption $startText
pour getCrumbs().
Modifi dans la version 2.1 : Le paramtre $startText a t ajout.
Modifi dans la version 2.3 : Les options separator, firstClass et lastClass ont t ajoutes.
Modifi dans la version 2.5 : Loption escape a t ajoute.
JSHelper
class JsHelper(View $view, array $settings = array())
Avertissement : JsHelper est actuellement dprci et compltement retir de 3.x. Nous recommandons
dutiliser du JavaScript classique et de directement intragir avec les librairies si possible.
Depuis le dbut le support de CakePHP pour Javascript a t orient vers Prototype/Scriptaculous (librairie
JavaScript). Tandis que nous continuons de penser quil sagit dexcellentes bibliothques Javascript, il a
t demand la communaut de supporter dautres librairies. Plutt que denlever Prototype en faveur
dune autre librairie JavaScript. Nous avons cr un adaptateur fonctionnant sur le principe dun Helper
et avons inclu 3 des librairies les plus demandes. Prototype/scriptaculous, Mootools/Mootools-more, et
jQuery/jQueryUI. Bien que lAPI nest pas aussi vaste que le Helper Ajax, nous pensons que la solution
base sur ladaptateur permet une solution plus extensible offrant aux dveloppeurs la puissance et la flexibilit dont ils ont besoin pour rpondre leurs besoins spcifiques.
Les moteurs Javascript forment lpine dorsale du nouveau Helper Js. Un moteur JavaScript traduit un
lment Javascript abstrait dans un code JavaScript concret spcifique la librairie en cours dutilisation.
De plus ils crent un systme extensible utiliser pour les autres.
Utilisation dun moteur Javascript spcifique
Avant tout, tlchargez votre librairie JavaScript prfre et placez la dans app/webroot/js.
Puis, vous devez inclure la librairie dans votre page. Pour linclure dans toutes les pages, ajoutez cette ligne
dans la section <head> de app/View/Layouts/default.ctp :
echo $this->Html->script('jquery'); // Inclut la librairie Jquery
Remplacez jquery par le nom de votre fichier de librairie (.js sera ajout au nom).
Par dfaut les scripts sont mis en cache, et vous devez explicitement imprimer le cache. Pour faire cela la
fin de chacune des pages, incluez cette ligne juste avant la balise de fin de </body>
Helpers (Assistants)
635
Attention : Vous devez inclure la librairie dans votre page et afficher le cache pour que le helper fonctionne.
La selection du moteur Javascript est dclare quand vous incluez le helper dans votre controller
public $helpers = array('Js' => array('Jquery'));
La partie ci-dessus utilise le moteur Jquery dans les instances du Helper Js dans vos vues. Si vous ne dclarez
pas un moteur spcifique, le moteur Jquery sera utilis par dfaut. Comme il est mentionn ci-dessus, il y a
trois moteurs implments dans le noyau, mais nous encourageons la communaut tendre la compatibilit
des librairies.
Utilisation de jQuery avec dautres librairies La librairie jQuery, et virtuellement tous ses plugins sont
limits au sein de lespace jQuery. Comme rgle gnrale, les objets globaux sont stocks dans lespace JQuery, ainsi vous ne devriez pas avoir de clash entre Jquery et dautre librairies (comme Prototype,
MooTools, ou YUI).
Ceci dit, il y a une mise en garde : Par dfaut, jQuery utilise $ comme raccourci de jQuery
Pour redfinir le raccourci $, utilisez la variable jQueryObject :
$this->Js->JqueryEngine->jQueryObject = '$j';
echo $this->Html->scriptBlock(
'var $j = jQuery.noConflict();',
array('inline' => false)
);
// Demande jQuery de se placer dans un mode noconflict
Utilisation du Helper Js dans des helpers personnaliss Dclarez le Helper Js dans le tableau
$helpers de votre Helper personnalis :
public $helpers = array('Js');
Note : Il nest pas possible de dclarer le moteur JavaScript dans un Helper personnalis. Ceci naurait
aucun effet.
Si vous tes prt utiliser un moteur JavaScript autre que celui par dfaut, fates le paramtrage du Helper
dans votre controller comme ceci :
public $helpers = array(
'Js' => array('Prototype'),
'CustomHelper'
);
636
Les helpers de moteur Javascript suivent les conventions normales des helper, avec quelques restrictions supplmentaires. Ils doivent avoir le suffixe Engine. DojoHelper nest pas bon, DojoEngineHelper est
correct. De plus ils doivent tendre JsBaseEngineHelper afin de tirer parti du meilleur de la nouvelle
API.
Utilisation du moteur Javascript
Le JsHelper fournit quelques mthodes, et agit comme une faade pour le moteur helper. Vous ne devriez
pas accder au moteur helper except dans de rares occasions. Utilisez les fonctionnalits de faade du
Helper Js vous permet de tirer parti de la mise en mmoire tampon et de la mthode caractristique de
chanage intgr ; (le chanage de mthode ne fonctionne que dans PHP5).
Par dfaut le Helper Js bufferise presque tous les codes du script gnrs, ce qui vous permet de rcuprer
les scripts partout dans la vue, les lments et les mises en page, et de les ressortir un endroit. La
Rcupration des scripts bufferiss est ralis avec $this->Js->writeBuffer(); ceci retournera
le contenu du buffer dans une balise script. Vous pouvez dsactiver le buffering gnralis avec la proprit $bufferScripts ou en dfinissant buffer => false dans les mthodes qui prennent des
$options.
tant donn que la plupart des mthodes en Javascript commencent avec une slection dlments dans le
DOM, $this->Js->get() retourne un $this, vous permettent denchaner les mthodes en utilisant la
selection. Le chanage de mthode vous permet dcrire moins, et de rendre votre code plus expressif .
$this->Js->get('#foo')->event('click', $eventCode);
Est un exemple de chanage de mthode. Le chanage de mthode nest pas possible dans PHP4 et lexemple
ci-dessus devrait tre crit comme :
$this->Js->get('#foo');
$this->Js->event('click', $eventCode);
Options communes Dans le but de simplifier le dveloppement et comme les librairies JavaScript peuvent
changer, un ensemble courant doptions est pris en charge par JsHelper, ces options courantes seront
mappes en dehors des options spcifiques de la librairies en interne. Si vous ne prvoyez pas la commutation
des librairies, chaque librairie supporte toutes les fonctions de callback natives et les options.
Helpers (Assistants)
637
Enveloppement de Callback Par dfaut, toutes les options de callback sont enveloppes dans une
fonction anonyme avec les bons arguments. Vous pouvez dsactiver ce comportement en fournissant
wrapCallbacks = false dans votre tableau doptions.
Travailler avec des scripts bufferiss Un inconvnient la prcdente implmentation des fonctionnalits de type dAJAX tait la dispersion des balises de script partout dans le document , et limpossibilit
de bufferiser les scripts ajouts par les lments dans la mise en page. Le nouveau Helper Js si il est utilis
correctement vite ces deux questions. Il est recommand de placer $this->Js->writeBuffer()
la fin du fichier layout au dessus la balise </body>. Ceci permettra tous les scripts gnrs dans les
lments du layout dtre ressortis (output) un endroit. Il doit tre not que les scripts bufferiss sont grs
sparment des scripts de fichiers inclus.
JsHelper::writeBuffer($options = array())
crit tous le codes Javascript gnrs jusquici dans un bloc de code ou les met en mmoire cache dans un
fichier et retourne un script li.
Options
inline - Dfini true pour avoir la sortie des scripts dans un bloc de script inline. si cache est aussi
true, une balise de lien de script sera gnre (par dfaut true)
cache - Dfini true pour avoir les scripts dans un fichier de la mmoire cache et sy reli (false par
dfaut)
clear - Dfini false pour viter au fichier de cache dtre effac (true par dfaut)
onDomReady - enveloppe les scripts en mmoire cache dans un evnement domready (par dfaut true)
safe - si un block inline est gnr il sera envelopp dans < ![CDATA[ ... ]]> (true par dfaut)
La cration dun fichier de cache avec writeBuffer() ncessite que webroot/js soit accessible en
criture et permette au navigateur de placer dans le cache les ressources de script gnr pour la page.
JsHelper::buffer($content)
Ajoute $content au buffer de script interne.
JsHelper::getBuffer($clear = true)
Rcupre le contenu du buffer courant. Passe false pour ne pas effacer le buffer en mme temps.
Bufferiser des mthodes qui ne sont normalement pas bufferise
Quelques mthodes dans le Helper sont bufferise par dfaut. Le moteur bufferise les mthodes suivantes
par dfaut :
event
sortable
drag
drop
slider
De plus vous pouvez forcer une autre mthode du Helper Js utiliser la mise en mmoire cache. En ajoutant
un boolen la fin des arguments vous pouvez forcer dautres mthodes daller en mmoire cache. Par
exemple la mthode each() qui nest normalement pas bufferise :
$this->Js->each('alert("sapristi!");', true);
638
Ce qui est ci-dessus va forcer la mthode each() utiliser le buffer. En revanche si vous souhaitez quune
mthode bufferise ne bufferise plus, vous pouvez passer un false comme le dernier argument :
$this->Js->event('click', 'alert("sapristi!");', false);
Ceci forcera la fonction event qui est normalement mis en mmoire cache retourner son rsultat.
Dautres Mthodes
Les moteurs Javascript du noyau fournissent les mmes fonctionnalits dfinies a travers les autres librairies,
il y a aussi un sous-ensemble doptions communes qui sont traduites dans les options spcifiques des librairies. Tout cela pour fournir au dveloppeurs finaux une Api unifie autant que possible. La liste suivante
de mthodes est supporte par tous les moteurs inclus dans le noyau CakePHP. Chaque fois que vous voyez
une liste spare pour les Options et les Event Options Les deux ensembles de paramtres sont fournis dans le tableau $options pour la mthode.
JsHelper::object($data, $options = array())
Srialise $data vers JSON. Cette mthode est un proxy pour json_encode() avec quelques
fonctionnalits supplmentaires ajoute avec le paramtre $options.
Options :
prefix - Chane ajoute en dbut des donnes retournes.
postfix - Chane ajoute aux donne retourne.
Exemple dutilisation :
$json = $this->Js->object($data);
JsHelper::sortable($options = array())
Sortable gnre un extrait de code pour fabriquer un ensemble dlments (souvent une liste) drag and
drop triable.
Les options normalises sont :
Options
containment - Conteneur de laction de dplacement.
handle - Selecteur de llment. Seul cet lment commencera laction de tri.
revert - Sil faut ou pas utiliser un effet pour dplacer llment triable dans sa position finale.
opacity - Opacit de lespace rserv.
distance - Distance a laquelle llment triable doit tre dragg avant que le tri nopre.
Event Options
start - vnement lanc quand le tri commence.
sort - vnement lanc quand le tri est en cours.
complete - vnement lanc quand le tri est termin.
Dautres options sont supportes par chacune des librairies Javascript, et vous pouvez obtenir dans
leurs documentation respective des informations plus dtailles sur les options et les paramtres.
Exemple dutilisation :
$this->Js->get('#ma-liste');
$this->Js->sortable(array(
'distance' => 5,
'containment' => 'parent',
Helpers (Assistants)
639
En imaginant que vous tiez en train dutiliser le moteur Jquery, vous devriez avoir le code suivant
dans votre block Javascript gnr.
$("#myList").sortable({
containment:"parent",
distance:5,
sort:onSort,
start:onStart,
stop:onStop
});
JsHelper::get($selector)
Dfinit la slection interne dans un slecteur CSS. La slection active est utilise dans les oprations
ultrieures jusqu ce quune nouvelle soit faite.
$this->Js->get('#element');
Le JsHelper fait maintenant rfrence toutes les mthodes de la slection bases sur #element.
Pour changer la slection active appelez get() nouveau avec un nouvel lment.
640
Si vous utilisiez le moteur Jquery le code suivant devrait tre ajout au buffer
$("#element").draggable({
containment:"#content",
drag:onDrag,
grid:[10,10],
start:onStart,
stop:onStop
});
JsHelper::drop($options = array())
Fabrique un lment accepte des lments dragguables et agit comme dropzone pour les lments
draggs.
Options
accept - Slecteur des lments que ce droppable acceptera.
hoverclass - Classe pour ajouter droppable quand un draggable est termin.
Event Options
drop - vnement lanc quand un lment est dropp dans la drop zone.
hover - vnement lanc quand un drag entre dans une drop zone.
leave - vnement lanc quand un drag est retir depuis une drop zone sans tre dropp.
Exemple dutilisation :
Helpers (Assistants)
641
$this->Js->get('#element');
$this->Js->drop(array(
'accept' => '.items',
'hover' => 'onHover',
'leave' => 'onExit',
'drop' => 'onDrop',
'wrapCallbacks' => false
));
Si vous utilisiez le moteur jQuery le code suivant devrait tre ajout au buffer.
$("#element").droppable({
accept:".items",
drop:onDrop,
out:onExit,
over:onHover
});
Note : Les lments Droppables dans Mootools fonctionnent diffremment des autres librairies. Les
Droppables sont implments comme une extension de Drag. Donc pour faire une selection get() pour
llment droppable. Vous devez aussi fournir une rgle de selecteur llment draggable. De plus,
les droppables Mootools hritent de toutes les option de Drag.
JsHelper::slider($options = array())
Cr un morceau de code Javascript qui converti un lment dans un morceau de code slider ui. Voir les
implmentations des diffrentes librairies pour des utilisations supplmentaires et les fonctionnalits.
Options
handle - l id de llment utilis dans le sliding.
direction - La direction du slider soit vertical ou horizontal.
min - La valeur minimale pour le slider.
max - La valeur maximale pour le slider.
step - Le nombre dtapes que le curseur aura.
value - Le dcalage initial du slider.
Events
change - Lanc quand la valeur du slider est actualis.
complete - Lanc quand un utilisateur arrte de slider le gestionnaire.
Exemple dutilisation :
$this->Js->get('#element');
$this->Js->slider(array(
'complete' => 'onComplete',
'change' => 'onChange',
'min' => 0,
'max' => 10,
'value' => 2,
'direction' => 'vertical',
'wrapCallbacks' => false
));
Si vous utilisiez le moteur jQuery le code suivant devrait tre ajout au buffer.
642
$("#element").slider({
change:onChange,
max:10,
min:0,
orientation:"vertical",
stop:onComplete,
value:2
});
Helpers (Assistants)
643
Si vous employiez la librairie jQuery vous devriez avoir le code Javascript suivant ajout au buffer.
Notez que lvnement du navigateur par dfaut nest pas annul :
$('#some-link').bind('click', function (event) {
alert('hey you!');
});
JsHelper::domReady($callback)
Cr lvnement spcial DOM ready. JsHelper::writeBuffer() enveloppe automatiquement les scripts bufferiss dans une mthode domReady.
JsHelper::each($callback)
Cr un morceau de code qui effectue une itration sur les lments slectionns, et insre
$callback.
Exemple :
$this->Js->get('div.message');
$this->Js->each('$(this).css({color: "red"});');
JsHelper::alert($message)
Cr un extrait de code JavaScript contenant un alert(). Par dfaut, alert ne bufferise pas, et
retourne le morceau de script suivant.
$alert = $this->Js->alert('Zogotunga!');
JsHelper::confirm($message)
Cr un bout de code contenant confirm(). Par dfaut, confirm ne bufferise pas, et retourne le
morceau de script suivant.
$alert = $this->Js->confirm('Vraiment certain?');
JsHelper::prompt($message, $default)
Cr un bout de code Javascript contenant prompt(). Par dfaut, prompt ne bufferise pas, et
retourne le morceau de code suivant.
$prompt = $this->Js->prompt('C'est quoi ta couleur prfre?', 'bleu');
644
Va cr un bouton submit et un vnement onclick attach. Lvnement click sera bufferis par
dfaut.
echo $this->Js->submit('Save', array(
'update' => '#content',
'div' => false,
'type' => 'json',
'async' => false
));
Helpers (Assistants)
645
JsHelper::serializeForm($options = array())
Srialise le formulaire attach au $selector. Passe true pour $isForm si la selection courante est
un lment de formulaire. Converti le formulaire ou llment de formulaire attach la slection
courante dans un objet chane/json (dpendant de limplmentation de la librairie) pour utilisation
avec les oprations XHR.
Options
isForm - est ce que la slection courante est un formulaire ou un input ? (par dfaut false)
inline - est ce que le traitement du rendu sera utilis dans un autre traitement JS ? (par dfaut
false)
En dfinissant inline == false vous permet de retirer la bordure ;. Ceci est utile quand vous avez besoin
de srialiser un lment de formulaire comme faisant parti dune autre opration Javascript ou utilisez
la mthode de srialisation dans un Objet littral.
JsHelper::redirect($url)
Redirige la page vers $url en utilisant window.location.
JsHelper::value($value)
Convertit une variable native PHP dun type dans une reprsentation JSON quivalente. chappe une
valeur de chane dans une chane compatible JSON. Les caractre UTF-8 seront chapps .
La Pagination AJAX
Bien mieux quavec la pagination AJAX de la 1.2, vous pouvez utiliser le Helper JS pour grer les liens de
pagination AJAX au lieu de liens HTML.
Fabriquer les liens AJAX Avant de pouvoir crer les liens ajax vous devez inclure la librairie Javascript
qui correspond ladaptateur que vous utilisez avec le Helper JS. Par dfaut le Helper Js utilise
jQuery. Donc dans votre layout incluez jQuery (ou la librairie que vous utilisez). Assurez vous galement
dinclure RequestHandlerComponent dans votre behavior. Ajoutez ce qui suit dans votre controller :
public $components = array('RequestHandler');
public $helpers = array('Js');
Ce qui suit relie la librairie Javascript que vous voulez utiliser. Pour cet exemple nous utiliserons jQuery :
echo $this->Html->script('jquery');
646
De mme quavec la 1.2 vous devez dire au PaginatorHelper que vous voulez faire des liens Javascript
avancs au lieu des plain HTML. Pour faire cela utilisez options() :
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true
));
La classe PaginatorHelper sait maintenant quil faut crer des liens Javascript tendus, et que ces liens
devront mettre jour le contenu #content de llment. Bien sr cet lment doit exister, et la plupart
du temps vous voulez envelopper le $content_for_layout par une div qui correspond lid utilise
dans loption update. Vous devez galement dfinir evalScripts true si vous utilisez des adaptateurs
Mootools ou Prototype, sans evalScripts ces librairies seront incapables de relier les requtes entrent
elles. Loption indicator nest pas supporte par le Helper JS et sera ignore.
Vous venez donc de crer tous les liens demands pour le fonctionnement de la pagination. Puisque le
Helper Js bufferise automatiquement tous les contenus de scripts pour rduire les balises <script>
dans vos codes sources vous devez appeler la restitution du buffer. A la fin de votre fichier de vue. Vrifiez
linclusion de :
echo $this->Js->writeBuffer();
Si vous oubliez cela vous ne pourrez pas enchaner les liens de pagination AJAX. Quand vous crivez le
buffer, cela lefface galement , et vous navez donc pas vous inquiter de doublon de code Javascript.
Ajouter des effets et des transitions Depuis que indicator nest plus support, vous devez ajouter les
effets dindicator vous mme. :
<!DOCTYPE html>
<html>
<head>
<?php echo $this->Html->script('jquery'); ?>
//more stuff here.
</head>
<body>
<div id="content">
<?php echo $this->fetch('content'); ?>
</div>
<?php
echo $this->Html->image(
'indicator.gif',
array('id' => 'busy-indicator')
);
?>
</body>
</html>
Rappelez vous de placer le fichier indicator.gif dans le rpertoire app/webroot/img. Vous devriez voir une
situation o indicator.gif saffiche immdiatement au chargement de la page. Vous avez besoin dinsrer cet
indicateur #busy-indicator { display:none; } dans votre fichier CSS principal.
Helpers (Assistants)
647
Avec le layout ci-dessus, nous avons inclus un indicateur, qui affichera une animation occup que nous
aurons montrer et cacher avec le Helper Js. Pour faire cela, nous avons besoin de mettre jour notre
fonction options() :
$this->Paginator->options(array(
'update' => '#content',
'evalScripts' => true,
'before' => $this->Js->get('#busy-indicator')->effect(
'fadeIn',
array('buffer' => false)
),
'complete' => $this->Js->get('#busy-indicator')->effect(
'fadeOut',
array('buffer' => false)
),
));
Ceci montrera/cachera llment indicateur occup avant et aprs que le contenu de la balise #content
soit mis jour. Bien que indicator ait t enlev, les nouvelles fonctionnalits du JsHelper permettent
la cration de plus de contrle et deffets plus complexes.
NumberHelper
class NumberHelper(View $view, array $settings = array())
Le helper Number contient des mthodes pratiques qui permettent laffichage des nombres dans divers
formats communs dans vos vues. Ces mthodes contiennent des moyens pour formater les devises, pourcentages, taille des donnes, le format des nombres avec prcisions et aussi de vous donner davantage de
souplesse en matire de formatage des nombres.
Modifi dans la version 2.1 : NumberHelper a t remani dans une classe CakeNumber pour permettre
une utilisation plus facile a lextrieur de la couche View. Dans une vue, ces mthodes sont accessibles
via la classe NumberHelper et vous pouvez lappeler comme vous pourriez appeler une mthode de helper
normale : $this->Number->method($args);.
Toutes ces fonctions retournent le nombre format ; Elles naffichent pas automatiqement la sortie dans la
vue.
NumberHelper::currency(float $number, string $currency = USD, array $options = array())
Paramtres
$number (float) La valeur convertir.
$currency (string) Le format de monnaie connu utiliser.
$options (array) Options, voir ci-dessous.
Cette mthode est utilise pour afficher un nombre dans des formats de monnaie courante
(EUR,GBP,USD). Lutilisation dans une vue ressemble ceci :
// Appel avec NumberHelper
echo $this->Number->currency($number, $currency);
// Appel avec CakeNumber
648
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency($number, $currency);
Le premier paramtre $number, doit tre un nombre virgule qui reprsente le montant dargent
que vous dsirez. Le second paramtre est utilis pour choisir un schma de formatage de monnaie
courante :
$currency 1234.56, format par le type courant
EUR
C1.234,56
GBP
1,234.56
USD
$1,234.56
Le troisime paramtre est un tableau doptions pour dfinir la sortie. Les options suivantes sont
disponibles :
Option
Description
before
Le symbole de la monnaie placer avant les nombres ex : $
after
Le symbole de la monnaie placer aprs les nombres dcimaux ex : c. Dfinit le
boolen false pour utiliser aucun symbole dcimal ex : 0.35 => $0.35.
zero
Le texte utiliser pour des valeurs zro, peut tre une chane de caractres ou un
nombre. ex : 0, Free !
places
Nombre de dcimales utiliser. ex : 2
thouSparateur des milliers ex : ,
sands
decimals Symbole de Sparateur des dcimales. ex : .
negative
Symbole pour les nombres ngatifs. Si gal (), le nombre sera entour avec ( et )
escape
La sortie doit-elle tre chappe de htmlentity ? Par dfaut dfini true
wholeSym- La chane de caractres utiliser pour les tous nombres. ex : dollars
bol
wholePo- Soit before soit after pour placer le symbole entier
sition
fractionChane de caractres utiliser pour les nombres en fraction. ex : cents
Symbol
fractionSoit before soit after pour placer le symbole de fraction
Position
fractionFraction exponent de cette monnaie spcifique. Par dfaut 2.
Exponent
Si une valeur $currency non reconnue est fournie, elle est prfixe par un nombre format en USD.
Par exemple :
// Appel avec NumberHelper
echo $this->Number->currency('1234.56', 'FOO');
// Sortie
FOO 1,234.56
// Appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency('1234.56', 'FOO');
NumberHelper::defaultCurrency(string $currency)
Paramtres
Helpers (Assistants)
649
$currency
(string)
Dfini
CakeNumber::currency().
une
monnaie
connu
pour
Setter/getter pour la monnaie par dfaut. Ceci retire la ncessit de toujours passer la monnaie
CakeNumber::currency() et change toutes les sorties de monnaie en dfinissant les autres par
dfaut.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.
NumberHelper::addFormat(string $formatName, array $options)
Paramtres
$formatName (string) Le nom du format utiliser dans le futur.
$options (array) Le tableau doptions pour ce format. Utilise les mmes cls
$options comme CakeNumber::currency().
before Symbole de monnaie avant le nombre. False pour aucun.
after Symbole de monnaie aprs le nombre. False pour aucun.
zero Le texte utiliser pour les valeurs zro, peut tre une chane de caractres
ou un nombre. ex : 0, Free !
places Nombre de dcimal utiliser. ex. 2.
thousands Sparateur des milliers. ex : ,.
decimals Symbole de Sparateur des dcimales. ex : ..
negative Symbole pour les nombres ngatifs. Si gal (), le nombre sera entour
avec ( et ).
escape La sortie doit-elle tre chappe de htmlentity ? Par dfaut true.
wholeSymbol Chane de caractres utiliser pour tous les nombres. ex : dollars.
wholePosition Soit before soit after pour placer le symbole complet.
fractionSymbol Chane de caractres utiliser pour les nombres fraction. ex :
cents.
fractionPosition Soit before soit after pour placer le symbole de fraction.
Ajoute le format de monnaie au helper Number. Facilite la rutilisation des formats de monnaie.
Vous pouvez maintenant utiliser BRL de manire courte quand vous formatez les montants de monnaie :
// appel par NumberHelper
echo $this->Number->currency($value, 'BRL');
// appel par CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency($value, 'BRL');
Les formats ajouts sont fusionns avec les formats par dfaut suivants :
650
array(
'wholeSymbol'
'wholePosition'
'fractionSymbol'
'fractionPosition'
'zero'
'places'
'thousands'
'decimals'
'negative'
'escape'
'fractionExponent'
)
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
'',
'before',
false,
'after',
0,
2,
',',
'.',
'()',
true,
2
Helpers (Assistants)
651
echo CakeNumber::toPercentage(45.691873645);
// Appel avec multiply. Sortie: 45.69%
echo CakeNumber::toPercentage(0.45691, 2, array(
'multiply' => true
));
Introduit dans la version 2.4 : Largument $options avec loption multiply a t ajout.
NumberHelper::fromReadableSize(string $size, $default)
Paramtres
$size (string) La valeur formate lisible par un humain.
Cette mthode enlve le format dun nombre partir dune taille de byte lisible par un humain en un
nombre entier de bytes.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3
NumberHelper::toReadableSize(string $dataSize)
Paramtres
$data_size (string) Le nombre de bytes pour le rendre lisible.
Cette mthode formate les tailles de donnes dans des formes lisibles pour lhomme. Elle fournit une
manire raccourcie de convertir les en KB, MB, GB, et TB. La taille est affiche avec un niveau de
prcision deux chiffres, selon la taille de donnes fournie (ex : les tailles suprieurs sont exprimes
dans des termes plus larges) :
// appel avec NumberHelper
echo $this->Number->toReadableSize(0); // 0 Bytes
echo $this->Number->toReadableSize(1024); // 1 KB
echo $this->Number->toReadableSize(1321205.76); // 1.26 MB
echo $this->Number->toReadableSize(5368709120); // 5.00 GB
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::toReadableSize(0); // 0 Bytes
echo CakeNumber::toReadableSize(1024); // 1 KB
echo CakeNumber::toReadableSize(1321205.76); // 1.26 MB
echo CakeNumber::toReadableSize(5368709120); // 5.00 GB
Le paramtre $number est le nombre que vous souhaitez formater pour la sortie. Avec aucun $options
fourni, le nombre 1236.334 sortirait comme ceci : 1,236. Notez que la prcision par dfaut est daucun
chiffre aprs la virgule.
Le paramtre $options est l o rside la relle magie de cette mthode.
652
Si vous passez un entier alors celui-ci devient le montant de prcision pour la fonction.
Si vous passez un tableau associatif, vous pouvez utiliser les cls suivantes :
places (integer) : le montant de prcision dsir.
before (string) : mettre avant le nombre sortir.
escape (boolean) : si vous voulez la valeur avant dtre chappe.
decimals (string) : utilis pour dlimiter les places des dcimales dans le nombre.
thousands (string) : utilis pour marquer les milliers, millions, . . .
Exemple :
// appel avec NumberHelper
echo $this->Number->format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
));
// sortie ' 123,456.79'
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
));
// sortie ' 123,456.79'
Le paramtre $number est le nombre que vous planifiez sur le formatage de sortie. Avec aucun $options fourni, le nombre 1236.334 sortirait 1,236. Notez que la valeur de prcision par dfaut est aucune
dcimale.
Le paramtre $options prend les mmes cls que CakeNumber::format() lui-mme :
places (integer) : le montant de precision souhait.
before (string) : mettre avant le nombre sorti.
after (string) : mettre aprs le nombre sorti.
decimals (string) : utilis pour dlimiter les places de la dcimal dans un nombre.
thousands (string) : utilis pour marquer les places des centaines, millions, . . .
Exemple :
Helpers (Assistants)
653
Paginator
class PaginatorHelper(View $view, array $settings = array())
Le Helper Paginator est utilis pour prsenter des contrles de pagination comme les numros de pages et
les liens suivant/prcdent. Il travaille en tandem avec PaginatorComponent.
Voir aussi Pagination pour des informations sur la faon de crer des jeux de donnes pagins et faire des
requtes pagines.
Cration de liens tris
654
direction La direction par dfaut utiliser quand ce lien nest pas actif.
lock Verrouiller la direction. Va seulement utiliser la direction par dfaut, par dfaut false.
Introduit dans la version 2.5 : Vous pouvez maintenant dfinir loption lock true afin de verrouiller la
direction du tri dans la direction spcifie.
En considrant que vous paginez des posts, quils sont sur la page un :
echo $this->Paginator->sort('user_id');
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">User Id</a>
Vous pouvez utiliser le paramtre title pour crer des textes personnaliss pour votre lien :
echo $this->Paginator->sort('user_id', 'User account');
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">User account</a>
Si vous utilisez de lHTML comme des images dans vos liens rappelez-vous de paramtrer lchappement :
echo $this->Paginator->sort(
'user_id',
'<em>User account</em>',
array('escape' => false)
);
Sortie :
<a href="/posts/index/page:1/sort:user_id/direction:asc/">
<em>User account</em>
</a>
Loption de direction peut tre utilise pour paramtrer la direction par dfaut pour un lien. Une fois quun
lien est activ, il changera automatiquement de direction comme habituellement :
echo $this->Paginator->sort('user_id', null, array('direction' => 'desc'));
Sortie
<a href="/posts/index/page:1/sort:user_id/direction:desc/">User Id</a>
Loption lock peut tre utilise pour verrouiller le tri dans la direction spcifie :
echo $this->Paginator->sort('user_id', null, array('direction' => 'asc', 'lock' => true));
Helpers (Assistants)
655
PaginatorHelper::numbers($options = array())
Retourne un ensemble de nombres pour le jeu de rsultat pagin. Utilise un modulo pour dcider combien
de nombres prsenter de chaque cot de la page courante. Par dfaut 8 liens de chaque cot de la page
courante seront crs si cette page existe. Les liens ne seront pas gnrs pour les pages qui nexistent pas.
La page courante nest pas un lien galement.
Les options supportes sont :
before Contenu a insrer avant les nombres.
after Contenu a insrer aprs les nombres.
model Model pour lequel crer des nombres, par dfaut PaginatorHelper::defaultModel().
modulus combien de nombres inclure sur chacun des cots de la page courante, par dfaut 8.
separator Sparateur, par dfaut |
tag La balise dans laquelle envelopper les liens, par dfaut span.
class Le nom de classe de la balise entourante.
currentClass Le nom de classe utiliser sur le lien courant/actif. Par dfaut current.
first Si vous voulez que les premiers liens soit gnrs, dfinit un entier pour dfinir le nombre de
premier liens gnrer. Par dfaut false. Si une chane est dfinie un lien pour la premire page sera
gnre avec la valeur comme titre :
echo $this->Paginator->numbers(array('first' => 'Premire page'));
last Si vous voulez que les derniers liens soit gnrs, dfinit un entier pour dfinir le nombre de
dernier liens gnrer. Par dfaut false. Suit la mme logique que loption first. il y a mthode
last() utiliser sparment si vous le voulez.
ellipsis Contenu des suspensions, par dfaut ...
La balise currentTag utiliser pour le nombre de page courant, par dfaut null. Cela vous autorise
gnrer par exemple le Bootstrap Twitter comme les liens avec le nombre de page courant enroul dans
les balises a ou span supplmentaires.
Bien que cette mthode permette beaucoup de customisation pour ses sorties. Elle est aussi prte pour tre
appele sans aucun paramtres.
echo $this->Paginator->numbers();
En utilisant les options first et last vous pouvez crer des liens pour le dbut et la fin du jeu de page. Le code
suivant pourrait crer un jeu de liens de page qui inclut les liens des deux premiers et deux derniers rsultats
de pages :
echo $this->Paginator->numbers(array('first' => 2, 'last' => 2));
Modifi dans la version 2.1 : Loption currentClass t ajoute dans la version 2.1.
Introduit dans la version 2.3 : Loption currentTag a t ajoute dans 2.3.
Cration de liens de sauts
En plus de gnrer des liens qui vont directement sur des numros de pages spcifiques, vous voudrez
souvent des liens qui amnent vers le lien prcdent ou suivant, premire et dernire pages dans le jeu de
656
donnes pagines.
PaginatorHelper::prev($title = << Previous, $options = array(), $disabledTitle = null,
$disabledOptions = array())
Paramtres
$title (string) Titre du lien.
$options (mixed) Options pour le lien de pagination.
$disabledTitle (string) Titre quand le lien est dsactiv, comme quand vous tes
dj sur la premire page, sans page prcdente o aller.
$disabledOptions (mixed) Options pour le lien de pagination dsactiv.
Gnre un lien vers la page prcdente dans un jeu denregistrements pagins.
$options et $disabledOptions supportent les cls suivantes :
tag La balise enveloppante que vous voulez utiliser, span par dfaut.
escape Si vous voulez que le contenu soit encod en HTML, par dfaut true.
model Le model utiliser, par dfaut PaginatorHelper : :defaultModel()
Un simple exemple serait :
echo $this->Paginator->prev(
' << ' . __('previous'),
array(),
null,
array('class' => 'prev disabled')
);
Si vous tiez actuellement sur la secondes pages des posts (articles), vous obtenez le rsultat suivant :
<span class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
<< previous
</a>
</span>
Sortie :
<li class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
</li>
Output :
Helpers (Assistants)
657
Ceci cr un simple lien pour la premire page. Ne retournera rien si vous tes sur la premire page.
Vous pouvez aussi utiliser un nombre entier pour indiquer combien de premier liens pagins vous
voulez gnrer :
echo $this->Paginator->first(3);
Ceci crera des liens pour les 3 premires pages, une fois la troisime page ou plus atteinte. Avant
cela rien ne sera retourn.
Les paramtres doption acceptent ce qui suit :
tag La balise tag enveloppante que vous voulez utiliser, par dfaut span.
after Contenu insrer aprs le lien/tag.
model Le model utiliser par dfaut PaginatorHelper : :defaultModel().
separator Contenu entre les liens gnrs, par dfaut | .
ellipsis Contenu pour les suspensions, par dfaut ....
PaginatorHelper::last($last = last >>, $options = array())
Cette mthode fonctionne trs bien comme la mthode first(). Elle a quelques diffrences cependant. Elle ne gnrera pas de lien si vous tes sur la dernire page avec la valeur chane $last. Pour
une valeur entire de $last aucun lien ne sera gnr une fois que lutilisateur sera dans la zone des
dernires pages.
PaginatorHelper::current(string $model = null)
rcupre la page actuelle pour le jeu denregistrement du model donn :
// Ou l'URL est: http://example.com/comments/view/page:3
echo $this->Paginator->current('Comment');
// la sortie est 3
PaginatorHelper::counter($options = array())
Retourne une chane compteur pour le jeu de rsultat pagin. En Utilisant une chane formate fournie et un
nombre doptions vous pouvez crer des indicateurs et des lments spcifiques de lapplication indiquant
ou lutilisateur se trouve dans lensemble de donnes pagines.
Il y a un certain nombre doptions supportes pour counter(). celles supportes sont :
format Format du compteur. Les formats supports sont range, pages et custom. Par dfaut pages
qui pourrait ressortir comme 1 of 10. Dans le mode custom la chane fournie est analyse (parse) et les
jetons sont remplaces par des valeurs relles. Les jetons autoriss sont :
{:page} - la page courante affiche.
{:pages} - le nombre total de pages.
{:current} - le nombre actuel denregistrements affichs.
{:count} - le nombre total denregistrements dans le jeu de rsultat.
{:start} - le nombre de premier enregistrement affichs.
{:end} - le nombre de dernier enregistrements affichs.
{:model} - La forme plurielle du nom de model. Si votre model tait RecettePage, {:model}
devrait tre recipe pages. cette option a t ajoute dans la 2.0.
Vous pouvez aussi fournir simplement une chane la mthode counter en utilisant les jetons autoriss.
Par exemple :
echo $this->Paginator->counter(
'Page {:page} of {:pages}, showing {:current} records out of
{:count} total, starting on record {:start}, ending on {:end}'
);
separator Le sparateur entre la page actuelle et le nombre de pages. Par dfaut of . Ceci est utilis
en conjonction avec format =pages qui la valeur par dfaut de format :
echo $this->Paginator->counter(array(
'separator' => ' sur un total de '
));
model
Le
nom
du
model
en
cours
de
pagination,
par
dfaut
PaginatorHelper::defaultModel(). Ceci est utilis en conjonction avec la chane personnalise de loption format.
Helpers (Assistants)
659
PaginatorHelper::options($options = array())
Paramtres
$options (mixed) Options par dfaut pour les liens de pagination. Si une chane
est fournie - elle est utilise comme id de llment DOM actualiser.
Dfinit toutes les options pour le Helper Paginator Helper. Les options supportes sont :
url LURL de laction de pagination. url comporte quelques sous options telles que :
sort La cl qui dcrit la faon de trier les enregistrements.
direction La direction du tri. Par dfaut ASC.
page Le numro de page afficher.
Les options mentionnes ci-dessus peuvent tre utilises pour forcer des pages/directions particulires.
Vous pouvez aussi ajouter des contenu dURL supplmentaires dans toutes les URLs gnres dans le
helper :
$this->Paginator->options(array(
'url' => array(
'sort' => 'email', 'direction' => 'desc', 'page' => 6,
'lang' => 'en'
)
));
Ce qui se trouve ci-dessus ajoutera en comme paramtre de route pour chacun des liens que le helper va
gnrer. Il crera galement des liens avec des tris, direction et valeurs de page spcifiques. Par dfaut
PaginatorHelper fusionnera cela dans tous les paramtres passs et nomms. Ainsi vous naurez pas le
faire dans chacun des fichiers de vue.
escape Dfinit si le champ titre des liens doit tre chapp HTML. Par dfaut true.
update Le selecteur CSS de llment actualiser avec le rsultat de lappel de pagination AJAX. Si
cela nest pas spcifi, des liens rguliers seront crs :
$this->Paginator->options(array('update' => '#content'));
Ceci est utile lors de lutilisation de la pagination AJAX La Pagination AJAX. Gardez lesprit que la
valeur actualise peut tre un selecteur CSS valide, mais il est souvent plus simple dutiliser un selecteur
id.
model
Le
nom
du
model
en
cours
de
pagination,
par
dfaut
PaginatorHelper::defaultModel().
Utilisation de paramtres GET pour la pagination Normalement la Pagination dans CakePHP utilise
Paramtres Nomms. Il y a des fois ou vous souhaiterez utilisez des paramtres GET la place. Alors que la
principale option de configuration pour cette fonctionnalit est dans PaginatorComponent, vous avez
des contrles supplmentaires dans les vues. Vous pouvez utiliser options() pour indiquer que vous voulez
la conversion dautres paramtres nomms :
$this->Paginator->options(array(
'convertKeys' => array('your', 'keys', 'here')
));
660
Configurer le Helper Paginator pour utiliser le Helper Javascript Par dfaut le Helper
Paginator utilise JsHelper pour effectuer les fonctionnalits AJAX. Toutefois, si vous ne voulez
pas cela et que vous voulez utiliser un Helper personnalis pour les liens AJAX, vous pouvez le faire en
changeant le tableau $helpers dans votre controller. Aprs avoir lanc paginate() fates ce qui suit :
// Dans l'action de votre controller.
$this->set('posts', $this->paginate());
$this->helpers['Paginator'] = array('ajax' => 'CustomJs');
Changera le Helper Paginator pour utiliser CustomJs pour les oprations AJAX. Vous pourriez
aussi dfinir la cl AJAX pour tre un Helper, tant que la classe implmente la mthode link() qui se
comporte comme HtmlHelper::link().
La Pagination dans les Vues
Cest vous de dcider comment afficher les enregistrements lutilisateur, mais la plupart des fois, ce sera
fait lintrieur des tables HTML. Lexemple ci-dessous suppose une prsentation tabulaire, mais le Helper
Paginator disponible dans les vues Na pas toujours besoin dtre limit en tant que tel.
Voir les dtails sur PaginatorHelper 15 dans l API. Comme mentionn prcdemment, le Helper Paginator
offre galement des fonctionnalits de tri qui peuvent tre facilement intgrs dans vos en-ttes de colonne
de table :
// app/View/Posts/index.ctp
<table>
<tr>
<th><?php echo $this->Paginator->sort('id', 'ID'); ?></th>
<th><?php echo $this->Paginator->sort('title', 'Title'); ?></th>
</tr>
<?php foreach ($data as $recipe): ?>
<tr>
<td><?php echo $recipe['Recipe']['id']; ?> </td>
<td><?php echo h($recipe['Recipe']['title']); ?> </td>
</tr>
<?php endforeach; ?>
</table>
Helpers (Assistants)
661
Lingrdient final pour laffichage de la pagination dans les vues est laddition de pages de navigation, aussi
fournies par le Helper de Pagination :
// Montre les numros de page
echo $this->Paginator->numbers();
// Montre les liens prcdent et suivant
echo $this->Paginator->prev(' Previous', null, null, array('class' => 'disabled'));
echo $this->Paginator->next('Next ', null, null, array('class' => 'disabled'));
// affiche X et Y, ou X est la page courante et Y est le nombre de pages
echo $this->Paginator->counter();
Le texte de sortie de la mthode counter() peut galement tre personnalis en utilisant des marqueurs
spciaux :
echo $this->Paginator->counter(array(
'format' => 'Page {:page} of {:pages}, showing {:current} records out of
{:count} total, starting on record {:start}, ending on {:end}'
));
Dautres Mthodes
cela
crerait
un
lien
pointant
vers
662
$asArray (boolean) Retourne lURL comme dans un tableau, ou une chane URL.
Par dfaut false.
$model (string) Le model sur lequel paginer.
Par dfaut retourne une chane URL compltement pagine utiliser dans des contextes non-standard
(ex. JavaScript).
echo $this->Paginator->url(array('sort' => 'titre'), true);
PaginatorHelper::defaultModel()
Retourne le model par dfaut du jeu de pagination ou null si la pagination nest pas initialise.
PaginatorHelper::params(string $model = null)
Retourne les paramtres courants de la pagination du jeu de rsultat dun model donn :
debug($this->Paginator->params());
/*
Array
(
[page] => 2
[current] => 2
[count] => 43
[prevPage] => 1
[nextPage] => 3
[pageCount] => 3
[order] =>
[limit] => 20
[options] => Array
(
[page] => 2
[conditions] => Array
(
)
)
[paramType] => named
)
*/
Helpers (Assistants)
663
Cet exemple suppose que vous ayez un Controller Posts et un Model Post dj crs et que vous vouliez
crer une vue alternative pour les flux RSS.
Crer une version xml/rss de posts/index est vraiment simple avec CakePHP. Aprs quelques tapes faciles,
vous pouvez tout simplement ajouter lextension .rss demande posts/index pour en faire votre URL
posts/index.rss. Avant daller plus loin en essayant dinitialiser et de lancer notre service Web, nous
avons besoin de faire un certain nombre de choses. Premirement, le parsing dextensions doit tre activ
dans app/config/routes.php :
Router::parseExtensions('rss');
Dans lappel ci-dessus, nous avons activ lextension .rss. Quand vous utilisez
Router::parseExtensions(), vous pouvez passer autant darguments ou dextensions que
vous le souhaitez. Cela activera le content-type de chaque extension utilise dans votre application.
Maintenant, quand ladresse posts/index.rss est demande, vous obtiendrez une version XML de
votre posts/index. Cependant, nous avons dabord besoin dditer le controller pour y ajouter le code
rss-spcifique.
Code du Controller Cest une bonne ide dajouter RequestHandler au tableau $components de votre
controller Posts. Cela permettra beaucoup dautomagie de se produire :
public $components = array('RequestHandler');
Notre vue utilise aussi TextHelper pour le formatage, ainsi il doit aussi tre ajout au controller :
public $helpers = array('Text');
664
Avant que nous puissions faire une version RSS de notre posts/index, nous avons besoin de mettre certaines
choses en ordre. Il pourrait tre tentant de mettre le canal des mtadonnes dans laction du controller et
de le passer votre vue en utilisant la mthode Controller::set(), mais ceci est inappropri. Cette
information pourrait galement aller dans la vue. Cela arrivera sans doute plus tard, mais pour linstant,
si vous avez un ensemble de logique diffrent entre les donnes utilises pour crer le flux RSS et les
donnes pour la page HTML, vous pouvez utiliser la mthode RequestHandler::isRss(), sinon
votre controller pourrait rester le mme :
// Modifie l'action du Controller Posts correspondant
// l'action qui dlivre le flux rss, laquelle est
// l'action index dans notre exemple
public function index() {
if ($this->RequestHandler->isRss() ) {
$posts = $this->Post->find(
'all',
array('limit' => 20, 'order' => 'Post.created DESC')
);
return $this->set(compact('posts'));
}
// ceci n'est pas une requte RSS
// donc on retourne les donnes utilises par l'interface du site web
$this->paginate['Post'] = array(
'order' => 'Post.created DESC',
'limit' => 10
);
$posts = $this->paginate();
$this->set(compact('posts'));
}
Maintenant que toutes ces variables de Vue sont dfinies, nous avons besoin de crer un layout rss.
Layout Un
layout
Rss
est
trs
simple,
app/View/Layouts/rss/default.ctp :
mettez
les
contenus
suivants
dans
if (!isset($documentData)) {
$documentData = array();
}
if (!isset($channelData)) {
$channelData = array();
}
if (!isset($channelData['title'])) {
$channelData['title'] = $this->fetch('title');
}
$channel = $this->Rss->channel(array(), $channelData, $this->fetch('content'));
echo $this->Rss->document($documentData, $channel);
Il ne ressemble pas plus mais grce la puissance du RssHelper il fait beaucoup pour amliorer le visuel
pour nous. Nous navons pas dfini $documentData ou $channelData dans le controller, cependant
Helpers (Assistants)
665
dans CakePHP vos vues peuvent retourner les variables au layout. Ce qui est lendroit o notre tableau
$channelData va venir dfinir toutes les donnes meta pour notre flux.
Ensuite il y a le fichier de vue pour mes posts/index. Un peu comme le fichier de layout que nous avons cr,
nous avons besoin de crer un rpertoire View/Posts/rss/ et un nouveau index.ctp lintrieur de
ce rpertoire. Les contenus du fichier sont ci-dessous.
View Notre vue, localise dans app/View/Posts/rss/index.ctp, commence par dfinir les variables $documentData et $channelData pour le layout, celles-ci contiennent toutes les metadonnes
pour notre flux RSS. Cest fait en utilisant la mthode View::set() qui est analogue la mthode
View::set(). Ici nous passons les canaux de donnes en retour au layout :
$this->set('channelData', array(
'title' => __("Most Recent Posts"),
'link' => $this->Html->url('/', true),
'description' => __("Most recent posts."),
'language' => 'en-us'));
La seconde partie de la vue gnre les lments pour les enregistrements actuels du flux. Ceci est accompli en bouclant sur les donnes qui ont t passes la vue ($items) et en utilisant la mthode
RssHelper::item(). Lautre mthode que vous pouvez utiliser RssHelper::items() qui prend
un callback et un tableau des items pour le flux. (La mthode que jai vu utilise pour le callback a toujours
t appele transformRss(). Il y a un problme pour cette mthode, qui est quelle nutilise aucune des
classes de helper pour prparer vos donnes lintrieur de la mthode de callback parce que la porte
lintrieur de la mthode ninclut pas tout ce qui nest pas pass lintrieur, ainsi ne donne pas accs au
TimeHelper ou tout autre helper dont vous auriez besoin. RssHelper::item() transforme le tableau
associatif en un lment pour chaque pair de valeur de cl.
Note : Vous devrez modifier la variable $postLink comme il se doit pour votre application.
foreach ($posts as $post) {
$postTime = strtotime($post['Post']['created']);
$postLink = array(
'controller' => 'posts',
'action' => 'view',
'year' => date('Y', $postTime),
'month' => date('m', $postTime),
'day' => date('d', $postTime),
$post['Post']['slug']
);
// Retire & chappe tout HTML pour tre sr que le contenu va tre valid.
$bodyText = h(strip_tags($post['Post']['body']));
$bodyText = $this->Text->truncate($bodyText, 400, array(
'ending' => '...',
'exact' => true,
'html'
=> true,
));
666
echo
$this->Rss->item(array(), array(
'title' => $post['Post']['title'],
'link' => $postLink,
'guid' => array('url' => $postLink, 'isPermaLink' => 'true'),
'description' => $bodyText,
'pubDate' => $post['Post']['created']
));
}
Vous pouvez voir ci-dessus que nous pouvons utiliser la boucle pour prparer les donnes devant tre transformes en lments XML. Il est important de filtrer tout texte de caractres non brute en-dehors de la
description, spcialement si vous utilisez un diteur de texte riche pour le corps de votre blog. Dans le
code ci-dessus nous utilisons strip_tags() et h() pour retirer/chapper tout caractre spcial XML du
contenu, puisquils peuvent entraner des erreurs de validation. Une fois que nous avons dfini les donnes
pour le feed, nous pouvons ensuite utiliser la mthode RssHelper::item() pour crer le XML dans le
format RSS. Une fois que vous avez toutes ces configurations, vous pouvez tester votre feed RSS en allant
votre /posts/index.rss et que vous verrez votre nouveau feed. Il est toujours important que vous
validiez votre feed RSS avant de le mettre en live. Ceci peut tre fait en visitant les sites qui valident le XML
comme Le Validateur de Feed ou le site de w3c http ://validator.w3.org/feed/.
Note : Vous aurez besoin de dfinir la valeur de debug dans votre configuration du coeur 1 ou 0 pour
obtenir un flux valide, cause des diffrentes informations de debug ajoutes automatiquement sous des
paramtres de debug plus haut qui cassent la syntaxe XML ou les rgles de validation du flux.
property RssHelper::$action
Action courante
property RssHelper::$base
Base URL
property RssHelper::$data
donne du model POSTe
property RssHelper::$field
Nom du champ courant
property RssHelper::$helpers
Helpers utiliss par le Helper RSS
property RssHelper::$here
URL de laction courante
property RssHelper::$model
Nom du model courant
property RssHelper::$params
Paramtre tableau
Helpers (Assistants)
667
property RssHelper::$version
Version de spec par dfaut de la gnration de RSS.
RssHelper::channel(array $attrib = array (), array $elements = array (), mixed $content =
null)
Type retourn string
Retourne un lment RSS <channel />.
RssHelper::document(array $attrib = array (), string $content = null)
Type retourn string
Retourne un document RSS entour de tags <rss />.
RssHelper::elem(string $name, array $attrib = array (), mixed $content = null, boolean $endTag = true)
Type retourn string
Gnre un lment XML.
RssHelper::item(array $att = array (), array $elements = array ())
Type retourn string
Convertit un tableau en un lment <item /> et ses contenus.
RssHelper::items(array $items, mixed $callback = null)
Type retourn string
Transforme un tableau de donnes en utilisant un callback optionnel, et le map pour un ensemble de
tags <item />.
RssHelper::time(mixed $time)
Type retourn string
Convertit un time de tout format en time de RSS. Regardez TimeHelper::toRSS().
SessionHelper
class SessionHelper(View $view, array $settings = array())
quivalent du Component Session, le Helper Session offre la majorit des fonctionnalits du component
et les rend disponible dans votre vue. Le Helper session est automatiquement ajout la vue, il nest pas
ncessaire de lajouter la variable tableau $helpers dans votre controller.
La grande diffrence entre le Component Session et le Helper Session est que ce dernier ne peut pas crire
dans la session.
Comme pour le Component Session, les donnes sont crites et lues en utilisant des structures de tableaux
avec la notation avec points, comme ci-dessous :
array('User' =>
array('username' => 'super@example.com')
);
668
tant donn ce tableau, le nud sera accessible par User.username, le point indiquant le tableau imbriqu. Cette notation est utilise pour toutes les mthodes du helper Session o une variable $key est
utilise.
SessionHelper::read(string $key)
Type retourn mixed
Lire partir de la Session. Retourne une chane de caractre ou un tableau dpendant des contenus de
la session.
SessionHelper::consume($name)
Type retourn mixed
Lit et supprime une valeur de Session. Cest utile quand vous voulez combiner la lecture et la suppression de valeurs en une seule opration.
SessionHelper::check(string $key)
Type retourn boolean
Vrifie si une cl est dans la Session. Retourne un bolen sur lexistence dun cl.
SessionHelper::error()
Type retourn string
Retourne la dernire erreur encourue dans une session.
SessionHelper::valid()
Type retourn boolean
Utilise pour vrifier si une session est valide dans une vue.
Affichage de notifications ou de messages flash
Comme pour la mthode du component, vous pouvez dfinir des proprits supplmentaires et personnaliser quel lment est utilis. Dans le controller, vous pouvez avoir du code comme :
// dans un controller
$this->Session->setFlash('Le user n'a pu tre supprim.');
Helpers (Assistants)
669
Quand le message sort, vous pouvez choisir llment utilis pour afficher ce message :
// dans un layout.
echo $this->Session->flash('flash', array('element' => 'failure'));
Vous pouvez aussi passer des paramtres supplmentaires dans la mthode flash(), ce qui vous
permet de gnrer des messages personnaliss :
// Dans le controller
$this->Session->setFlash('Thanks for your payment %s');
// Dans le layout.
echo $this->Session->flash('flash', array(
'params' => array('name' => $user['User']['name'])
'element' => 'payment'
));
// View/Elements/payment.ctp
<div class="flash payment">
<?php printf($message, h($name)); ?>
</div>
TextHelper
class TextHelper(View $view, array $settings = array())
TextHelper possde des mthodes pour rendre le texte plus utilisable et sympa dans vos vues. Il aide activer
les liens, formater les URLs, crer des extraits de texte autour des mots ou des phrases choisies, mettant
en vidence des mots cls dans des blocs de texte et tronquer lgamment de longues tendues de texte.
Modifi dans la version 2.1 : Plusieurs des mthodes de TextHelper ont t dplaces dans la classe
String pour permettre une utilisation plus facile de la couche View. Dans une vue, ces mthodes sont
accessibles avec la classe TextHelper et vous pouvez lappeler comme vous appelleriez une mthode normale
de helper : $this->Text->method($args);.
TextHelper::autoLinkEmails(string $text, array $options=array())
Paramtres
$text (string) Le texte convertir.
$options (array) Un tableau d attributs HTML pour gnrer les liens.
Ajoute les liens aux adresses email bien formes dans $text, selon toute les options dfinies dans
$options (regardez HtmlHelper::link()).
670
Sortie :
Pour plus d'informations sur nos ptes et desserts fameux,
contactez <a href="mailto:info@example.com">info@example.com</a>
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement ces inputs. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoLinkUrls(string $text, array $options=array())
Paramtres
$text (string) Le texte convertir.
$options (array) Un tableau d attributs HTML pour la gnration de liens.
De mme que dans autoLinkEmails(), seule cette mthode cherche les chanes de caractre qui
commence par https, http, ftp, ou nntp et les liens de manire approprie.
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement son input. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoLink(string $text, array $options=array())
Paramtres
$text (string) Le texte lier automatiquement.
$htmlOptions (array) Un tableau d attributs HTML pour gnrer les liens.
Excute la fonctionnalit dans les deux autoLinkUrls() et autoLinkEmails() sur le $text
fourni. Tous les URLs et emails sont lis de manire approprie donne par $htmlOptions fourni.
Modifi dans la version 2.1 : Dans 2.1, cette mthode chappe automatiquement son input. Utilisez
loption escape pour la dsactiver si ncessaire.
TextHelper::autoParagraph(string $text)
Paramtres
$text (string) Le texte convertir.
Ajoute <p> autour du texte o la double ligne retourne et <br> o une simple ligne retourne, sont
trouvs.
$myText = 'For more information
regarding our world-famous pastries and desserts.
contact info@example.com';
$formattedText = $this->Text->autoParagraph($myText);
Output :
<p>Pour plus d\'information<br />
selon nos clbres ptes et desserts.<p>
<p>contact info@example.com</p>
671
Paramtres
$haystack (string) La chane de caractres rechercher.
$needle (string) La chane trouver.
$options (array) Un tableau doptions, voir ci-dessous.
Mettre en avant $needle dans $haystack en utilisant la chane spcifique
$options[format] ou une chane par dfaut.
Options :
format - chane la partie de html avec laquelle la phrase sera mise en exergue.
html - bool Si true, va ignorer tous les tags HTML, sassurant que seul le bon texte est mise en
avant.
Exemple :
// appel avec TextHelper
echo $this->Text->highlight(
$lastSentence,
'using',
array('format' => '<span class="highlight">\1</span>')
);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::highlight(
$lastSentence,
'using',
array('format' => '<span class="highlight">\1</span>')
);
Sortie :
Highlights $needle in $haystack <span class="highlight">using</span>
the $options['format'] string specified or a default string.
TextHelper::stripLinks($text)
Enlve le $text fourni de tout lien HTML.
TextHelper::truncate(string $text, int $length=100, array $options)
Paramtres
$text (string) Le texte tronquer.
$length (int) La longueur en caractres pour laquelle le texte doit tre tronqu.
$options (array) Un tableau doptions utiliser.
Si $text est plus long que $length, cette mthode le tronque la longueur $length et ajoute un
prefix ellipsis, si dfini. Si exact est pass false, le truchement va se faire au premier
espace aprs le point o $length a dpass. Si html est pass true, les balises html seront
respectes et ne seront pas coupes.
$options est utilis pour passer tous les paramtres supplmentaires, et a les cls suivantes possibles par dfaut, celles-ci tant toutes optionnelles :
array(
'ellipsis' => '...',
'exact' => true,
672
Exemple :
// appel avec TextHelper
echo $this->Text->truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
Sortie :
The killer crept...
Modifi dans la version 2.3 : ending a t remplac par ellipsis. ending est toujours utilis dans
2.2.1.
TextHelper::tail(string $text, int $length=100, array $options)
Paramtres
$text (string) The text tronquer.
$length (int) La longueur en caractres pour laquelle le texte doit tre tronqu.
$options (array) Un tableau doptions utiliser.
Si $text est plus long que $length, cette mthode retire une sous-chane initiale avec la longueur
de la diffrence et ajoute un suffixe ellipsis, si il est dfini. Si exact est pass false,
le truchement va se faire au premier espace avant le moment o le truchement aurait t fait.
$options est utilis pour passer tous les paramtres supplmentaires, et a les cls possibles suivantes par dfaut, toutes sont optionnelles :
array(
'ellipsis' => '...',
'exact' => true
)
Helpers (Assistants)
673
$sampleText = 'I packed my bag and in it I put a PSP, a PS3, a TV, ' .
'a C# program that can divide by zero, death metal t-shirts'
// appel avec TextHelper
echo $this->Text->tail(
$sampleText,
70,
array(
'ellipsis' => '...',
'exact' => false
)
);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::tail(
$sampleText,
70,
array(
'ellipsis' => '...',
'exact' => false
)
);
Sortie :
...a TV, a C# program that can divide by zero, death metal t-shirts
Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...
674
Sortie :
red, orange, yellow, green, blue, indigo et violet
TimeHelper
class TimeHelper(View $view, array $settings = array())
Le Helper Time vous permet, comme il lindique de gagner du temps. Il permet le traitement rapide des
informations se rapportant au temps. Le Helper Time a deux tches principales quil peut accomplir :
1. Il peut formater les chanes de temps.
2. Il peut tester le temps (mais ne peut pas le courber, dsol).
Modifi dans la version 2.1 : TimeHelper a t reconstruit dans la classe CakeTime pour faciliter lutilisation en-dehors de la couche View. Dans une vue, ces mthodes sont accessibles via la
classe TimeHelper et vous pouvez lappeler comme vous appelleriez une mthode normale de helper :
$this->Time->method($args);.
Utiliser le Helper
Une utilisation courante de Time Helper est de compenser la date et le time pour correspondre au
time zone de lutilisateur. Utilisons un exemple de forum. Votre forum a plusieurs utilisateurs qui
peuvent poster des messages depuis nimporte quelle partie du monde. Une faon facile de grer le
temps est de sauvegarder toutes les dates et les times GMT+0 or UTC. Dcommenter la ligne
date_default_timezone_set(UTC); dans app/Config/core.php pour sassurer que le
time zone de votre aplication est dfini GMT+0.
Ensuite, ajoutez un time zone votre table users et fates les modifications ncessaires pour permettre vos
utilisateurs de dfinir leur time zone. Maintenant que nous connaissons le time zone de lutilisateur connect,
nous pouvons corriger la date et le temps de nos posts en utilisant le Helper Time :
echo $this->Time->format(
'F jS, Y h:i A',
$post['Post']['created'],
null,
$user['User']['time_zone']
Helpers (Assistants)
675
);
// Affichera August 22nd, 2011 11:53 PM pour un utilisateur dans GMT+0
// August 22nd, 2011 03:53 PM pour un utilisateur dans GMT-8
// et August 23rd, 2011 09:53 AM GMT+10
La plupart des mthodes du Helper Time contiennent un paramtre $timezone. Le paramtre $timezone
accepte une chane identifiante de timezone valide ou une instance de la classe DateTimeZone.
Formatage
676
Modifi dans la version 2.2 : Le paramtre $timezone remplace $userOffset utilis dans 2.1 et
suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::format($date, $format = NULL, $default = false, $timezone = NULL)
Type retourn string
Va retourner une chane formate avec le format donn en utilisant les options de formatage de la
fonction PHP strftime() 16 :
// appel via TimeHelper
echo $this->Time->format('2011-08-22 11:53:00', '%B %e, %Y %H:%M %p');
// August 22nd, 2011 11:53 AM
echo $this->Time->format('%r', '+2 days');
// 2 days from now formatted as Sun, 13 Nov 2011 03:36:10 AM EET
// appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2011-08-22 11:53:00', '%B %e, %Y %H:%M %p');
echo CakeTime::format('+2 days', '%c');
Vous pouvez aussi fournir la date/time en premier argument. En faisant cela vous devrez utiliser le
format strftime compatible. Cette signature dappel vous permet de tirer parti du format de date
de la locale ce qui nest pas possible en utilisant le format de date() compatible :
// appel avec TimeHelper
echo $this->Time->format('2012-01-13', '%d-%m-%Y', 'invalid');
// appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2011-08-22', '%d-%m-%Y');
Modifi dans la version 2.2 : Les paramtres $format et $date sont en ordre oppos par rapport ce qui se faisait dans 2.1 et suivants. Le paramtre $timezone remplace le paramtre
16. http ://www.php.net/manual/en/function.strftime.php
Helpers (Assistants)
677
678
Helpers (Assistants)
679
Utilisez loption end pour dterminer le point de cutoff pour ne plus utiliser de mots ; par dfaut
+1 month :
// Appel avec TimeHelper
echo $this->Time->timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
// On Nov 10th, 2011 it would display: 2 months, 2 weeks, 6 days ago
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
Utilisez loption accuracy pour dterminer la prcision de la sortie. Vous pouvez utiliser ceci pour
limiter la sortie :
// Si $timestamp est il y a 1 month, 1 week, 5 days et 6 hours
echo CakeTime::timeAgoInWords($timestamp, array(
'accuracy' => array('month' => 'month'),
'end' => '1 year'
));
// Sort '1 month ago'
680
(
[0] => 2011-07-01
[1] => 2011-09-30
)
*/
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::toQuarter('Aug 22, 2011');
$arr = CakeTime::toQuarter('Aug 22, 2011', true);
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
Introduit dans la version 2.4 : Les nouveaux paramtres doption relativeString (par dfaut
%s ago) et absoluteString (par dfaut on %s) pour permettre la personnalisation de la
chane de sortie rsultante sont maintenant disponibles.
TimeHelper::toRSS($dateString, $timezone = NULL)
Type retourn string
Va retourner une chane de date au format RSS Sat, 12 Jan 2008 00 :00 :00 -0500
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toUnix($dateString, $timezone = NULL)
Type retourn integer
Un enrouleur pour fromString.
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toServer($dateString, $timezone = NULL, $format = Y-m-d H :i :s)
Type retourn mixed
Introduit dans la version 2.2 : Retourne une date formate dans le timezone du serveur.
TimeHelper::timezone($timezone = NULL)
Type retourn DateTimeZone
Introduit dans la version 2.2 : Retourne un objet timezone partir dune chane de caractres ou de
lobjet timezone de lutilisateur. Si la fonction est appele sans paramtres, elle essaie dobtenir le
timezone de la variable de configuration Config.timezone.
TimeHelper::listTimezones($filter = null, $country = null, $options = array())
Type retourn array
Introduit dans la version 2.2 : Retourne une liste des identificateurs de timezone.
Modifi dans la version 2.8 : $options accepte maintenant un tableau avec les cls group, abbr,
before, et after. Spcifier abbr => true va ajouter labrviation de la timezone dans le texte
<option>.
Helpers (Assistants)
681
Tester Time
wasWithinLast prend un intervalle de time qui est une chane au format 3 months et accepte un
intervalle de time en secondes, minutes, heures, jours, semaines, mois et annes (pluriels ou non). Si
un intervalle de time nest pas reconnu (par exemple, si il y a une faute de frappe) ensuite ce sera par
dfaut days.
Utilitaires
En plus des components du coeur MVC, CakePHP inclut une bonne slection de classes utilitaires qui vous
aident faire tout partir de requtes de services web, de mettre en cache, de se logger, dinternationaliser
et plus encore.
682
Utilitaires
La mise en cache
La mise en cache est frquemment utilise pour rduire le temps pris pour crer ou lire depuis une autre
ressource. La mise en cache est souvent utilise pour rendre la lecture de ressources consommatrices en
temps en ressources moins consommatrice. Vous pouvez aisment stocker en cache les rsultats de requtes
consommatrices en ressources ou les accs distance des services web qui ne changent pas frquemment.
Une fois mis en cache, re-lire les ressources stockes depuis le cache est moins consommateur en ressource
quun accs a une ressource distante.
La mise en cache dans CakePHP se fait principalement par la classe Cache. Cette classe fournit un ensemble
de mthodes statiques qui fournissent une API uniforme pour le traitement des diffrentes implmentations
de mise en cache. CakePHP arrive avec plusieurs moteurs de cache intgrs, et fournit un systme facile
pour implmenter votre propre systme de mise en cache. Les moteurs de cache intgrs sont :
FileCache File cache est un cache simple qui utilise des fichiers locaux. Cest le moteur de cache le
plus lent, et il ne fournit que peu de fonctionnalits pour les oprations atomiques. Cependant, le stockage
sur disque est souvent peu consommateur en ressource, le stockage de grands objets ou des lments qui
sont rarement crits fonctionne bien dans les fichiers. Cest le moteur de Cache par dfaut pour 2.3+.
ApcCache Le cache APC utilise lextension PHP APC 18 . Cette extension utilise la mmoire partage
du serveur Web pour stocker les objets. Cela le rend trs rapide, et capable de fournir les fonctionnalits
atomiques en lecture/criture. Par dfaut CakePHP dans 2.0-2.2 utilisera ce moteur de cache si il est
disponible.
Wincache Utilise lextension Wincache 19 . Wincache offre des fonctionnalits et des performances semblables APC, mais optimises pour Windows et IIS.
XcacheEngine Xcache 20 . est une extension PHP qui fournit des fonctionnalits similaires APC.
MemcacheEngine Utilise lextension Memcache 21 . Memcache fournit un cache trs rapide qui peut
tre distribu au travers de nombreux serveurs et il permet les oprations atomiques.
MemcachedEngine Utilise lextension Memcached 22 . Il est aussi une interface avec memcache mais
il fournit une meilleur performance.
RedisEngine Utilise lextension phpredis 23 . Redis fournit un systme de cache cohrent et rapide
similaire memcached et il permet aussi les oprations atomiques.
. versionchanged : : 2.3 FileEngine est toujours le moteur de cache par dfaut. Dans le pass, un certain nombre de personnes avait des difficults configurer et dployer APC correctement dans les
deux cli + web. Utiliser les fichiers devrait faciliter la configuration de CakePHP pour les nouveaux
dveloppeurs.
Modifi dans la version 2.5 : Le moteur Memcached a t ajout. Et le moteur Memcache a t dprci.
Quelque soit le moteur de cache que vous choisirez dutiliser, votre application interagit avec Cache de
manire cohrente. Cela signifie que vous pouvez aisment permuter les moteurs de cache en fonction de
lvolution de votre application. En plus de la classe Cache, le Helper CacheHelper vous permet le cache
en pleine page, qui peut ainsi grandement amliorer les performances.
18.
19.
20.
21.
22.
23.
http ://php.net/apc
http ://php.net/wincache
http ://xcache.lighttpd.net/
http ://php.net/memcache
http ://php.net/memcached
https ://github.com/nicolasff/phpredis
Utilitaires
683
La configuration de la classe Cache peut tre effectue nimporte o, mais gnralement vous voudrez configurer le cache dans app/Config/bootstrap.php. Vous pouvez configurer autant de configurations
de cache dont vous avez besoin, et vous pouvez utiliser tous les mlanges de moteurs de cache. CakePHP
utilise deux configurations de cache en interne, qui sont configurs dans app/Config/core.php. Si
vous utilisez APC ou Memcache vous devrez vous assurer de dfinir des cls uniques pour les caches du
noyau. Ceci vous vitera quune application vienne rcrire les donnes cache dune autre application.
Lutilisation de plusieurs configurations de cache peut aider rduire le nombre de fois o vous aurez
utiliser Cache::set() et permettra aussi de centraliser tous vos paramtres de cache. Lutilisation de
plusieurs configurations vous permet galement de changer le stockage comme vous lentendez.
Note : Vous devez spcifier le moteur utiliser. Il ne met pas File par dfaut.
Exemple :
Cache::config('short', array(
'engine' => 'File',
'duration' => '+1 hours',
'path' => CACHE,
'prefix' => 'cake_short_'
));
// long
Cache::config('long', array(
'engine' => 'File',
'duration' => '+1 week',
'probability' => 100,
'path' => CACHE . 'long' . DS,
));
En insrant le code ci-dessus dans votre app/Config/bootstrap.php vous aurez deux configurations
de cache supplmentaires. Le nom de ces configurations short ou long est utilis comme paramtre
$config pour Cache::write() et Cache::read().
Note : Quand vous utilisez le moteur FileEngine vous pouvez avoir besoin de loption mask pour vous
assurer que les fichiers cachs sont crs avec les bonnes permissions.
Introduit dans la version 2.4 : En mode debug, les rpertoires manquants vont tre maintenant automatiquement crs pour viter le lancement des erreurs non ncessaires lors de lutilisation de FileEngine.
Cration dun moteur de stockage pour le Cache
Vous pouvez fournir vos propre adaptateurs Cache dans app/Lib ou dans un plugin en
utilisant $plugin/Lib. Les moteurs de cache App/plugin peuvent aussi remplacer les moteurs du coeur. Les adaptateurs de cache doivent tre dans un rpertoire cache. Si vous
avez un moteur de cache nomm MonMoteurDeCachePerso il devra tre plac soit dans
app/Lib/Cache/Engine/MonMoteurDeCachePerso.php comme une app/librairie ou dans
684
Note :
Les moteurs de cache App et Plugin doivent tre configurs dans
app/Config/bootstrap.php. Si vous essayez de les configurer dans core.php ils ne fonctionneront pas correctement.
Les moteurs de cache personnaliss doivent tendre CacheEngine qui dfinit un certain nombre de mthodes dabstraction ainsi que quelques mthodes dinitialisation.
LAPI requise pour CacheEngine est
class CacheEngine
La classe de base pour tous les moteurs de cache utilise avec le Cache.
CacheEngine::write($key, $value, $config = default)
Retourne un boolen en cas de succs.
crit la valeur dune cl dans le cache, la chane optionnelle $config spcifie le nom de la configuration
crire.
CacheEngine::read($key, $config = default)
Retourne La valeur mise en cache ou false en cas dchec.
Lit une cl depuis le cache. Retourne false pour indiquer que lentre a expir ou nexiste pas.
CacheEngine::delete($key, $config = default)
Retourne Un boolen true en cas de succs.
Efface une cl depuis le cache. Retourne false pour indiquer que lentre nexiste pas ou ne peut tre
efface.
CacheEngine::clear($check)
Retourne Un Boolen true en cas de succs.
Efface toutes les cls depuis le cache. Si $check est true, vous devez valider que chacune des valeurs
a rellement expire.
CacheEngine::clearGroup($group)
Retourne Boolean true en cas de succs.
Supprime toutes les cls partir du cache appartenant au mme groupe.
CacheEngine::decrement($key, $offset = 1)
Retourne La valeur dcrmente en en cas de succs, false sinon.
Dcrmente un nombre dans la cl et retourne la valeur dcrmente
CacheEngine::increment($key, $offset = 1)
Retourne La valeur incrmente en en cas de succs, false sinon.
Utilitaires
685
Vous pouvez considrablement amliorer les performances de vos applications en plaant les rsultats qui
ne changent que peu frquemment ou qui peuvent tre sujets de nombreuses lectures dans le cache. Un
exemple parfait de ceci pourrait tre les rsultats dun find Model::find(). Une mthode qui utilise la
mise en Cache pour stocker les rsultats pourrait ressembler cela
class Post extends AppModel {
Vous pouvez amliorer le code ci-dessus en dplaant la lecture du cache dans un comportement, qui lit
depuis le cache, ou qui excute les mthodes de model. Cest un exercice que vous pouvez faire.
Depuis 2.5, vous pouvez accomplir ce qui est au-dessus de faon bien plus simple en utilisant
Cache::remember(). Utiliser la nouvelle mthode ci-dessous ressemblerait ceci :
class Post extends AppModel {
public function newest() {
$model = $this;
return Cache::remember('newest_posts', function() use ($model){
return $model->find('all', array(
'order' => 'Post.updated DESC',
'limit' => 10
));
}, 'longterm');
}
}
686
Lutilisation de compteurs dans le cache peut tre une chose intressante. Par exemple un simple compte
rebours pour retenir les slots restants dun concours pourrait tre stock en Cache. La classe Cache propose
des moyens atomiques pour incrmenter/dcrmenter des valeurs de compteur facilement. Les oprations
atomiques sont importantes pour ces valeurs parce que cela rduit le risque de contention et la capacit de
deux utilisateurs simultanment en abaisser la valeur et de se retrouver avec une valeur incorrecte.
Aprs avoir dfini une valeur entire vous pouvez la manipuler en utilisant Cache::increment() et
Cache::decrement() :
Cache::write('compteur_initial', 10);
// Plus tard sur
Cache::decrement('compteur_initial');
//ou
Cache::increment('compteur_initial');
Note : Lincrmentation et la dcrmentation ne fonctionne pas avec le moteur FileEngine. Vous devez
utiliser APC ou Memcached en remplacement.
Disons que vous voulez stocker le HTML gnr pour votre page daccueil dans le cache, mais vous voulez
aussi invalider automatiquement ce cache chaque fois quun commentaire ou un post est ajout votre base
de donnes. En ajoutant les groupes comment et post, nous avons effectivement taggs les cls stockes
dans la configuration du cache avec les noms des deux groupes.
Par exemple, ds quun post est ajout, nous pouvons dire au moteur de Cache de retirer toutes les entres
associes au groupe post :
// Model/Post.php
public function afterSave($created, $options = array()) {
if ($created) {
Cache::clearGroup('post', 'site_home');
Utilitaires
687
}
}
Les groupes sont partags travers toutes les configs de cache en utilisant le mme moteur et le mme
prfixe. Si vous utilisez les groupes et voulez tirer profit de la suppression de groupe, choisissez un prfixe
commun pour toutes vos configs.
lAPI de Cache
class Cache
La classe Cache dans CakePHP fournit un frontend gnrique pour plusieurs systmes de cache
backend. Diffrentes configurations de Cache et de moteurs peuvent tre configurs dans votre
app/Config/core.php
static Cache::config($name = null, $settings = array())
Cache::config() est utilise pour crer des configurations de cache supplmentaires. Ces configurations supplmentaires peuvent avoir diffrentes dures, moteurs, chemins, ou prfixes par rapport
la configuration par dfaut du cache.
static Cache::read($key, $config = default)
Cache : :read() est utilise pour lire la valeur en cache stocke dans $key depuis le $config. Si
$config est null la configuration par dfaut sera utilise. Cache::read() retournera la valeur en
cache si cest un cache valide ou false si le cache a expir ou nexiste pas. Le contenu du cache
pourrait tre vu comme false, donc assurez-vous que vous utilisez les oprateurs de comparaison
stricte === ou !==.
Par exemple :
$cloud = Cache::read('cloud');
if ($cloud !== false) {
return $cloud;
688
}
// gnration des donnes cloud
// ...
// stockage des donne en cache
Cache::write('cloud', $cloud);
return $cloud;
Utiliser Cache::write() et Cache::read() pour facilement rduire le nombre de dplacement fait dans la base de donnes pour rechercher les posts.
static Cache::delete($key, $config = default)
Cache::delete() vous permet denlever compltement un objet mis en cache de son lieu de
stockage de Cache.
static Cache::set($settings = array(), $value = null, $config = default)
Cache::set() vous permet de rcrire temporairement les paramtres de configs pour une opration (habituellement une lecture ou criture). Si vous utilisez Cache::set() pour changer les
paramtres pour une criture, vous devez aussi utiliser Cache::set() avant de lire les donnes
en retour. Si vous ne faites pas cela, les paramtres par dfaut seront utiliss quand la cl de cache est
lue.
Cache::set(array('duration' => '+30 days'));
Cache::write('results', $data);
// plus tard
Cache::set(array('duration' => '+30 days'));
$results = Cache::read('results');
Si vous trouvez que vous rptez lappel Cache::set() peut-tre devriez-vous crer une nouvelle
Cache::config(). Qui enlvera les besoins dappeler Cache::set().
static Cache::increment($key, $offset = 1, $config = default)
Incrmente de manire atomique une valeur stocke dans le moteur de cache. Idal pour modifier un
compteur ou des valeurs de smaphore.
static Cache::decrement($key, $offset = 1, $config = default)
Dcrmente de manire atomique une valeur stocke dans le moteur de cache. Idal pour modifier un
compteur ou des valeurs de smaphore.
Utilitaires
689
690
Cette classe remplace EmailComponent et donne plus de flexibilit dans lenvoi demails. Par exemple,
vous pouvez crer vos propres transports pour envoyer lemail au lieu dutiliser les transports SMTP et Mail
fournis.
Utilisation basique
Premirement, vous devez vous assurer que la classe est charge en utilisant App::uses() :
App::uses('CakeEmail', 'Network/Email');
Lutilisation de CakeEmail est similaire lutilisation de EmailComponent. Mais au lieu dutiliser les
attributs, vous utilisez les mthodes. Exemple :
$Email = new CakeEmail();
$Email->from(array('me@example.com' => 'My Site'));
$Email->to('you@example.com');
$Email->subject('About');
$Email->send('My message');
Pour simplifier les choses, toutes les mthodes de setter retournent linstance de classe. Vous pouvez rcrire le code ci-dessous :
$Email = new CakeEmail();
$Email->from(array('me@example.com' => 'My Site'))
->to('you@example.com')
->subject('About')
->send('Mon message');
Choisir lmetteur Quand on envoie des emails de la part dautre personne, cest souvent une bonne ide
de dfinir lmetteur original en utilisant le header Sender. Vous pouvez faire ceci en utilisant sender()
$Email = new CakeEmail();
$Email->sender('app@example.com', 'MyApp emailer');
Note : Cest aussi une bonne ide de dfinir lenveloppe de lmetteur quand on envoie un mail de la part
dune autre personne. Cela les empche dobtenir tout message sur la dlivrance.
Configuration
De mme que pour la base de donnes, la configuration demail peut tre centralise dans une classe.
Crer le fichier app/Config/email.php avec la classe EmailConfig.
app/Config/email.php.default donne un exemple de ce fichier.
Le
fichier
CakeEmail va crer une instance de la classe EmailConfig pour accder config. Si vous avez des
donnes dynamiques mettre dans les configs, vous pouvez utiliser le constructeur pour le faire :
Utilitaires
691
class EmailConfig {
public function __construct() {
// Faire des assignments conditionnel ici.
}
}
Il nest pas ncessaire de crer app/Config/email.php, CakeEmail peut tre utilis sans lui et
utiliser les mthodes respectives pour dfinir toutes les configurations sparment ou charger un tableau de
configs.
Pour charger un config partir de EmailConfig, vous pouvez utiliser la mthode config() ou la passer
au constructeur de CakeEmail :
$Email = new CakeEmail();
$Email->config('default');
//ou dans un constructeur::
$Email = new CakeEmail('default');
// config 'default' implicite utilise depuis 2.7
$Email = new CakeEmail();
Plutt que de passer une chane qui correspond au nom de la configuration dans EmailConfig, vous
pouvez aussi juste charger un tableau de configs :
$Email = new CakeEmail();
$Email->config(array('from' => 'me@example.org', 'transport' => 'MyCustom'));
//ou dans un constructeur::
$Email = new CakeEmail(array('from' => 'me@example.org', 'transport' => 'MyCustom'));
Note : Utilisez $Email->config() ou le constructeur pour dfinir le niveau de log pour enregistrer lentte demail et le message dans les logs. Utilisez $Email->config(array(log => true)); va
utiliser LOG_DEBUG. Regardez aussi CakeLog::write()
Vous pouvez configurer les serveurs SSL SMTP, comme Gmail. Pour faire ceci, mettez ssl:// en
prfixe dans le host et configurez la valeur du port selon. Exemple :
class EmailConfig {
public $gmail = array(
'host' => 'ssl://smtp.gmail.com',
'port' => 465,
'username' => 'my@gmail.com',
'password' => 'secret',
'transport' => 'Smtp'
);
}
Vous pouvez galement utiliser tls:// pour spcifier TLS pour le chiffrement au niveau de la connexion.
692
Avertissement : Vous devrez avoir laccs aux applications moins scurises activ dans votre compte
Google pour que cela fonctionne : Autoriser les applications moins scurises accder votre compte a .
a. https ://support.google.com/accounts/answer/6010255
Note : Pour utiliser les fonctionnalits ssl :// ou tls ://, vous aurez besoin davoir SSL configur dans votre
installation PHP.
Depuis 2.3.0, vous pouvez aussi activer STARTTLS SMTP en utilisant loption tls :
class EmailConfig {
public $gmail = array(
'host' => 'smtp.gmail.com',
'port' => 465,
'username' => 'my@gmail.com',
'password' => 'secret',
'transport' => 'Smtp',
'tls' => true
);
}
Utilitaires
693
viewVars : Si vous utilisez un contenu rendu, dfinissez le tableau avec les variables devant tre
rendus dans la vue. Regardez CakeEmail::viewVars().
attachments : Liste des fichiers attacher. Regardez CakeEmail::attachments().
emailFormat
:
Format
de
lemail
(html,
text
ou
both).
Regardez
CakeEmail::emailFormat().
transport : Nom du Transport. Regardez CakeEmail::transport().
helpers : Tableau de helpers utilis dans le template demail.
Toutes ces configurations sont optionnelles, except from. Si vous mettez plus de configurations dans
ce tableau, les configurations seront utilises dans la mthode CakeEmail::config() et passes la
classe de transport config(). Par exemple, si vous utilisez le transport SMTP, vous devez passer le host,
port et autres configurations.
Note : Les valeurs des cls ci-dessus utilisant Email ou un tableau, comme from, to, cc
etc. seront passes en premier paramtre des mthodes correspondantes. Lquivalent pour
CakeEmail::from(my@example.com, My Site) sera dfini comme from =>
array(my@example.com => My Site) dans votre config.
Dfinir les headers Dans CakeEmail, vous tes libre de dfinir les headers que vous souhaitez. Si vous
migrez pour utiliser CakeEmail, noubliez pas de mettre le prfixe X- dans vos headers.
Regardez CakeEmail::setHeaders() et CakeEmail::addHeaders()
Envoyer les emails templats Les Emails sont souvent bien plus que de simples messages textes. Afin de
faciliter cela, CakePHP fournit une faon denvoyer les emails en utilisant la view layer de CakePHP.
Les templates pour les emails se placent dans un dossier spcial appel Emails dans le rpertoire View
de votre application. Les vues des emails peuvent aussi utiliser les layouts et lments tout comme les vues
normales :
$Email = new CakeEmail();
$Email->template('welcome', 'fancy')
->emailFormat('html')
->to('bob@example.com')
->from('app@domain.com')
->send();
app/View/Layouts/Emails/text/fancy.ctp
app/View/Emails/html/welcome.ctp
app/View/Layouts/Emails/html/fancy.ctp
Quand on envoie les emails templats, vous avez la possibilit denvoyer soit text, html soit both.
Vous pouvez dfinir des variables de vue avec CakeEmail::viewVars() :
$Email = new CakeEmail('templated');
$Email->viewVars(array('value' => 12345));
Vous pouvez aussi utiliser les helpers dans les emails, un peu comme vous pouvez dans des fichiers normaux
de vue. Par dfaut, seul HtmlHelper est charg. Vous pouvez chargez des helpers supplmentaires en
utilisant la mthode helpers() :
$Email->helpers(array('Html', 'Custom', 'Text'));
Quand vous dfinissez les helpers, assurez vous dinclure Html ou il sera retir des helpers chargs dans
votre template demail.
Si vous voulez envoyer un email en utilisant templates dans un plugin, vous pouvez utiliser la syntaxe de
plugin familire pour le faire :
$Email = new CakeEmail();
$Email->template('Blog.new_comment', 'Blog.auto_message')
Ce qui est au-dessus utiliserait les templates partir dun plugin de Blog par exemple.
Envoyer les pices jointes Vous pouvez aussi attacher des fichiers aux messages demail. Il y a quelques
formats diffrents qui dpendent de quel type de fichier vous avez, et comment vous voulez que les noms de
fichier apparaissent dans le mail de rception du client :
1. Chane de caractres : $Email->attachments(/full/file/path/file.png) va attacher ce fichier avec le nom file.png.
2. Tableau : $Email->attachments(array(/full/file/path/file.png) aura le
mme comportement quen utilisant une chane de caractres.
3. Tableau
avec
cl
:
$Email->attachments(array(photo.png =>
/full/some_hash.png)) va attacher some_hash.png avec le nom photo.png. Le rcipiendaire va voir photo.png, pas some_hash.png.
4. Tableaux imbriqus :
$Email->attachments(array(
'photo.png' => array(
'file' => '/full/some_hash.png',
'mimetype' => 'image/png',
'contentId' => 'my-unique-id'
)
));
Utilitaires
695
Ce qui est au-dessus va attacher le fichier avec diffrent mimetype et avec un content ID personnalis (Quand vous dfinissez le content ID, la pice jointe est transforme en inline). Le mimetype et
contentId sont optionels dans ce formulaire.
4.1. Quand vous utilisez contentId, vous pouvez utiliser le fichier dans corps
comme <img src="cid:my-content-id">.
HTML
Vous devez intgrer la mthode send(CakeEmail $Email) avec votre logique personnalise. En option, vous pouvez intgrer la mthode config($config). config() est appel avant send() et vous
permet daccepter les configurations de lutilisateur. Par dfaut, cette mthode met la configuration dans
lattribut protg $_config.
Si vous avez besoin dappeler des mthodes supplmentaires sur le transport avant lenvoi, vous pouvez
utiliser CakeEmail::transportClass() pour obtenir une instance du transport. Exemple :
$yourInstance = $Email->transport('your')->transportClass();
$yourInstance->myCustomMethod();
$Email->send();
696
Parfois vous avez besoin dune faon rapide denvoyer un email, et vous navez pas particulirement envie
en mme temps de dfinir un tas de configuration. CakeEmail::deliver() est prsent pour ce cas.
Vous pouvez crer votre configuration dans EmailConfig, ou utiliser un tableau avec toutes les options
dont vous aurez besoin et utiliser la mthode statique CakeEmail::deliver(). Exemple :
Utilitaires
697
$Email->domain('www.example.org');
// Resulte en ids de message comme ``<UUID@www.example.org>`` (valid)
// au lieu de `<UUID@>`` (invalid)
Un id de message valide peut permettre ce message de ne pas finir dans un dossier de spam. Si vous gnrez
des liens dans les corps de vos emails, vous pouvez aussi avoir besoin de dfinir la valeur de configuration
App.fullBaseUrl.
Folder & File
Les utilitaires Folder et File sont des classes pratiques pour aider la lecture, lcriture/lajout de fichiers ;
Lister les fichiers dun dossier et autres tches habituelles lies aux rpertoires.
Utilisation basique
et chercher tous les fichiers .ctp lintrieur de ce dossier en utilisant les regex :
<?php
$files = $dir->find('.*\.ctp');
Maintenant nous pouvons faire une boucle sur les fichiers et les lire, crire/ajouter aux contenus, ou simplement supprimer le fichier :
<?php
foreach ($files as $file) {
$file = new File($dir->pwd() . DS . $file);
$contents = $file->read();
// $file->write('J'cris dans ce fichier');
// $file->append('J'ajoute la fin de ce fichier.');
// $file->delete(); // Je supprime ce fichier
$file->close(); // Assurez vous de fermer le fichier quand c'est fini
}
API de Folder
class Folder(string $path = false, boolean $create = false, mixed $mode = false)
698
<?php
// Cre un nouveau dossier avec les permissions 0755
$dir = new Folder('/path/to/folder', true, 0755);
property Folder::$path
Le chemin pour le dossier courant. Folder::pwd() retournera la mme information.
property Folder::$sort
Dit si la liste des rsultats doit tre oui ou non range par name.
property Folder::$mode
Mode utiliser pour la cration de dossiers. par dfaut 0755. Ne fait rien sur les machines Windows.
static Folder::addPathElement(string $path, string $element)
Type retourn string
Retourne $path avec $element ajout, avec le bon slash entre-deux :
$path = Folder::addPathElement('/a/path/for', 'testing');
// $path gal /a/path/for/testing
Introduit dans la version 2.5 : Le paramtre $element accepte un tableau depuis 2.5
Folder::cd(string $path)
Type retourn string
Change le rpertoire en $path. Retourne false si chec :
<?php
$folder = new Folder('/foo');
echo $folder->path; // Affiche /foo
$folder->cd('/bar');
echo $folder->path; // Affiche /bar
$false = $folder->cd('/non-existent-folder');
Folder::chmod(string $path, integer $mode = false, boolean $recursive = true, array $exceptions = array())
Type retourn boolean
Change le mode sur la structure de rpertoire de faon rcursive. Ceci inclut aussi le changement du
mode des fichiers :
<?php
$dir = new Folder();
$dir->chmod('/path/to/folder', 0755, true, array('skip_me.php'));
Utilitaires
699
Copie de faon rcursive un rpertoire. Le seul paramtre $options peut tre soit un chemin copier
soit un tableau doptions :
<?php
$folder1 = new Folder('/path/to/folder1');
$folder1->copy('/path/to/folder2');
// Va mettre folder1 et tous son contenu dans folder2
$folder = new Folder('/path/to/folder');
$folder->copy(array(
'to' => '/path/to/new/folder',
'from' => '/path/to/copy/from', // va entraner l'execution de cd()
'mode' => 0755,
'skip' => array('skip-me.php', '.git'),
'scheme' => Folder::SKIP, // Passe les rpertoires/fichiers qui existent dj.
'recursive' => true
));
y a 3 schmas supports :
Folder::SKIP chapper la copie/dplacement des fichiers & rpertoires qui existent dans le
rpertoire de destination.
Folder::MERGE fusionne les rpertoires source/destination. Les fichiers dans le rpertoire source
vont remplacer les fichiers dans le rpertoire de cible. Les contenus du rpertoire seront fusionns.
Folder::OVERWRITE crase les fichiers & rpertoires existant dans la rpertoire cible avec ceux
dans le rpertoire source. Si les deux source et destination contiennent le mme sous-rpertoire, les
contenus du rpertoire de cible vont tre retirs et remplacs avec celui de la source.
Modifi dans la version 2.3 : La fusion, lvitement et la surcharge des schmas ont t ajouts
copy().
static Folder::correctSlashFor($path)
Type retourn string
Retourne un ensemble correct de slashes pour un $path donn. (\ pour les chemins Windows et /
pour les autres chemins).
Folder::create(string $pathname, integer $mode = false)
Type retourn boolean
Cre une structure de rpertoire de faon rcursive. Peut tre utilis pour crer des structures de chemin
profond comme /foo/bar/baz/shoe/horn :
<?php
$folder = new Folder();
if ($folder->create('foo' . DS . 'bar' . DS . 'baz' . DS . 'shoe' . DS . 'horn')) {
// Successfully created the nested folders
}
700
<?php
$folder = new Folder('foo');
if ($folder->delete()) {
// Successfully deleted foo and its nested folders
}
Folder::dirsize()
Type retourn integer
Retourne la taille en bytes de ce Dossier et ses contenus.
Folder::errors()
Type retourn array
Rcupre lerreur de la dernire mthode.
Folder::find(string $regexpPattern = .*, boolean $sort = false)
Type retourn array
Retourne un tableau de tous les fichiers correspondants dans le rpertoire courant :
<?php
// Trouve tous les .png dans votre dossier app/webroot/img/ et range les rsultats
$dir = new Folder(WWW_ROOT . 'img');
$files = $dir->find('.*\.png', true);
/*
Array
(
[0] => cake.icon.png
[1] => test-error-icon.png
[2] => test-fail-icon.png
[3] => test-pass-icon.png
[4] => test-skip-icon.png
)
*/
Note : Les mthodes find et findRecursive de folder ne trouvent seulement que des fichiers. Si vous voulez
obtenir des dossiers et fichiers, regardez Folder::read() ou Folder::tree().
Folder::findRecursive(string $pattern = .*, boolean $sort = false)
Type retourn array
Retourne un tableau de tous les fichiers correspondants dans et en-dessous du rpertoire courant :
<?php
// Trouve de faon rcursive les fichiers commenant par test ou index
$dir = new Folder(WWW_ROOT);
$files = $dir->findRecursive('(test|index).*');
/*
Array
(
[0] => /var/www/cake/app/webroot/index.php
[1] => /var/www/cake/app/webroot/test.php
Utilitaires
701
[2]
[3]
[4]
[5]
=>
=>
=>
=>
/var/www/cake/app/webroot/img/test-skip-icon.png
/var/www/cake/app/webroot/img/test-fail-icon.png
/var/www/cake/app/webroot/img/test-error-icon.png
/var/www/cake/app/webroot/img/test-pass-icon.png
)
*/
Folder::inCakePath(string $path = )
Type retourn boolean
Retourne true si le Fichier est dans un CakePath donn.
Folder::inPath(string $path = , boolean $reverse = false)
Type retourn boolean
Retourne true si le Fichier est dans le chemin donn :
<?php
$Folder = new Folder(WWW_ROOT);
$result = $Folder->inPath(APP);
// $result = true, /var/www/example/app/ is in /var/www/example/app/webroot/
702
Folder::realpath(string $path)
Type retourn string
Rcupre le vrai chemin (taking .. and such into account).
static Folder::slashTerm(string $path)
Type retourn string
Utilitaires
703
Retourne $path avec le slash ajout la fin (corrig pour Windows ou dautres OS).
Folder::tree(null|string $path = null, array|boolean $exceptions = true, null|string $type =
null)
Type retourn mixed
Retourne un tableau de rpertoires imbriqus et de fichiers dans chaque rpertoire.
LAPI de File
property File::$Folder
Lobjet Folder du fichier.
property File::$name
Le nom du fichier avec lextension. Diffre de File::name() qui retourne le nom sans lextension.
property File::$info
Un tableau du fichier info. Utilisez File::info() la place.
property File::$handle
Maintient le fichier de gestion des ressources si le fichier est ouvert.
property File::$lock
Active le blocage du fichier en lecture et criture.
property File::$path
Le chemin absolu du fichier courant.
File::append(string $data, boolean $force = false)
Type retourn boolean
Ajoute la chane de caractres donne au fichier courant.
File::close()
Type retourn boolean
Ferme le fichier courant si il est ouvert.
File::copy(string $dest, boolean $overwrite = true)
Type retourn boolean
Copie le Fichier vers $dest.
File::create()
Type retourn boolean
Cre le Fichier.
File::delete()
704
705
La syntaxe de chemin dcrite ci-dessous est utilise par toutes les mthodes dans Hash. Les parties de la
syntaxe du chemin ne sont pas toutes disponibles dans toutes les mthodes. Une expression en chemin est
faite depuis nimporte quel nombre de tokens. Les Tokens sont composs de deux groupes. Les Expressions
sont utilises pour parcourir le tableau de donnes, alors que les matchers sont utiliss pour qualifier les
lments. Vous appliquez les matchers aux lments de lexpression.
Types dexpression
Expression
{n}
{s}
Foo
Dfinition
Tous les lments dexpression supportent toutes les mthodes. En plus des lments dexpression, vous
pouvez utiliser les attributs qui matchent avec certaines mthodes. Il y a extract(), combine(),
format(), check(), map(), reduce(), apply(), sort(), insert(), remove() et nest().
Utilitaires
707
Matcher
[id]
[id=2]
[id!=2]
[id>2]
[id>=2]
[id<2]
[id<=2]
[text=/.../]
Definition
Match les lments avec une cl de tableau donne.
Match les lments avec un id gal 2.
Match les lments avec un id non gal 2.
Match les lments avec un id suprieur 2.
Match les lments avec un id suprieur ou gal 2.
Match les lments avec un id infrieur 2.
Match les lments avec un id infrieur ou gal 2.
Match les lments qui ont des valeurs matchant avec lexpres
lintrieur de ....
Modifi dans la version 2.5 : Le support des matcher a t ajout dans insert() et remove().
static Hash::get(array $data, $path, $default = null)
Type retourn mixed
get() est une version simplifie de extract(), elle ne supporte que les expressions de chemin
direct. Les chemins avec {n}, {s} ou les matchers ne sont pas supports. Utilisez get() quand vous
voulez exactement une valeur sortie dun tableau. Le troisime paramtre sera retourn si le chemin
demand na pas t trouv dans le tableau.
Modifi dans la version 2.5 : Le troisime argument $default = null optionel a t ajout.
static Hash::extract(array $data, $path)
Type retourn array
Hash::extract() supporte toutes les expressions, les components matcher de la Syntaxe de
chemin Hash. Vous pouvez utiliser lextract pour rcuprer les donnes partir des tableaux, le long
des chemins arbitraires rapidement sans avoir parcourir les structures de donnes. A la place, vous
utilisez les expressions de chemin pour qualifier les lments que vous souhaitez retourner
// Utilisation habituelle:
$users = $this->User->find("all");
$results = Hash::extract($users, '{n}.User.id');
// $results gal :
// array(1,2,3,4,5,...);
708
(
[name] => files
)
)
Vous pouvez utiliser les chemins en utilisant {n} et {s} pour insrer des donnes dans des points
multiples :
$users = $this->User->find('all');
$users = Set::insert($users, '{n}.User.new', 'value');
Modifi dans la version 2.5 : Depuis 2.5.0, les expressions matchant lattribut fonctionnent avec insert().
static Hash::remove(array $data, $path)
Type retourn array
Retire tous les lments dun tableau qui matche avec $path.
$a = array(
'pages' => array('name' => 'page'),
'files' => array('name' => 'files')
);
$result = Hash::remove($a, 'files');
/* $result ressemble maintenant :
Array
(
[pages] => Array
(
[name] => page
)
)
*/
Lutilisation de {n} et {s} vous autorisera retirer les valeurs multiples en une fois.
Modifi dans la version 2.5 : Depuis 2.5.0, les expressions matchant lattribut fonctionnent avec remove()
static Hash::combine(array $data, $keyPath, $valuePath = null, $groupPath = null)
Type retourn array
Cre un tableau associatif en utilisant $keyPath en cl pour le chemin construire, et optionnellement
$valuePath comme chemin pour rcuprer les valeurs. Si $valuePath nest pas spcifie, ou ne matche
rien, les valeurs seront initialises null. Vous pouvez grouper en option les valeurs par ce qui est
obtenu en suivant le chemin spcifi dans $groupPath.
$a = array(
array(
'User' => array(
'id' => 2,
'group_id' => 1,
'Data' => array(
'user' => 'mariano.iglesias',
Utilitaires
709
710
Array
(
[1] => Array
(
[2] => Array
(
[user]
[name]
)
)
[2] => Array
(
[14] => Array
(
[user]
[name]
)
)
)
=> mariano.iglesias
=> Mariano Iglesias
=> phpnut
=> Larry E. Masters
*/
Vous pouvez fournir des tableaux pour les deux $keyPath et $valuePath. Si vous le fate, la premire
valeur sera utilise comme un format de chane de caractres, pour les valeurs extraites par les autres
chemins :
$result = Hash::combine(
$a,
'{n}.User.id',
array('%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'),
'{n}.User.group_id'
);
/* $result ressemble maintenant :
Array
(
[1] => Array
(
[2] => mariano.iglesias: Mariano Iglesias
)
[2] => Array
Utilitaires
711
(
[14] => phpnut: Larry E. Masters
)
)
*/
$result = Hash::combine(
$a,
array('%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'),
'{n}.User.id'
);
/* $result ressemble maintenant :
Array
(
[mariano.iglesias: Mariano Iglesias] => 2
[phpnut: Larry E. Masters] => 14
)
*/
712
=> 'main'),
=> 'about')
=> 'main'),
=> 'about'),
=> 'contact'),
Utilitaires
713
Utilitaires
715
et le
cl du
comme
comme
Note : Cette fonction va fonctionner avec un montant illimit darguments et convertit les paramtres
de non-tableau en tableaux.
$array = array(
array(
'id' => '48c2570e-dfa8-4c32-a35e-0d71cbdd56cb',
'name' => 'mysql raleigh-workshop-08 < 2008-09-05.sql ',
'description' => 'Importing an sql dump'
),
array(
'id' => '48c257a8-cf7c-4af2-ac2f-114ecbdd56cb',
'name' => 'pbpaste | grep -i Unpaid | pbcopy',
'description' => 'Remove all lines that say "Unpaid".',
)
);
$arrayB = 4;
$arrayC = array(0 => "test array", "cats" => "dogs", "people" => 1267);
$arrayD = array("cats" => "felines", "dog" => "angry");
$res = Hash::merge($array, $arrayB, $arrayC, $arrayD);
/* $res ressemble maintenant :
Array
(
[0] => Array
(
[id] => 48c2570e-dfa8-4c32-a35e-0d71cbdd56cb
[name] => mysql raleigh-workshop-08 < 2008-09-05.sql
[description] => Importing an sql dump
)
[1] => Array
(
[id] => 48c257a8-cf7c-4af2-ac2f-114ecbdd56cb
[name] => pbpaste | grep -i Unpaid | pbcopy
[description] => Remove all lines that say "Unpaid".
)
[2] => 4
[3] => test array
[cats] => felines
[people] => 1267
[dog] => angry
)
*/
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1'
$result = Hash::dimensions($data);
// $result == 2
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1'
$result = Hash::maxDimensions($data, true);
// $result == 3
Utilitaires
717
$dir peut tre soit asc, soit desc. Le $type peut tre une des valeurs suivantes :
regular pour le trier rgulier.
numeric pour le tri des valeurs avec leurs valeurs numriques quivalentes.
string pour le tri des valeurs avec leur valeur de chane.
natural pour trier les valeurs dune faon humaine. Va trier foo10 en-dessous de foo2 par
exemple. Le tri naturel a besoin de PHP 5.4 ou suprieur.
718
Introduit dans la version 2.8 : Loption $type accepte maintenant un tableau et loption
ignoreCase active le tri sans sensibilit la casse.
static Hash::diff(array $data, array $compare)
Type retourn array
Calcule la diffrence entre deux tableaux :
$a = array(
0 => array('name'
1 => array('name'
);
$b = array(
0 => array('name'
1 => array('name'
2 => array('name'
);
=> 'main'),
=> 'about')
=> 'main'),
=> 'about'),
=> 'contact')
$array1 = array('ModelOne' => array('id' => 1001, 'field_one' => 'a1.m1.f1', 'field_tw
$array2 = array('ModelOne' => array('id' => 1003, 'field_one' => 'a3.m1.f1', 'field_tw
$res = Hash::mergeDiff($array1, $array2);
/* $res ressemble maintenant :
Array
(
[ModelOne] => Array
(
[id] => 1001
[field_one] => a1.m1.f1
[field_two] => a1.m1.f2
[field_three] => a3.m1.f3
)
)
*/
Exemple 2
Utilitaires
719
720
'Validator',
'Transactional'
);
$result = Hash::normalize($b);
/* $result ressemble maintenant :
Array
(
[Cacheable] => Array
(
[enabled] => false
)
[Limit] => null
[Bindable] => null
[Validator] => null
[Transactional] => null
)
*/
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
Utilitaires
721
),
'children' => array(
(int) 0 => array(
'ModelName' => array(
'id' => (int) 7,
'parent_id' => (int)
),
'children' => array()
),
(int) 1 => array(
'ModelName' => array(
'id' => (int) 8,
'parent_id' => (int)
),
'children' => array()
),
(int) 2 => array(
'ModelName' => array(
'id' => (int) 9,
'parent_id' => (int)
),
'children' => array()
),
(int) 3 => array(
'ModelName' => array(
'id' => (int) 10,
'parent_id' => (int)
),
'children' => array()
)
)
)
)
*/
HttpSocket
class HttpSocket(mixed $config = array())
CakePHP inclut une classe HttpSocket qui peut tre utilise pour faire des requtes. Cest un bon moyen
pour communiquer avec des services web externes ou des apis distantes.
Faire une requte
Vous pouvez utiliser HttpSocket pour crer la plupart des requtes HTTP avec les diffrentes mthodes
HTTP.
HttpSocket::get($uri, $query, $request)
Le paramtre $query peut soit tre une chane de caractres, soit un tableau de cls et de valeurs. La
mthode get fait une simple requte HTTP GET retournant les rsultats :
722
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
// requte chane
$results = $HttpSocket->get('http://www.google.com/search', 'q=cakephp');
// requte tableau
$results = $HttpSocket->get('http://www.google.com/search', array('q' => 'cakephp'));
Utilitaires
723
Grer la rponse
Les rponses des requtes fates avec HttpSocket sont des instances de HttpResponse. Lobjet vous
donne quelques mthodes accessor pour accder au contenu de la rponse HTTP. Cette classe intgre le
ArrayAccess 26 et __toString() 27 , donc vous pouvez continuer en utilisant $http->response en tableau
et le retour des mthodes de requte en chane :
App::uses('HttpSocket', 'Network/Http');
$http = new HttpSocket();
$response = $http->get('http://www.cakephp.org');
// Check the body for the presence of a title tag.
$titlePos = strpos($response->body, '<title>');
// Rcupre le code de statut pour la rponse.
$code = $response->code;
724
Votre $response->headers (ou $response[header]) va contenir les bonnes cls envoys. Afin
daccder de manire scuris aux champs du header, il est mieux dutiliser getHeader(). Si vos headers
ressemblent ceci :
Date: Mon, 16 Apr 2007 04:14:16 GMT
server: CakeHttp Server
content-tyPe: text/html
Utilitaires
725
<?php
App::uses('HttpSocket', 'Network/Http');
Autoriserait les certificats signs soi-mme pour toutes les requtes fates avec le socket cr.
Introduit dans la version 2.3 : La validation de certificats SSL a t ajoute dans 2.3.
Crer une classe de rponse personnalise Vous pouvez crer votre propre classe de rponse pour utiliser
HttpSocket. Vous pourriez crer le fichier app/Lib/Network/Http/YourResponse.php avec le
contenu :
App::uses('HttpResponse', 'Network/Http');
class YourResponse extends HttpResponse {
public function parseResponse($message) {
parent::parseResponse($message);
// Make what you want
}
}
726
Modifi dans la version 2.3 : Depuis 2.3.0, vous devriez tendre HttpSocketResponse la place. Cela
vite un problme commun avec lextension HTTP PECL.
Tlcharger les rsultats HttpSocket a une nouvelle mthode appele setContentResource(). En configurant une ressource avec cette mthode, le contenu sera crit dans la ressource, en utilisant fwrite(). Pour
tlcharger un fichier, vous pouvez faire :
App::uses('HttpSocket', 'Network/Http');
$http = new HttpSocket();
$f = fopen(TMP . 'bakery.xml', 'w');
$http->setContentResource($f);
$http->get('http://bakery.cakephp.org/comments.rss');
fclose($f);
Note : Les headers ne sont pas inclus dans le fichier, vous rcuprerez seulement le contenu du corps crit dans votre ressource. Pour dsactiver la sauvegarde dans la ressource, utilisez
$http->setContentResource(false).
Utiliser lauthentification
HttpSocket supporte des mthodes dauthentification HTTP Basic et Digest. Vous pouvez maintenant crer
des objets dauthentification personnaliss pour supporter des protocoles comme OAuth. Pour utiliser un
systme dauthentification, vous devez configurer linstance HttpSocket :
App::uses('HttpSocket', 'Network/Http');
$http = new HttpSocket();
$http->configAuth('Basic', 'user', 'password');
Ce qui est au-dessus configurerait linstance HttpSocket pour utiliser lauthentification Basic en utilisant
user et password en credentials.
Crer un objet dauthentification personnalis Vous pouvez maintenant crer votre propre mthode dauthentification utiliser avec HttpSocket. Vous pouvez crer le fichier
app/Lib/Network/Http/YourMethodAuthentication.php avec le contenu :
class YourMethodAuthentication {
/**
* Authentication
Utilitaires
727
*
* @param HttpSocket $http
* @param array $authInfo
* @return void
*/
public static function authentication(HttpSocket $http, &$authInfo) {
// Faire quelque chose, par exemple dfinir la valeur $http->request['header']['Aut
}
}
Pour configurer HttpSocket afin dutiliser votre configuration auth, vous pouvez utiliser la nouvelle mthode
configAuth() :
$http->configAuth('YourMethod', array('config1' => 'value1', 'config2' => 'value2'));
$http->get('http://secure.your-site.com');
/**
* Authentication
*
* @param HttpSocket $http
* @param array $authInfo
* @return void
*/
public static function authentication(HttpSocket $http, &$authInfo) {
// Faire quelque chose, par exemple dfinir ma valeur $http->request['header']['Aut
}
/**
* Proxy Authentication
*
* @param HttpSocket $http
* @param array $proxyInfo
* @return void
*/
public static function proxyAuthentication(HttpSocket $http, &$proxyInfo) {
// Faire quelque chose, par exemple dfinir la valeur $http->request['header']['Pro
}
}
728
Inflector
class Inflector
La classe Inflector prend une chane de caractres et peut la manipuler pour grer les variations de mot
comme les mises au pluriel ou les mises en Camel et est normalement accessible statiquement. Exemple :
Inflector::pluralize(example) retourne examples.
Vous pouvez essayer les inflections enligne sur inflector.cakephp.org 29 .
static Inflector::pluralize($singular)
Input : Apple, Orange, Person, Man
Output : Apples, Oranges, People, Men
Note : pluralize() ne convertit pas toujours correctement un nom qui est dj au pluriel.
static Inflector::singularize($plural)
Input : Apples, Oranges, People, Men
Output : Apple, Orange, Person, Man
Note : singularize() ne convertit pas toujours correctement un nom qui est dj au singulier.
static Inflector::camelize($underscored)
Input : Apple_pie, some_thing, people_person
Output : ApplePie, SomeThing, PeoplePerson
static Inflector::underscore($camelCase)
Il doit tre not que les underscores vont seulement convertir les mots formats en camelCase. Les
mots qui contiennent des espaces seront en minuscules, mais ne contiendront pas dunderscore.
Input : applePie, someThing
Output : apple_pie, some_thing
static Inflector::humanize($underscored)
Input : apple_pie, some_thing, people_person
Output : Apple Pie, Some Thing, People Person
static Inflector::tableize($camelCase)
Input : Apple, UserProfileSetting, Person
Output : apples, user_profile_settings, people
static Inflector::classify($underscored)
Input : apples, user_profile_settings, people
Output : Apple, UserProfileSetting, Person
static Inflector::variable($underscored)
Input : apples, user_result, people_people
Output : apples, userResult, peoplePeople
static Inflector::slug($word, $replacement = _)
Slug convertit les caractres spciaux en version latins et convertit les caractres ne correspondant pas
et les espaces aux underscores. La mthode slug sattend un encodage UTF-8.
29. http ://inflector.cakephp.org/
Utilitaires
729
Il ny a que quelques tapes franchir pour passer dune application mono-langue une application multilangue, la premire est dutiliser la fonction __() dans votre code. Ci-dessous un exemple dun code pour
une application mono-langue :
<h2>Posts</h2>
Pour internationaliser votre code, la seule chose faire est dentourer la chane avec __() comme ceci :
<h2><?php echo __('Posts') ?></h2>
Si vous ne fates rien de plus, ces deux bouts de codes donneront un rsultat identique - ils renverront le
mme contenu au navigateur. La fonction __() traduira la chane passe si une traduction est disponible,
sinon elle la renverra non modifie. Cela fonctionne exactement comme les autres implmentations Gettext
Gettext 30 (comme les autres fonctions de traductions, comme __d() , __n() etc).
Aprs avoir prpar votre code pour le multi-langue, ltape suivante est de crer votre fichier pot pot file 31 ,
qui est le template pour toutes les chanes traduisibles de votre application. Pour gnrer votre (vos) fichier(s)
pot, tout ce que vous avez faire est de lancer la tche i18n i18n console task de la console Cake, qui va
chercher partout dans votre code o vous avez utilis une fonction de traduction, et gnrer le(s) fichier(s)
pot pour vous. Vous pouvez (et devez) relancer cette tche console chaque fois que vous changez les
chanes traduisibles dans votre code.
30. http ://en.wikipedia.org/wiki/Gettext
31. http ://en.wikipedia.org/wiki/Gettext
730
Le(s) fichier(s) pot eux mmes ne sont pas utiliss par CakePHP, ils sont les templates utiliss pour crer ou
mettre jour vos fichiers po, po files 32 qui contiennent les traductions. CakePHP cherchera vos fichiers po
dans les dossiers suivants :
/app/Locale/<locale>/LC_MESSAGES/<domain>.po
Le domaine par dfaut est default, donc votre dossier locale devrait ressembler cela :
/app/Locale/eng/LC_MESSAGES/default.po (Anglais)
/app/Locale/fra/LC_MESSAGES/default.po (Franais)
/app/Locale/por/LC_MESSAGES/default.po (Portugais)
Pour crer ou diter vos fichiers po, il est recommand de ne pas utiliser votre diteur de texte prfr. Pour
crer un fichier po pour la premire fois, il est possible de copier le fichier pot lendroit correct et de
changer lextension. Cependant, moins que vous ne soyez familiaris avec leur format, il est trs facile
de crer un fichier po invalide, ou de le sauver dans un mauvais encodage de caractres (si vous ditez ces
fichiers manuellement, utilisez lUTF-8 pour viter les problmes). Il y a des outils gratuits tel que PoEdit
PoEdit 33 qui rendent les tches ddition et de mise jour de vos fichiers po vraiment simples, spcialement
pour la mise jour dun fichier po existant avec un fichier pot nouvellement mis jour.
Les codes des locales en trois caractres suivent la norme ISO 639-2 34 mais si vous crez des locales
rgionales (en_US, en_GB, etc.) CakePHP les utilisera dans les cas appropris.
Avertissement : Dans 2.3 et 2.4, certains codes de langues ont t corrigs pour correspondre au standard
ISO. Merci de regarder les guides de migrations correspondants pour plus de dtails.
Souvenez-vous que les fichiers po sont utiles pour des messages courts. Si vous pensez que vous aurez
traduire de longs paragraphes, ou des pages entires, vous devriez penser limplmentation dune solution
diffrente. Par ex :
// Code du fichier App Controller.
public function beforeFilter() {
$locale = Configure::read('Config.language');
if ($locale && file_exists(APP . 'View' . DS . $locale . DS . $this->viewPath)) {
// utilise /app/views/fra/pages/tos.ctp au lieu de /app/views/pages/tos.ctp
$this->viewPath = $locale . DS . $this->viewPath;
}
}
ou :
// code de la Vue
echo $this->element(Configure::read('Config.language') . '/tos')
Pour la traduction de chanes de catgorie LC_TIME, CakePHP utilise des fichiers POSIX compliant
LC_TIME. Les fonctions i18n de la classe dutilitaire CakeTime et le helper TimeHelper utilise ces
fichiers LC_TIME.
Placez juste le fichier LC_TIME dans son rpertoire local respectif :
32. http ://en.wikipedia.org/wiki/Gettext
33. http ://www.poedit.net
34. http ://www.loc.gov/standards/iso639-2/php/code_list.php
Utilitaires
731
/app/Locale/fra/LC_TIME (French)
/app/Locale/por/LC_TIME (Portuguese)
Vous pouvez trouver ces fichiers pour quelques langues populaires partir du dpt officiel Localized 35 .
Internationaliser les plugins CakePHP
Si vous souhaitez inclure des fichiers traduits dans votre application, vous aurez besoin de suivre quelques
conventions.
Au lieu de __() et __n() vous devrez utiliser __d() et __dn(). Le D signifie domain. Donc si vous avez un
plugin appel DebugKit vous devrez faire ceci :
__d('debug_kit', 'My example text');
Utiliser la syntaxe en underscore est important, si vous ne lutilisez pas, CakePHP ne trouvera pas votre
fichier de traduction.
Votre fichier de traduction pour cet exemple devra tre dans :
/app/Plugin/DebugKit/Locale/<locale>/LC_MESSAGES/<domain>.po
La raison pour cela est que CakePHP va utiliser le nom du plugin en minuscule et avec des underscores,
pour le comparer avec le domaine de traduction et va regarder dans le plugin si il y a une correspondance
pour le fichier de traduction donn.
Controller lOrdre de Traduction
La valeur de configuration I18n.preferApp peut maintenant tre utilise pour controller lordre des
traductions. Si dfini true, les traductions de lapplication seront prfres celles des plugins :
Configure::write('I18n.preferApp', true);
732
Pour changer ou dfinir le langage de votre application, tout ce que vous avez faire est dans la partie
suivante :
Configure::write('Config.language', 'fra');
Ceci signale CakePHP quelle locale utiliser (si vous utilisez une locale rgionale, comme fr_FR, la locale
ISO 639-2 36 ) sera utilise au cas o cela nexisterait pas), vous pouvez changer la langue nimporte quel
moment pendant une requte. Ex : dans votre bootstrap si vous avez dfini les paramtres de langue par
dfaut, dans la partie beforefilter de votre (app) controller si cest spcifique la requte ou lutilisateur,
ou en fait en tout lieu tout moment avant de passer le message dans une autre langue. Pour dfinir la langue
pour lutilisateur courant, vous pouvez stocker le paramtrage dans lobjet Session, comme cela :
$this->Session->write('Config.language', 'fra');
Au dbut de chacune des requtes dans la partie beforeFilter de votre controller vous devez configurer
Configure ainsi :
class AppController extends Controller{
public function beforeFilter() {
if ($this->Session->check('Config.language')) {
Configure::write('Config.language', $this->Session->read('Config.language'));
}
}
}
En faisant cela vous assurerez que I18n et TranslateBehavior accdent aux mme valeurs de langue.
Cest une bonne ide de rendre du contenu public disponible dans plusieurs langues partir dune URL
unique - il deviendra plus facile pour les utilisateurs (et les moteurs de recherches) de trouver ce quils sont
venus chercher dans la langue souhaite. Il y a plusieurs moyens de faire cela, en utilisant un sous domaine
de langue spcifique (en.exemple.com,fra.exemple.com, etc.), ou en utilisant un prfixe lURL comme
cest le cas avec cette application. Vous pourriez galement souhaitez glaner linformation depuis lagent de
navigation (browser agent) de lutilisateur, entre autres choses.
Comme mentionn dans la section prcdente, laffichage des contenus localiss est effectu en utilisant la
fonction pratique __(), ou une des autres fonctions de traduction qui sont globalement disponibles, mais
probablement la plus utilise dans vos vues. Le premier paramtre de la fonction est utilis comme le msgid
dfini dans les fichiers .po.
CakePHP suppose automatiquement que tous les messages derreur de validation de votre model dans votre
tableau $validate sont destins tre localises. En excutant la console i18n ces chanes seront elles
aussi extraites.
Il y a dautres aspects de localisation de votre application qui ne sont pas couverts par lutilisation des
fonctions de traduction, ce sont les formats date/monnaie. Noubliez pas que CakePHP est PHP :), donc
pour dfinir les formats de ses lments vous devez utiliser setlocale 37 .
36. http ://www.loc.gov/standards/iso639-2/php/code_list.php
37. http ://www.php.net/setlocale
Utilitaires
733
Si vous passez une locale qui nexiste pas sur votre ordinateur setlocale 38 cela naura aucun effet. Vous
pouvez trouver la liste des locales disponibles en excutant la commande locale -a dans un terminal.
Traduire les erreurs de validation de model
CakePHP va automatiquement extraire lerreur de validation quand vous utilisez i18n console task.
Par dfaut, le domaine default est utilis. Ceci peut tre surcharg en configurant la proprit
$validationDomain dans votre model :
class User extends AppModel {
public $validationDomain = 'validation_errors';
}
Les paramtres supplmentaires dfinis dans la rgle de validation sont passs la fonction de traduction.
Cela vous permet de crer des messages de validation dynamiques :
class User extends AppModel {
public $validationDomain = 'validation';
public $validate = array(
'username' => array(
'length' => array(
'rule' => array('between', 2, 10),
'message' => 'Username devrait tre entre %d et %d caractres'
)
)
)
}
Journalisation (logging)
Bien que les rglages de la Classe Configure du cur de CakePHP puissent vraiment vous aider voir ce qui
se passe sous le capot, vous aurez besoin certaines fois de consigner des donnes sur le disque pour dcouvrir
ce qui se produit. Dans un monde devenu plus dpendant des technologies comme SOAP et AJAX, dboguer
peut savrer difficile.
Le logging (journalisation) peut aussi tre une faon de dcouvrir ce qui sest pass dans votre application
chaque instant. Quels termes de recherche ont t utiliss ? Quelles sortes derreurs ont t vues par mes
utilisateurs ? A quelle frquence est excute une requte particulire ?
La journalisation des donnes dans CakePHP est facile - la fonction log() est un lment de la classe Object, qui est lanctre commun de la plupart des classes CakePHP. Si le contexte est une classe CakePHP
38. http ://www.php.net/setlocale
734
(Model, Controller, Component... nimporte quoi dautre), vous pouvez loguer (journaliser) vos donnes.
Vous pouvez aussi utiliser CakeLog::write() directement. voir Ecrire dans les logs
Cration et Configuration des flux dun log (journal)
Les gestionnaires de flux de log peuvent faire partie de votre application, ou partie
dun plugin. Si par exemple vous avez un enregistreur de logs de base de donnes appel DatabaseLog. Comme faisant parti de votre application il devrait tre plac dans
app/Lib/Log/Engine/DatabaseLog.php. Comme faisant partie dun plugin il devrait tre
plac dans app/Plugin/LoggingPack/Lib/Log/Engine/DatabaseLog.php. Une fois configur CakeLog va tenter de charger la configuration des flux de logs en appelantCakeLog : :config().
La configuration de notre DatabaseLog pourrait ressembler ceci :
// pour app/Lib
CakeLog::config('otherFile', array(
'engine' => 'Database',
'model' => 'LogEntry',
// ...
));
// pour un plugin appel LoggingPack
CakeLog::config('otherFile', array(
'engine' => 'LoggingPack.Database',
'model' => 'LogEntry',
// ...
));
Lorsque vous configurez le flux dun log le paramtre de engine est utilis pour localiser et charger le
handler de log. Toutes les autres proprits de configuration sont passes au constructeur des flux de log
comme un tableau.
App::uses('BaseLog', 'Log/Engine');
class DatabaseLog extends BaseLog {
public function __construct($options = array()) {
parent::__construct($options);
// ...
}
public function write($type, $message) {
// crire dans la base de donnes.
}
}
Alors que CakePHP na pas dexigences pour les flux de Log sinon quil doit implmenter une mthode
write, en tendant la classe BaseLog a quelques bnfices.
Il gre automatiquement le scope et type argument casting.
Il intgre la mthode config() qui est requise pour faire le travail du scope de logging.
Chaque mthode write doit prendre deux paramtres, dans lordre $type, $message.$type est le
type de chane du message logu, les valeurs de noyau sont error, warning, info et debug. De plus
Utilitaires
735
vous pouvez dfinir vos propres types par leur utilisation en appelant CakeLog::write. Introduit dans
la version 2.4.
Depuis 2.4 le moteur de FileLog a quelques nouvelles configurations :
size Utilis pour implmenter la rotation de fichier de journal basic. Si la taille dun fichier de log
atteint la taille spcifie, le fichier existant est renomm en ajoutant le timestamp au nom du fichier et un
nouveau fichier de log est cre. Peut tre une valeur de bytes en entier ou des valeurs de chanes lisible
par lhumain comme 10MB, 100KB etc. Par dfaut 10MB. Dfinir size false va dsactiver loption
rotate ci-dessous.
rotate Les fichiers de log font une rotation un temps spcifi avant dtre retir. Si la valeur est 0, les
versions anciennes seront retires plutt que mises en rotation. Par dfaut 10.
mask Dfinit les permissions du fichier pour les fichiers crs. Si laiss vide, les permissions par dfaut
sont utilises.
Avertissement :
Avant 2.4 vous deviez inclure le suffixe Log dans votre configuration
(LoggingPack.DatabaseLog). Ce nest plus ncessaire maintenant. Si vous avez utilis un moteur de Log comme DatabaseLogger qui ne suit pas la convention dutiliser un suffixe Log pour
votre nom de classe, vous devez ajuster votre nom de classe en DatabaseLog. Vous devez aussi viter
les noms de classe comme SomeLogLog qui inclut le suffixe deux fois la fin.
Note : Toujours configurer les loggers dans app/Config/bootstrap.php Essayer de configurer les
loggers ou les loggers de plugin dans core.php provoquera des problmes, les chemins dapplications ntant
pas encore configurs.
Aussi nouveau dans 2.4 : En mode debug, les rpertoires manquants vont maintenant tre automatiquement
crs pour viter le lancement des erreurs non ncessaires lors de lutilisation de FileEngine.
Les erreurs et les exception peuvent elles aussi tre journalises. En configurant les valeurs correspondantes
dans votre fichier core.php. Les erreurs seront affiches quand debug > 0 et logues quand debug == 0.
Dfinir Exception.log true pour loguer les exceptions non captures. Voir Configuration pour plus
dinformation.
Interagir avec les flux de log
Alors que Cakelog peut tre configur pour crire un certain nombre dadaptateurs de logging (journalisation) configurs par lutilisateur, il est galement livr avec une configuration de logging par dfaut qui sera
utilise chaque fois quil ny a pas dautre adaptateur de logging configur. Une fois quun adaptateur de
736
logging a t configur vous aurez galement configurer Filelog si vous voulez que le logging de fichier
continu.
Comme son nom lindique FileLog crit les messages log dans des fichiers. Le type des messages de
log en court dcriture dtermine le nom du fichier ou le message sera stocker. Si le type nest pas
fourni, LOG_ERROR est utilis ce qui pour effet dcrire dans le log error. Le chemin par dfaut est
app/tmp/logs/$type.log :
// Execute cela dans une classe CakePHP
$this->log("Quelque chose ne fonctionne pas!");
// Aboutit ce que cela soit ajout app/tmp/logs/error.log
// 2007-11-02 10:22:02 Error: Quelque chose ne fonctionne pas!
Vous pouvez spcifier un nom personnalis en utilisant le premier paramtre. La classe Filelog intgre par
dfaut traitera ce nom de log comme le fichier dans lequel vous voulez crire les logs :
// appel de manire statique
CakeLog::write('activity', 'Un message spcial pour l'activit de logging');
// Aboutit ce que cela soit ajout app/tmp/logs/activity.log (au lieu de error.log)
// 2007-11-02 10:22:02 Activity: Un message spcial pour l'activit de logging
Le rpertoire configur doit tre accessible en criture par le serveur web de lutilisateur pour que la journalisation fonctionne correctement.
Vous pouvez configurer/alterner la localisation de FileLog en utilisant CakeLog::config(). FileLog
accepte un chemin qui permet aux chemins personnaliss dtre utiliss.
CakeLog::config('chemin_perso', array(
'engine' => 'FileLog',
'path' => '/chemin/vers/endroit/perso/'
));
Logging to Syslog
Utilitaires
737
Le tableau de configuration accept pour le moteur de journalisation Syslog comprend les cls suivantes :
format : Un template de chanes sprintf avec deux placeholders, le premier pour le type derreur, et le
second pour le message lui-mme. Cette cl est utile pour ajouter des informations supplmentaires
sur le serveur ou la procdure dans le message de log. Par exemple : %s - Web Server 1 %s va ressembler error - Web Server 1 - An error occurred in this request
aprs avoir remplac les placeholders.
prefix : Une chaine qui va tre prfixe tous les messages de log.
flag : Un drapeau entier utilis pour louverture de la connexion logger, par dfaut LOG_ODELAY sera
utilise. Regardez la documentation de openlog pour plus doptions.
facility : Le slot de journalisation utiliser dans syslog. Par dfaut LOG_USER est utilis. Regardez la
documentation de syslog pour plus doptions.
Ecrire dans les logs
Ecrire dans les fichiers peut tre ralis de deux faons. La premire est dutiliser la mthode statique
CakeLog::write() :
CakeLog::write('debug', 'Quelque chose qui ne fonctionne pas');
La seconde est dutiliser la fonction raccourcie log() disponible dans chacune des classes qui tend Object.
En appelant log() cela appellera en interne CakeLog : :write() :
// Excuter cela dans une classe CakePHP:
$this->log("Quelque chose qui ne fonctionne pas!", 'debug');
Tous les flux de log configurs sont crits squentiellement chaque fois que CakeLog::write() est
appele.
Modifi dans la version 2.5.
CakeLog ne sauto-configure plus lui-mme. En rsultat, les fichiers de log, ne seront plus auto-crs si
aucun flux nest cout. Assurez-vous que vous ayez au moins un flux default configur si vous souhaitez
couter tous les types et les niveaux. Habituellement, vous pouvez juste dfinir la classe FileLog du coeur
pour le sortir dans app/tmp/logs/ :
CakeLog::config('default', array(
'engine' => 'File'
));
Scopes de journalisation
738
CakePHP expose ce concept dans les scopes de journalisation. Quand les messages derreur sont crits, vous
pouvez inclure un nom scope. Si il y a un logger configur pour ce scope, les messages de log seront dirigs
vers ces loggers. Si un message de log est crit vers un scope inconnu, les loggers qui grent ce niveau de
message va journaliser le message. Par exemple :
// configurez tmp/logs/shops.log pour recevoir tous les types (niveaux de log), mais seulem
// ceux avec les scope `orders` et `payments`
CakeLog::config('shops', array(
'engine' => 'FileLog',
'types' => array('warning', 'error'),
'scopes' => array('orders', 'payments'),
'file' => 'shops.log',
));
// configurez tmp/logs/payments.log pour recevoir tous les types, mais seulement
// ceux qui ont un scope `payments`
CakeLog::config('payments', array(
'engine' => 'SyslogLog',
'types' => array('info', 'error', 'warning'),
'scopes' => array('payments')
));
CakeLog::warning('this gets written only to shops stream', 'orders');
CakeLog::warning('this gets written to both shops and payments streams', 'payments');
CakeLog::warning('this gets written to both shops and payments streams', 'unknown');
Pour que les scope fonctionnent correctement, vous devrez dfinir les types accepts sur tous les loggers
avec lesquels vous voulez utiliser les scopes.
lAPI de CakeLog
class CakeLog
Une simple classe pour crire dans les logs (journaux).
static CakeLog::config($name, $config)
Paramtres
$name (string) Nom du logger en cours de connexion, utilis pour rejeter un
logger plus tard.
$config (array) Tableau de configuration de linformation et des arguments du
constructeur pour le logger.
Connecte un nouveau logger a CakeLog. Chacun des logger connect reoit tous les messages de log
chaque fois quun message de log est crit.
static CakeLog::configured
Retourne Un tableau des loggers configurs.
Obtient les noms des loggers configurs.
static CakeLog::drop($name)
Paramtres
$name (string) Nom du logger duquel vous ne voulez plus recevoir de messages.
Utilitaires
739
Pour dfinir/remplcaer une configuration existante, passez un tableau avec le second argument dfini
false :
CakeLog::levels(array('user0', 'user1'), false);
static CakeLog::defaultLevels
Retourne Un tableau des valeurs des niveaux de log par dfaut.
Efface les niveaux de lof leurs valeurs originales :
array(
'emergency'
'alert'
'critical'
'error'
'warning'
'notice'
'info'
'debug'
);
=>
=>
=>
=>
=>
=>
=>
=>
LOG_EMERG,
LOG_ALERT,
LOG_CRIT,
LOG_ERR,
LOG_WARNING,
LOG_NOTICE,
LOG_INFO,
LOG_DEBUG,
static CakeLog::enabled($streamName)
740
Retourne boolean
Vrifie si $streamName a t activ.
static CakeLog::enable($streamName)
Retourne void
Active le flux $streamName.
static CakeLog::disable($streamName)
Retourne void
Disable the stream $streamName.
static CakeLog::stream($streamName)
Retourne Instance de BaseLog ou false si non retrouve.
Rcupre $streamName partir des flux actifs.
Mthodes pratiques Introduit dans la version 2.2.
Les mthodes pratiques suivantes ont t ajoutes au log $message avec le niveau de log appropri.
static CakeLog::emergency($message, $scope = array())
static CakeLog::alert($message, $scope = array())
static CakeLog::critical($message, $scope = array())
static CakeLog::error($message, $scope = array())
static CakeLog::warning($message, $scope = array())
static CakeLog::notice($message, $scope = array())
static CakeLog::info($message, $scope = array())
static CakeLog::debug($message, $scope = array())
CakeNumber
class CakeNumber
Si vous avez besoin des fonctionnalits de NumberHelper en-dehors dune View, utilisez la classe
CakeNumber :
class UsersController extends AppController {
public $components = array('Auth');
Utilitaires
741
}
}
}
Le premier paramtre $number, doit tre un nombre virgule qui reprsente le montant dargent
que vous dsirez. Le second paramtre est utilis pour choisir un schma de formatage de monnaie
courante :
$currency 1234.56, format par le type courant
EUR
C1.234,56
GBP
1,234.56
USD
$1,234.56
Le troisime paramtre est un tableau doptions pour dfinir la sortie. Les options suivantes sont
disponibles :
742
Option
before
after
zero
Description
Le symbole de la monnaie placer avant les nombres ex : $
Le symbole de la monnaie placer aprs les nombres dcimaux ex : c. Dfinit le
boolen false pour utiliser aucun symbole dcimal ex : 0.35 => $0.35.
Le texte utiliser pour des valeurs zro, peut tre une chane de caractres ou un
nombre. ex : 0, Free !
Nombre de dcimales utiliser. ex : 2
Sparateur des milliers ex : ,
places
thousands
decimals Symbole de Sparateur des dcimales. ex : .
negative
Symbole pour les nombres ngatifs. Si gal (), le nombre sera entour avec ( et )
escape
La sortie doit-elle tre chappe de htmlentity ? Par dfaut dfini true
wholeSym- La chane de caractres utiliser pour les tous nombres. ex : dollars
bol
wholePo- Soit before soit after pour placer le symbole entier
sition
fractionChane de caractres utiliser pour les nombres en fraction. ex : cents
Symbol
fractionSoit before soit after pour placer le symbole de fraction
Position
fractionFraction exponent de cette monnaie spcifique. Par dfaut 2.
Exponent
Si une valeur $currency non reconnue est fournie, elle est prfixe par un nombre format en USD.
Par exemple :
// Appel avec NumberHelper
echo $this->Number->currency('1234.56', 'FOO');
// Sortie
FOO 1,234.56
// Appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency('1234.56', 'FOO');
CakeNumber::defaultCurrency(string $currency)
Paramtres
$currency
(string)
Dfini
CakeNumber::currency().
une
monnaie
connu
pour
Setter/getter pour la monnaie par dfaut. Ceci retire la ncessit de toujours passer la monnaie
CakeNumber::currency() et change toutes les sorties de monnaie en dfinissant les autres par
dfaut.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.
CakeNumber::addFormat(string $formatName, array $options)
Paramtres
$formatName (string) Le nom du format utiliser dans le futur.
$options (array) Le tableau doptions pour ce format. Utilise les mmes cls
$options comme CakeNumber::currency().
Utilitaires
743
Vous pouvez maintenant utiliser BRL de manire courte quand vous formatez les montants de monnaie :
// appel par NumberHelper
echo $this->Number->currency($value, 'BRL');
// appel par CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::currency($value, 'BRL');
Les formats ajouts sont fusionns avec les formats par dfaut suivants :
array(
'wholeSymbol'
'wholePosition'
'fractionSymbol'
'fractionPosition'
'zero'
'places'
'thousands'
'decimals'
'negative'
'escape'
'fractionExponent'
)
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
'',
'before',
false,
'after',
0,
2,
',',
'.',
'()',
true,
2
Introduit dans la version 2.4 : Largument $options avec loption multiply a t ajout.
CakeNumber::fromReadableSize(string $size, $default)
Paramtres
$size (string) La valeur formate lisible par un humain.
Cette mthode enlve le format dun nombre partir dune taille de byte lisible par un humain en un
nombre entier de bytes.
Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3
CakeNumber::toReadableSize(string $dataSize)
Utilitaires
745
Paramtres
$data_size (string) Le nombre de bytes pour le rendre lisible.
Cette mthode formate les tailles de donnes dans des formes lisibles pour lhomme. Elle fournit une
manire raccourcie de convertir les en KB, MB, GB, et TB. La taille est affiche avec un niveau de
prcision deux chiffres, selon la taille de donnes fournie (ex : les tailles suprieurs sont exprimes
dans des termes plus larges) :
// appel avec NumberHelper
echo $this->Number->toReadableSize(0); // 0 Bytes
echo $this->Number->toReadableSize(1024); // 1 KB
echo $this->Number->toReadableSize(1321205.76); // 1.26 MB
echo $this->Number->toReadableSize(5368709120); // 5.00 GB
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::toReadableSize(0); // 0 Bytes
echo CakeNumber::toReadableSize(1024); // 1 KB
echo CakeNumber::toReadableSize(1321205.76); // 1.26 MB
echo CakeNumber::toReadableSize(5368709120); // 5.00 GB
Le paramtre $number est le nombre que vous souhaitez formater pour la sortie. Avec aucun $options
fourni, le nombre 1236.334 sortirait comme ceci : 1,236. Notez que la prcision par dfaut est daucun
chiffre aprs la virgule.
Le paramtre $options est l o rside la relle magie de cette mthode.
Si vous passez un entier alors celui-ci devient le montant de prcision pour la fonction.
Si vous passez un tableau associatif, vous pouvez utiliser les cls suivantes :
places (integer) : le montant de prcision dsir.
before (string) : mettre avant le nombre sortir.
escape (boolean) : si vous voulez la valeur avant dtre chappe.
decimals (string) : utilis pour dlimiter les places des dcimales dans le nombre.
thousands (string) : utilis pour marquer les milliers, millions, . . .
Exemple :
// appel avec NumberHelper
echo $this->Number->format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
746
));
// sortie ' 123,456.79'
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::format('123456.7890', array(
'places' => 2,
'before' => ' ',
'escape' => false,
'decimals' => '.',
'thousands' => ','
));
// sortie ' 123,456.79'
Le paramtre $number est le nombre que vous planifiez sur le formatage de sortie. Avec aucun $options fourni, le nombre 1236.334 sortirait 1,236. Notez que la valeur de prcision par dfaut est aucune
dcimale.
Le paramtre $options prend les mmes cls que CakeNumber::format() lui-mme :
places (integer) : le montant de precision souhait.
before (string) : mettre avant le nombre sorti.
after (string) : mettre aprs le nombre sorti.
decimals (string) : utilis pour dlimiter les places de la dcimal dans un nombre.
thousands (string) : utilis pour marquer les places des centaines, millions, . . .
Exemple :
// appel avec NumberHelper
echo $this->Number->formatDelta('123456.7890', array(
'places' => 2,
'decimals' => '.',
'thousands' => ','
));
// sortie '+123,456.79'
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::formatDelta('123456.7890', array(
'places' => 2,
'decimals' => '.',
'thousands' => ','
));
// sortie '+123,456.79'
Utilitaires
747
Router
Le Router peut tre utilis pour parser les URLs en tableaux contenant les indexes pour le controller, laction,
et tout paramtre, et leur oppos : pour convertir les tableaux URL (ex : array(controller => posts, action
=> index)) en chanes URLs.
Lisez en plus sur les faons de configurer le Router avec la classe Router.
Assainissement des Donnes (Data Sanitization)
La classe Sanitize est dprcie depuis 2.4, et sera retire dans CakePHP 3.0. Au lieu dutiliser la classe
Sanitize, vous pouvez accomplir les mmes tches en utilisant dautres parties de CakePHP, les fonctions
PHP natives, ou dautres librairies.
Filtre dEntres
Plutt que dutiliser les fonctionnalits de filtre dentre destructive de la classe Sanitize, vous devriez plutt
le faire avec Validation des Donnes pour les donnes utilisateur que votre application accepte. En rejetant
les entres invalides, vous pouvez souvent retirer le besoin de modifier destructivement les donnes utilisateur. Vous pouvez aussi avoir envie de regarder l extension de filtre PHP 39 dans les situations o vous
aurez besoin de modifier les entres utilisateur.
Accepter le HTML soumis par lutilisateur
Souvent, le filtre dentres est utilis quand on veut accepter le HTML soumis par lutilisateur. Dans ces
situations, il est mieux dutiliser une librairie ddie comme le Purificateur de HTML <http ://htmlpurifier.org/>_.
Echappement de SQL
748
LAPI de Security
Avertissement : cipher() utilise un cipher XOR faible et ne doit pas tre utilis pour des
donnes importantes ou sensibles.
static Security::rijndael($text, $key, $mode)
Paramtres
$text (string) Le texte chiffrer.
$key (string) La cl utiliser pour le chiffrement. Elle doit tre plus longue que
32 bytes.
$mode (string) Le mode utiliser, soit encrypt soit decrypt.
Chiffre/Dchiffre le texte en utilisant le cipher rijndael-256. Ceci ncessite que lextension mcrypt 41
soit installe :
rijndael() peut tre utilise pour stocker des donnes que vous voulez dchiffrer plus tard, comme
les contenus des cookies. Il ne devra jamais tre utilis pour stocker des mots de passe. Pour cela,
vous devrez utiliser la seule mthode de hashage fourni par hash()
Introduit dans la version 2.2 : Security::rijndael() a t ajoute pour la version 2.2.
static Security::encrypt($text, $key, $hmacSalt = null)
Paramtres
$text (string) La valeur chiffrer.
$key (string) La cl 256 bit/32 byte utiliser en cl cipher.
$hmacSalt (string) Le sel utiliser pour le processus HMAC. Laissez null pour
utiliser Security.salt.
Chiffre $text en utilisant AES-256. La $key devrait tre une valeur avec beaucoup de diffrence
dans les donnes un peu comme un bon mot de passe. Le rsultat retourn sera la valeur chiffre avec
un checksum HMAC.
Cette mthode ne devrait jamais tre utilise pour stocker des mots de passe. A la place, vous devriez
utiliser la manire de hasher les mots de passe fournie par hash(). Un exemple dutilisation serait :
41. http ://php.net/mcrypt
Utilitaires
749
Si la valeurne peut pas tre dchiffre cause de changements dans la cl ou le sel HMAC false
sera retourne.
Introduit dans la version 2.5.
static Security::generateAuthKey()
Type retourn string
Gnre un hash dautorisation.
static Security::getInstance()
Type retourn object
Limplmentation Singleton pour obtenir linstance de lobjet.
static Security::hash($string, $type = NULL, $salt = false)
Type retourn string
Cre un hash partir dune chane en utilisant la mthode donne. Le Fallback sur la prochaine
mthode disponible. Si $salt est dfini true, la valeur de salt de lapplication sera utilis :
// Utilise la valeur du salt de l'application
$sha1 = Security::hash('CakePHP Framework', 'sha1', true);
// Utilise une valeur du salt personnalise
$md5 = Security::hash('CakePHP Framework', 'md5', 'my-salt');
// Utilise l'algorithme de hashage par dfaut
$hash = Security::hash('CakePHP Framework');
750
hash() supporte aussi dautres algorithmes scuriss de hashage comme bcrypt. Quand vous utilisez
bcrypt, vous devez vous souvenir de son usage lgrement diffrent. Crer un hash initial fonctionne
de la mme faon que les autres algorithmes :
// Cre un hash en utilisant bcrypt
Security::setHash('blowfish');
$hash = Security::hash('CakePHP Framework');
Au contraire des autres types de hash, la comparaison des valeurs de texte brut devra tre fate comme
ce qui suit :
// $storedPassword, est un hash bcrypt prcdemment gnr.
$newHash = Security::hash($newPassword, 'blowfish', $storedPassword);
Quand vous comparez les valeurs hashes avec bcrypt, le hash original devra tre fourni dans le
paramtre $salt. Cela permet bcrypt de rutiliser les mmes valeur de cot et de salt, en autorisant
le hash gnr de retourner les mmes hashs rsultants, avec la mme valeur dentre.
Modifi dans la version 2.3 : Le support pour bcrypt a t ajout dans la version 2.3.
static Security::setHash($hash)
Type retourn void
Dfinit la mthode de hash par dfaut pour lobjet Security. Cela affecte tous les objets en utilisant
Security : :hash().
static Security::validateAuthKey($authKey)
Type retourn boolean
Valide les hash dautorisation.
Set
class Set
La gestion de tableau, si elle est bien faite, peut tre un outil trs puissant et utile pour construire plus malin,
et du code plus optimis. CakePHP offre un ensemble dutilitaires statiques trs utile dans la classe Set qui
vous permet justement de faire cela.
La classe Set de CakePHP peut tre appele par nimporte quel model ou controller de la mme faon que
lInflector est appel. Exemple : Set::combine().
Obsolte depuis la version 2.2 : La classe Set a t dprcie dans 2.2 en faveur de la classe Hash. Il offre
une interface et une API plus cohrente.
La syntaxe du Chemin Set-compatible
La syntaxe de Chemin est utilise par sorte (par exemple), et est utilise pour dfinir un chemin.
Exemple dutilisation (en utilisant Set::sort()) :
Utilitaires
751
$a = array(
0 => array('Person' => array('name' =>
1 => array('Person' => array('name' =>
2 => array('Person' => array('name' =>
);
$result = Set::sort($a, '{n}.Person.name',
/* result now looks like
array(
0 => array('Person' => array('name' =>
1 => array('Person' => array('name' =>
2 => array('Person' => array('name' =>
);
*/
Comme vous pouvez le voir dans lexemple ci-dessus, certaines choses sont entoures de {}, dautres non.
Dans la table ci-dessous, vous pouvez voir quelles options sont disponibles.
Expression
{n}
{s}
Foo
{[a-z]+}
Definition
Reprsente une cl numrique
Reprsente une chane
Toute chane (sans les accolades fermantes) est traite comme une chane littrale.
Toute chane entre accolades ( part {n} et {s}) est interprte comme une expression
rgulire.
752
// $result == True
$result = Set::check($set, 'My Index 1');
// $result == True
$result = Set::check($set, array());
// $result == array('My Index 1' => array('First' => 'The first item'))
$set = array(
'My Index 1' => array('First' =>
array('Second' =>
array('Third' =>
array('Fourth' => 'Heavy. Nesting.'))))
);
$result = Set::check($set, 'My Index 1.First.Second');
// $result == True
$result = Set::check($set, 'My Index 1.First.Second.Third');
// $result == True
$result = Set::check($set, 'My Index 1.First.Second.Third.Fourth');
// $result == True
$result = Set::check($set, 'My Index 1.First.Seconds.Third.Fourth');
// $result == False
Utilitaires
753
*/
$result = Set::classicExtract($a, '1.Article.title');
// $result == "Article 2"
$result = Set::classicExtract($a, '3.Article.title');
// $result == null
Exemple 2
$a = array(
0 => array('pages' => array('name' => 'page')),
1 => array('fruites' => array('name' => 'fruit')),
'test' => array(array('name' => 'jippi')),
'dot.test' => array(array('name' => 'jippi'))
);
$result = Set::classicExtract($a, '{n}.{s}.name');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[0] => page
)
[1] => Array
(
[0] => fruit
)
)
*/
$result = Set::classicExtract($a, '{s}.{n}.name');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[0] => jippi
)
[1] => Array
(
[0] => jippi
)
)
*/
$result = Set::classicExtract($a,'{\w+}.{\w+}.name');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[pages] => page
)
[1] => Array
(
754
Utilitaires
755
*/
$result = Set::classicExtract($a,'{s}');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[0] => Array
(
[name] => jippi
)
)
[1] => Array
(
[0] => Array
(
[name] => jippi
)
)
)
/
*
$result = Set::classicExtract($a,'{[a-z]}');
/* $result ressemble maintenant :
Array
(
[test] => Array
(
[0] => Array
(
[name] => jippi
)
)
[dot.test] => Array
(
[0] => Array
(
[name] => jippi
)
)
)
/
*
$result = Set::classicExtract($a, '{dot\.test}.{n}');
/* $result ressemble maintenant :
Array
(
[dot.test] => Array
(
[0] => Array
(
[name] => jippi
)
756
)
)
*/
Utilitaires
757
(
[2] =>
[14] =>
[25] =>
)
*/
$result = Set::combine($a, '{n}.User.id', '{n}.User.non-existant');
/* $result ressemble maintenant :
Array
(
[2] =>
[14] =>
[25] =>
)
*/
$result = Set::combine($a, '{n}.User.id', '{n}.User.Data');
/* $result ressemble maintenant :
Array
(
[2] => Array
(
[user] => mariano.iglesias
[name] => Mariano Iglesias
)
[14] => Array
(
[user] => phpnut
[name] => Larry E. Masters
)
[25] => Array
(
[user] => gwoo
[name] => The Gwoo
)
)
/
*
$result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name');
/* $result ressemble maintenant :
Array
(
[2] => Mariano Iglesias
[14] => Larry E. Masters
[25] => The Gwoo
)
*/
$result = Set::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
/* $result ressemble maintenant :
Array
(
758
=> mariano.iglesias
=> Mariano Iglesias
=> gwoo
=> The Gwoo
=> phpnut
=> Larry E. Masters
)
*/
$result = Set::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
/* $result ressemble maintenant :
Array
(
[1] => Array
(
[2] => Mariano Iglesias
[25] => The Gwoo
)
[2] => Array
(
[14] => Larry E. Masters
)
)
/
*
Utilitaires
759
)
*/
760
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1'
$result = Set::countDim($data);
// $result == 2
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1'
$result = Set::countDim($data, true);
// $result == 3
$data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1
$result = Set::countDim($data, true);
// $result == 4
$data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1
$result = Set::countDim($data, true);
Utilitaires
761
// $result == 5
$data = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1
$result = Set::countDim($data, true);
// $result == 5
$set = array('1' => array('1.1' => '1.1.1'), array('2' => array('2.1' => array('2.1.1'
$result = Set::countDim($set, false, 0);
// $result == 2
$result = Set::countDim($set, true);
// $result == 5
=> 'main'),
=> 'about')
=> 'main'),
=> 'about'),
=> 'contact')
762
Array
(
[0] => Array
(
[name] => main
)
[1] => Array
(
[name] => about
)
[2] => Array
(
[name] => contact
)
)
*/
$b = array(
0 => array('name' => 'me'),
1 => array('name' => 'about')
);
$result = Set::diff($a, $b);
/* $result now looks like:
Array
(
[0] => Array
(
[name] => main
)
)
*/
763
$res = Set::filter(array('0', false, true, 0, array('one thing', 'I can tell you', 'is
/* $res ressemble maintenant :
Array (
[0] => 0
[2] => 1
[3] => 0
[4] => Array
(
764
$data = array(
array('Person' => array('first_name' => 'Nate', 'last_name' => 'Abele', 'city' =>
array('Person' => array('first_name' => 'Larry', 'last_name' => 'Masters', 'city'
array('Person' => array('first_name' => 'Garrett', 'last_name' => 'Woodworth', 'ci
Utilitaires
765
*/
766
$a = array(
'pages' => array('name' => 'page')
);
$result = Set::insert($a, 'files', array('name' => 'files'));
/* $result ressemble maintenant :
Array
(
[pages] => Array
(
[name] => page
)
[files] => Array
(
[name] => files
)
)
/
*
$a = array(
'pages' => array('name' => 'page')
);
$result = Set::insert($a, 'pages.name', array());
/* $result ressemble maintenant :
Array
(
[pages] => Array
(
[name] => Array
(
)
)
)
*/
$a = array(
'pages' => array(
0 => array('name' => 'main'),
1 => array('name' => 'about')
)
);
$result = Set::insert($a, 'pages.1.vars', array('title' => 'page title'));
/* $result ressemble maintenant :
Array
(
[pages] => Array
(
[0] => Array
(
[name] => main
)
[1] => Array
(
[name] => about
Utilitaires
767
768
Utilitaires
769
// retourne true
$res=Set::matches(array('id<2'), $a[1]['Article']);
// retourne false
$res=Set::matches(array('id>1'), $a[1]['Article']);
// retourne true
$res=Set::matches(array('id>1', 'id<3', 'id!=0'), $a[1]['Article']);
// retourne true
$res=Set::matches(array('3'), null, 3);
// retourne true
$res=Set::matches(array('5'), null, 5);
// retourne true
$res=Set::matches(array('id'), $a[1]['Article']);
// retourne true
$res=Set::matches(array('id', 'title'), $a[1]['Article']);
// retourne true
$res=Set::matches(array('non-existent'), $a[1]['Article']);
// retourne false
$res=Set::matches('/Article[id=2]', $a);
// retourne true
$res=Set::matches('/Article[id=4]', $a);
// retourne false
$res=Set::matches(array(), $a);
// retourne true
770
Utilitaires
771
772
(
[Tree] =>
[CounterCache] =>
[Upload] => Array
(
[folder] =>
[fields] =>
(
[0]
[1]
[2]
[3]
[4]
)
products
Array
=>
=>
=>
=>
=>
image_1_id
image_2_id
image_3_id
image_4_id
image_5_id
)
[Cacheable] => Array
(
[enabled] =>
)
[Limit] =>
[Bindable] =>
[Validator] =>
[Transactional] =>
)
*/
static Set::numeric($array=null)
Type retourn boolean
Vrifie si toutes les valeurs dans le tableau sont numriques :
$data = array('one');
$res = Set::numeric(array_keys($data));
// $res est true
$data = array(1 => 'one');
$res = Set::numeric($data);
// $res est false
$data = array('one');
$res = Set::numeric($data);
// $res est false
$data = array('one' => 'two');
$res = Set::numeric($data);
// $res est false
$data = array('one' => 1);
$res = Set::numeric($data);
Utilitaires
773
$array1 = array('ModelOne' => array('id' => 1001, 'field_one' => 'a1.m1.f1', 'field_tw
$array2 = array('ModelOne' => array('id' => 1003, 'field_one' => 'a3.m1.f1', 'field_tw
$res = Set::pushDiff($array1, $array2);
/* $res ressemble maintenant :
Array
(
[ModelOne] => Array
(
[id] => 1001
[field_one] => a1.m1.f1
[field_two] => a1.m1.f2
[field_three] => a3.m1.f3
)
)
/
*
Exemple 2
774
static Set::reverse($object)
Type retourn array
Set : :reverse est au fond loppos de Set::map. Elle convertit un objet en un tableau. Si $object
nest pas un objet, reverse va simplement retourner $object.
$result = Set::reverse(null);
// Null
$result = Set::reverse(false);
// false
$a = array(
'Post' => array('id' => 1, 'title' => 'Premier Post'),
'Comment' => array(
Utilitaires
775
776
(
[0] => Array
(
[id] =>
[title]
)
[1] => Array
(
[id] =>
[title]
)
)
[Tag] => Array
(
[0] => Array
(
[id] =>
[title]
)
[1] => Array
(
[id] =>
[title]
)
)
1
=> Premier Comment
2
=> Deuxime Comment
1
=> First Tag
2
=> Second Tag
)
)
*/
$result = Set::reverse($a['Post']); // Retourne juste un tableau
/* $result ressemble maintenant :
Array
(
[id] => 1
[title] => Premier Post
)
*/
Utilitaires
777
(
[color] => black
)
)
[1] => Array
(
[Person] => Array
(
[name] => Jeff
)
)
)
*/
$result = Set::sort($a, '{n}.Shirt', 'asc');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[Person] => Array
(
[name] => Jeff
)
)
[1] => Array
(
[Shirt] => Array
(
[color] => black
)
)
)
*/
$result = Set::sort($a, '{n}', 'desc');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[Shirt] => Array
(
[color] => black
)
)
[1] => Array
(
[Person] => Array
(
[name] => Jeff
)
)
778
)
*/
$a = array(
array(7,6,4),
array(3,4,5),
array(3,2,1),
);
= array(
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
);
$result = Set::nest($data, array('root' => 6));
/* $result ressemble maintenant :
array(
(int) 0 => array(
'ModelName' => array(
'id' => (int) 6,
'parent_id' => null
),
'children' => array(
Utilitaires
779
)
)
)
*/
CakeText
class CakeText
La classe CakeText inclut des mthodes pratiques pour la cration et la manipulation des chanes de caractres et est normalement accessible statiquement. Exemple : CakeText::uuid().
Obsolte depuis la version 2.7 : La classe String a t dprcie dans 2.7 en faveur de la classe
CakeText. Bien que la classe String soit toujours disponible pour garder une rtro-compatibilit, utiliser
CakeText est recommande puisquelle offre une compatibilit avec PHP7 et HHVM.
Si vous avez besoin des fonctionnalits de TextHelper en-dehors dune View, utilisez la classe
CakeText :
class UsersController extends AppController {
public $components = array('Auth');
public function afterLogin() {
780
App::uses('CakeText', 'Utility');
$message = $this->User->find('new_message');
if (!empty($message)) {
// notification l'utilisateur d'un nouveau message
$this->Session->setFlash(__('Vous avez un message: %s', CakeText::truncate($mes
}
}
}
Modifi dans la version 2.1 : Plusieurs mthodes de TextHelper ont t dplaces dans la classe
CakeText.
static CakeText::uuid
La mthode UUID est utilise pour gnrer des identificateurs uniques comme per RFC 4122 42 .
UUID est une chane de caractres de 128bit au format 485fc381-e790-47a3-9794-1337c0a8fe68.
CakeText::uuid(); // 485fc381-e790-47a3-9794-1337c0a8fe68
CakeText::insert('Mon nom est :name et j'ai :age ans.', array('name' => 'Bob', 'age' =
// gnre: "Mon nom est Bob et j'ai 65 ans."
Utilitaires
781
Vous pouvez fournir un tableau doptions qui contrlent la faon dont on entoure. Les options possibles sont :
width La largeur de lenroulement. Par dfaut 72.
wordWrap Entoure ou non les mots entiers. Par dfaut true.
indent Le caractre avec lequel on indente les lignes. Par dfaut .
indentAt Le nombre de ligne pour commencer lindentation du texte. Par dfaut 0.
CakeText::highlight(string $haystack, string $needle, array $options = array())
Paramtres
$haystack (string) La chane de caractres rechercher.
$needle (string) La chane trouver.
$options (array) Un tableau doptions, voir ci-dessous.
Mettre en avant $needle dans $haystack en utilisant la chane spcifique
$options[format] ou une chane par dfaut.
Options :
format - chane la partie de html avec laquelle la phrase sera mise en exergue.
html - bool Si true, va ignorer tous les tags HTML, sassurant que seul le bon texte est mise en
avant.
Exemple :
// appel avec TextHelper
echo $this->Text->highlight(
$lastSentence,
'using',
array('format' => '<span class="highlight">\1</span>')
);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::highlight(
$lastSentence,
'using',
array('format' => '<span class="highlight">\1</span>')
);
Sortie :
782
CakeText::stripLinks($text)
Enlve le $text fourni de tout lien HTML.
CakeText::truncate(string $text, int $length=100, array $options)
Paramtres
$text (string) Le texte tronquer.
$length (int) La longueur en caractres pour laquelle le texte doit tre tronqu.
$options (array) Un tableau doptions utiliser.
Si $text est plus long que $length, cette mthode le tronque la longueur $length et ajoute un
prefix ellipsis, si dfini. Si exact est pass false, le truchement va se faire au premier
espace aprs le point o $length a dpass. Si html est pass true, les balises html seront
respectes et ne seront pas coupes.
$options est utilis pour passer tous les paramtres supplmentaires, et a les cls suivantes possibles par dfaut, celles-ci tant toutes optionnelles :
array(
'ellipsis' => '...',
'exact' => true,
'html' => false
)
Exemple :
// appel avec TextHelper
echo $this->Text->truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::truncate(
'The killer crept forward and tripped on the rug.',
22,
array(
'ellipsis' => '...',
'exact' => false
)
);
Sortie :
The killer crept...
Modifi dans la version 2.3 : ending a t remplac par ellipsis. ending est toujours utilis dans
2.2.1.
Utilitaires
783
Sortie :
...a TV, a C# program that can divide by zero, death metal t-shirts
Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...
Sortie :
red, orange, yellow, green, blue, indigo et violet
CakeTime
class CakeTime
Si vous avez besoin de fonctionnalits TimeHelper en-dehors dune View, utilisez la classe CakeTime :
class UsersController extends AppController {
public $components = array('Auth');
public function afterLogin() {
App::uses('CakeTime', 'Utility');
if (CakeTime::isToday($this->Auth->user('date_of_birth']))) {
// greet user with a happy birthday message
Utilitaires
785
Modifi dans la version 2.2 : Le paramtre $timezone remplace $userOffset utilis dans 2.1 et
suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
CakeTime::format($date, $format = NULL, $default = false, $timezone = NULL)
Type retourn string
Va retourner une chane formate avec le format donn en utilisant les options de formatage de la
fonction PHP strftime() 43 :
// appel via TimeHelper
echo $this->Time->format('2011-08-22 11:53:00', '%B %e, %Y %H:%M %p');
// August 22nd, 2011 11:53 AM
echo $this->Time->format('%r', '+2 days');
// 2 days from now formatted as Sun, 13 Nov 2011 03:36:10 AM EET
// appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2011-08-22 11:53:00', '%B %e, %Y %H:%M %p');
echo CakeTime::format('+2 days', '%c');
Vous pouvez aussi fournir la date/time en premier argument. En faisant cela vous devrez utiliser le
format strftime compatible. Cette signature dappel vous permet de tirer parti du format de date
de la locale ce qui nest pas possible en utilisant le format de date() compatible :
// appel avec TimeHelper
echo $this->Time->format('2012-01-13', '%d-%m-%Y', 'invalid');
// appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::format('2011-08-22', '%d-%m-%Y');
Modifi dans la version 2.2 : Les paramtres $format et $date sont en ordre oppos par rapport ce qui se faisait dans 2.1 et suivants. Le paramtre $timezone remplace le paramtre
$userOffset utilis dans 2.1 et suivants. Le paramtre $default remplace le paramtre
$invalid utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $date accepte aussi maintenant un objet DateTime.
43. http ://www.php.net/manual/en/function.strftime.php
Utilitaires
787
788
Utilitaires
789
Utilisez loption end pour dterminer le point de cutoff pour ne plus utiliser de mots ; par dfaut
+1 month :
// Appel avec TimeHelper
echo $this->Time->timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
// On Nov 10th, 2011 it would display: 2 months, 2 weeks, 6 days ago
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::timeAgoInWords(
'Aug 22, 2011',
array('format' => 'F jS, Y', 'end' => '+1 year')
);
Utilisez loption accuracy pour dterminer la prcision de la sortie. Vous pouvez utiliser ceci pour
limiter la sortie :
// Si $timestamp est il y a 1 month, 1 week, 5 days et 6 hours
echo CakeTime::timeAgoInWords($timestamp, array(
'accuracy' => array('month' => 'month'),
'end' => '1 year'
));
// Sort '1 month ago'
790
(
[0] => 2011-07-01
[1] => 2011-09-30
)
*/
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::toQuarter('Aug 22, 2011');
$arr = CakeTime::toQuarter('Aug 22, 2011', true);
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
Introduit dans la version 2.4 : Les nouveaux paramtres doption relativeString (par dfaut
%s ago) et absoluteString (par dfaut on %s) pour permettre la personnalisation de la
chane de sortie rsultante sont maintenant disponibles.
CakeTime::toRSS($dateString, $timezone = NULL)
Type retourn string
Va retourner une chane de date au format RSS Sat, 12 Jan 2008 00 :00 :00 -0500
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
CakeTime::toUnix($dateString, $timezone = NULL)
Type retourn integer
Un enrouleur pour fromString.
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
CakeTime::toServer($dateString, $timezone = NULL, $format = Y-m-d H :i :s)
Type retourn mixed
Introduit dans la version 2.2 : Retourne une date formate dans le timezone du serveur.
CakeTime::timezone($timezone = NULL)
Type retourn DateTimeZone
Introduit dans la version 2.2 : Retourne un objet timezone partir dune chane de caractres ou de
lobjet timezone de lutilisateur. Si la fonction est appele sans paramtres, elle essaie dobtenir le
timezone de la variable de configuration Config.timezone.
CakeTime::listTimezones($filter = null, $country = null, $options = array())
Type retourn array
Introduit dans la version 2.2 : Retourne une liste des identificateurs de timezone.
Modifi dans la version 2.8 : $options accepte maintenant un tableau avec les cls group, abbr,
before, et after. Spcifier abbr => true va ajouter labrviation de la timezone dans le texte
<option>.
Utilitaires
791
Tester Time
wasWithinLast prend un intervalle de time qui est une chane au format 3 months et accepte un
intervalle de time en secondes, minutes, heures, jours, semaines, mois et annes (pluriels ou non). Si
un intervalle de time nest pas reconnu (par exemple, si il y a une faute de frappe) ensuite ce sera par
dfaut days.
Xml
class Xml
La classe Xml a t reconstruite. Comme PHP 5 a SimpleXML 45 et DOMDocument 46 , CakePHP ne ncssite pas de r-implmenter un parser XML. La nouvelle classe XML va fondamentalement transformer un
tableau en objets SimpleXMLElement ou DOMDocument, et vice versa.
45. http ://php.net/simplexml
46. http ://php.net/domdocument
792
Dans CakePHP 1.3, vous pouviez passez les tableaux, les XML et les chanes de caractre, les URL ou
les chemins de fichier vers le constructeur de la classe Xml pour importer les donnes. Dans CakePHP
2.0, vous pouvez le faire en utilisant Xml::build(). A moins que le retour soit un objet Xml, cela
retournera un objet SimpleXMLElement ou DOMDocument (selon votre paramtre options - par dfault
SimpleXMLElement). Ci-dessous les chantillons sur la faon dimporter des donnes depuis une URL :
//D'abord charger la Classe Utility
App::uses('Xml', 'Utility');
// Vieille mthode:
$xml = new Xml('http://bakery.cakephp.org/articles.rss');
// Nouvelle mthode en utilisant SimpleXML
$xml = Xml::build('http://bakery.cakephp.org/articles.rss');
// $xml est maintenant une instance de SimpleXMLElement
//ou
$xml = Xml::build('http://bakery.cakephp.org/articles.rss', array('return' => 'simplexml'))
// $xml est maintenant une instance de SimpleXMLElement
Vous pouvez utiliser Xml::build() pour construire les objets XML partir de diverses sources. Vous
pouvez utiliser XML pour construire des objets partir dune chane de caractre :
$text = '<?xml version="1.0" encoding="utf-8"?>
<post>
<id>1</id>
<title>Meilleur post</title>
<body> ... </body>
</post>';
$xml = Xml::build($text);
Vous pouvez aussi construire des objets Xml partir de fichiers locaux, ou de fichiers distants. Les fichiers
distants seront rcuprs avec HttpSocket :
// fichier local
$xml = Xml::build('/home/awesome/unicorns.xml');
// fichier distant
$xml = Xml::build('http://bakery.cakephp.org/articles.rss');
Utilitaires
793
Note : DOMDocument 47 et SimpleXML 48 implement different APIs. Assurez vous dutiliser les bonnes
mthodes sur lobjet que vous requtez partir dun Xml.
Convertir des chanes XML en tableaux est aussi facile avec la classe Xml. Par dfaut, vous obtiendrez un
objet SimpleXml en retour :
//Vieille mthode:
$xmlString = '<?xml version="1.0"?><root><child>value</child></root>';
$xmlObject = new Xml($xmlString);
$xmlArray = $xmlObject->toArray();
// Nouvelle mthode:
$xmlString = '<?xml version="1.0"?><root><child>value</child></root>';
$xmlArray = Xml::toArray(Xml::build($xmlString));
// Vieille mthode:
$xmlArray = array('root' => array('child' => 'value'));
$xmlObject = new Xml($xmlArray, array('format' => 'tags'));
$xmlString = $xmlObject->toString();
// Nouvelle mthode:
$xmlArray = array('root' => array('child' => 'value'));
$xmlObject = Xml::fromArray($xmlArray, array('format' => 'tags')); // You can use Xml::buil
$xmlString = $xmlObject->asXML();
47. http ://php.net/domdocument
48. http ://php.net/simplexml
794
Votre tableau ne doit avoir quun lment de niveau suprieur et il ne doit pas tre numrique. Si le tableau
nest pas dans le bon format, Xml va lancer une Exception. Des Exemples de tableaux invalides :
// Niveau suprieur avec une cl numrique
array(
array('key' => 'value')
);
// Plusieurs cls au niveau suprieur
array(
'key1' => 'premire valeur',
'key2' => 'autre valeur'
);
Avertissement : Loption format par dfault a t change de attributes pour tags. Cela a t fait pour
rendre le Xml que la classe Xml gnre plus compatible avec le Xml dans la nature. Attention si vous
dpendez de celui-ci. Dans la nouvelle version, vous pouvez crer un tableau mixte avec des tags, des
attributs et valeurs, utilisez juste le format en tags (ou ne dtes rien, car cest la valeur par dfaut) et les
cls prfixes qui sont senses tre des attributs avec @. Pour une valeur texte, mettez la cl @.
$xmlArray = array(
'projet' => array(
'@id' => 1,
'name' => 'Nom du projet, en tag',
'@' => 'Valeur du projet'
)
);
$xmlObject = Xml::fromArray($xmlArray);
$xmlString = $xmlObject->asXML();
Note : La structure des tableaux a t change. Maintenant lenfant doit avoir un sous-arbre et ne pas tre
dans le mme arbre. En plus, les chanes de caractres ne seront pas changes par Inflector. Regardez
lexemple ci-dessous :
$oldArray = array(
'Projets' => array(
array(
'Projet' => array('id' => 1, 'title' => 'Projet 1'),
'Industry' => array('id' => 1, 'name' => 'Industry 1')
),
array(
'Projet' => array('id' => 2, 'title' => 'Projet 2'),
'Industry' => array('id' => 2, 'name' => 'Industry 2')
)
)
);
Utilitaires
795
$newArray = array(
'projets' => array(
'projet' => array(
array(
'id' => 1,
'industry'
),
array(
'id' => 2,
'industry'
)
)
)
);
Utiliser des Namespaces Pour utiliser les Namespaces XML, dans votre tableau vous devez crer une
cl avec le nom xmlns: vers un namespace gnrique ou avec le prfixe xmlns: dans un namespace
personnalis. Regardez les exemples :
$xmlArray = array(
'root' => array(
'xmlns:' => 'http://cakephp.org',
'child' => 'value'
)
);
$xml1 = Xml::fromArray($xmlArray);
$xmlArray(
'root' => array(
796
<?xml version="1.0"?>
<root><tag xmlns:pref="http://cakephp.org"><pref:item>item 1</pref:item><pref:item>item 2</
Crer un enfant La classe Xml de CakePHP 2.0 ne fournit pas la manipulation du contenu, cela doit tre
fait en utilisant SimpleXMLElement ou DOMDocument. Mais, comme CakePHP est trop sympa, ci-dessous
vous avez les tapes pour crer un noeud enfant :
// CakePHP 1.3
$myXmlOriginal = '<?xml version="1.0"?><root><child>value</child></root>';
$xml = new Xml($myXmlOriginal, array('format' => 'tags'));
$xml->children[0]->createNode('young', 'new value');
// CakePHP 2.0 - En utilisant SimpleXML
$myXmlOriginal = '<?xml version="1.0"?><root><child>value</child></root>';
$xml = Xml::build($myXmlOriginal);
$xml->root->addChild('young', 'new value');
// CakePHP 2.0 - En utilisant DOMDocument
$myXmlOriginal = '<?xml version="1.0"?><root><child>value</child></root>';
$xml = Xml::build($myXmlOriginal, array('return' => 'domdocument'));
$child = $xml->createElement('young', 'new value');
$xml->firstChild->appendChild($child);
Astuce : Aprs avoir manipul votre XML en utilisant SimpleXMLElement ou DomDocument vous pouvez
utiliser Xml::toArray() sans problmes.
API de Xml
Une classe usine de conversion pour crer des objets SimpleXML ou DOMDocument partir dun certain
nombre de sources, y compris des chanes, des tableaux et des URLs distantes.
Utilitaires
797
Quand on construit du XML partir dun tableau, assurez-vous quil ny a quun seul lment de
niveau suprieur.
static Xml::toArray($obj)
Convertit soit un objet SimpleXml, soit DOMDocument en un tableau.
798
CHAPITRE 8
Plugins
CakePHP vous permet de mettre en place une combinaison de controllers, models et vues et de les distribuer
comme un plugin dapplication packag que dautres peuvent utiliser dans leurs applications CakePHP. Vous
avez un module de gestion des utilisateurs sympa, un simple blog, ou un module de service web dans une
de vos applications ? Packagez le en plugin CakePHP afin de pouvoir la mettre dans dautres applications.
Le principal lien entre un plugin et lapplication dans laquelle il a t install, est la configuration de lapplication (connexion la base de donnes, etc.). Autrement, il fonctionne dans son propre espace, se comportant
comme il laurait fait si il tait une application part entire.
Manuellement
Pour installer un plugin manuellement, vous avez juste dposer le dossier du plugin dans votre rpertoire
app/Plugin/. Si vous installez un plugin nomm ContactManager, vous devez alors avoir un dossier nomm
ContactManager dans le rpertoire app/Plugin/ lintrieur duquel sont les View, Model, Controller, webroot et tout autre rpertoire de votre plugin.
799
Composer
Si vous ntes pas familier avec le gestionnaire de dpendances nomm Composer, prenez le temps de lire
la documentation de Composer 1 .
Pour installer le plugin imaginaire ContactManager grce Composer, ajoutez le en tant que dpendance
dans le composer.json de votre projet :
{
"require": {
"cakephp/contact-manager": "1.2.*"
}
}
Si le plugin CakePHP est de type cakephp-plugin, comme il se devrait, Composer linstallera lintrieur de votre rpertoire /Plugin, au lieu du rpertoire vendors habituel.
Note : Utilisez require-dev si vous souhaitez uniquement inclure le plugin pour votre environnement de
dveloppement.
Sinon, vous pouvez utiliser l outil CLI de Composer 2 pour dclarer (et installer) le plugin :
php composer.phar require cakephp/contact-manager:1.2.*
Clonage Git
Si le plugin que vous souhaitez installer est hberg en tant que dpt Git, vous pouvez galement le cloner.
Imaginons que le plugin ContactManager est hberg sur Github. Vous pouvez le cloner en excutant la
ligne de commande suivante depuis votre rpertoire app/Plugin/ :
git clone git://github.com/cakephp/contact-manager.git ContactManager
Sous-module Git
Si le plugin que vous souhaitez installer est hberg en tant que dpt Git mais que vous ne voulez pas le
cloner, vous pouvez galement lintgrer en tant que sous-module. Excutez la ligne de commande suivante
depuis votre rpertoire app :
git submodule add git://github.com/cakephp/contact-manager.git Plugin/ContactManager
git submodule init
git submodule update
1. https ://getcomposer.org/doc/00-intro.md
2. https ://getcomposer.org/doc/03-cli.md#require
800
Chapitre 8. Plugins
loadAll() charge tous les plugins disponibles, et vous laisse la possibilit de rgler certain paramtres
pour des plugins spcifiques. load() fonctionne de faon similaire mais charge uniquement le plugin
spcifi explicitement.
Configuration du Plugin
Vous pouvez faire beaucoup de choses avec les mthodes load et loadAll pour vous aider avec la configuration et le routing dun plugin. Peut-tre souhaiterez vous charger tous les plugins automatiquement, en
spcifiant des routes et des fichiers de bootstrap pour certains plugins.
Pas de problme :
CakePlugin::loadAll(array(
'Blog' => array('routes' => true),
'ContactManager' => array('bootstrap' => true),
'WebmasterTools' => array('bootstrap' => true, 'routes' => true),
));
Avec ce type de configuration, vous navez plus besoin de faire manuellement un include() ou un require()
dune configuration de plugin ou dun fichier de routesCela arrive automatiquement au bon moment et
la bonne place. Un paramtre totalement identique peut avoir t fourni la mthode load(), ce qui aurait
charg seulement ces trois plugins, et pas le reste.
Au final, vous pouvez aussi spcifier un ensemble de valeurs dans defaults pour loadAll qui sapplique
chaque plugin qui na pas de configuration spcifique.
Chargez le fichier bootstrap partir de tous les plugins, et aussi les routes du plugin Blog :
CakePlugin::loadAll(array(
array('bootstrap' => true),
'Blog' => array('routes' => true)
));
Notez que tous les fichiers spcifis doivent rellement exister dans le(s) plugin(s) configurs ou PHP vous
donnera des avertissements pour chaque fichier quil ne peut pas charger. Cest particulrement important
retenir quand on spcifie defaults pour tous les plugins.
801
CakePHP 2.3.0 ajoute une option ignoreMissing, qui vous permet dignorer toute route manquante et
les fichiers de bootstrap quand vous chargez les plugins. Vous pouvez raccourcir le code en chargeant tous
les plugins en utilisant ceci :
// Charge tous les plugins y compris les possibles routes et les fichiers de bootstrap
CakePlugin::loadAll(array(
array('routes' => true, 'bootstrap' => true, 'ignoreMissing' => true)
));
Certains plugins ont besoin en supplment de crer une ou plusieurs tables dans votre base de donnes. Dans
ces cas, ils incluent souvent un fichier de schma que vous appelez partir du shell de cake comme ceci :
user@host$ cake schema create --plugin ContactManager
La plupart des plugins indiqueront dans leur documentation leur propre procdure pour les configurer et
configurer la base de donnes. Certains plugins ncessiteront plus de configuration que dautres.
Vous pouvez aussi spcifier une fonction qui pourra tre appele quand le plugin est charg :
function aCallableFunction($pluginName, $config) {
}
CakePlugin::loadAll(array(
'Blog' => array(
'bootstrap' => 'aCallableFunction'
)
));
Utiliser un Plugin
Vous pouvez rfrencer les controllers, models, components, behaviors et helpers du plugin en prfixant le
nom du plugin avant le nom de classe.
802
Chapitre 8. Plugins
Par exemple, disons que vous voulez utiliser le ContactInfoHelper du plugin ContactManager pour sortir
de bonnes informations de contact dans une de vos vues. Dans votre controller, le tableau $helpers pourrait
ressembler ceci :
public $helpers = array('ContactManager.ContactInfo');
Vous serez ensuite capable daccder ContactInfoHelper comme tout autre helper dans votre vue, comme
ceci :
echo $this->ContactInfo->address($contact);
Notez que le nom du dossier du plugin, ContactManager. Il est important que ce dossier ait le mme nom
que le plugin.
Dans le dossier plugin, vous remarquerez quil ressemble beaucoup une application CakePHP, et cest au
fond ce que cest. Vous navez inclure aucun de vos dossiers si vous ne les utilisez pas. Certains plugins
peuvent ne contenir quun Component ou un Behavior, et dans certains cas, ils peuvent carrment ne pas
avoir de rpertoire View.
Un plugin peut aussi avoir tous les autres rpertoires que votre application a, comme Config, Console, Lib,
webroot, etc...
Note : Si vous voulez tre capable daccder votre plugin avec une URL, vous devrez dfinir un AppController et un AppModel pour le plugin. Ces deux classes spciales sont nommes daprs le plugin, et
tendent les AppController et AppModel de notre application parente. Voil quoi cela devrait ressembler
pour notre exemple de ContactManager :
// /app/Plugin/ContactManager/Controller/ContactManagerAppController.php:
class ContactManagerAppController extends AppController {
}
803
// /app/Plugin/ContactManager/Model/ContactManagerAppModel.php:
class ContactManagerAppModel extends AppModel {
}
Si vous oubliez de dfinir ces classes spciales, CakePHP vous donnera des erreurs Missing Controller
jusqu ce que ce soit fait.
Notez que le processus de cration de plugins peut tre simplifi en utilisant le shell de CakePHP.
Pour cuisiner un plugin, utilisez la commande suivante :
user@host$ cake bake plugin ContactManager
Maintenant vous pouvez cuisiner en utilisant les mmes conventions qui sappliquent au reste de votre app.
Par exemple - baking controllers :
user@host$ cake bake controller Contacts --plugin ContactManager
Consultez le chapitre Gnration de code avec Bake si vous avez le moindre problme avec lutilisation de
la ligne de commande.
Avertissement : Les Plugins ne fonctionnent pas en namespace pour sparer le code. A cause du manque
de namespaces de PHP dans les versions plus vieilles, vous ne pouvez pas avoir la mme classe ou le
mme nom de fichier dans vos plugins. Mme si il sagit de deux plugins diffrents. Donc utilisez des
classes et des noms de fichier uniques, en prfixant si possible la classe et le nom de fichier par le nom
du plugin.
Controllers du Plugin
Les
controllers
pour
notre
plugin
ContactManager
seront
stocks
dans
/app/Plugin/ContactManager/Controller/. Puisque la principale chose que nous souhaitons faire est la
gestion des contacts, nous aurons besoin de crer un ContactsController pour ce plugin.
Ainsi, nous mettons notre nouveau ContactsController dans /app/Plugin/ContactManager/Controller et il
ressemblerait cela :
// app/Plugin/ContactManager/Controller/ContactsController.php
class ContactsController extends ContactManagerAppController {
public $uses = array('ContactManager.Contact');
public function index() {
//...
}
}
Chapitre 8. Plugins
Dans ce cas, le tableau $uses ne serait pas ncessaire comme dans ContactManager. Contact sera le model
par dfaut pour ce controller, cependant, il est inclu pour dmontrer comment faire prceder proprement le
nom du plugin.
Si vous souhaitez accder ce que nous avons obtenu jusqu prsent, visitez /contact_manager/contacts.
Vous devriez obtenir une erreur Missing Model parce que nous navons pas un model Contact dj dfini.
Models du Plugin
Les Models pour le plugin sont stocks dans /app/Plugin/ContactManager/Model. Nous avons dj dfini
un ContactsController pour ce plugin, donc crons le model pour ce controller, appel Contact :
// /app/Plugin/ContactManager/Model/Contact.php:
class Contact extends ContactManagerAppModel {
}
Visiter /contact_manager/contacts maintenant (Etant donn, que vous avez une table dans votre base de
donnes appele contacts) devrait nous donner une erreur Missing View. Crons la ensuite.
Note : Si vous avez besoin de rferencer un model dans votre plugin, vous avez besoin dinclure le nom du
plugin avec le nom du model, spar dun point.
Par exemple :
// /app/Plugin/ContactManager/Model/Contact.php:
class Contact extends ContactManagerAppModel {
public $hasMany = array('ContactManager.AltName');
}
Si vous prfrez que les cls du tableau pour lassociation naient pas le prfixe du plugin sur eux, utilisez
la syntaxe alternative :
// /app/Plugin/ContactManager/Model/Contact.php:
class Contact extends ContactManagerAppModel {
public $hasMany = array(
'AltName' => array(
'className' => 'ContactManager.AltName'
)
);
}
Vues du Plugin
Les Vues se comportent exactement comme elles le font dans les applications normales. Placez-les juste dans
le bon dossier lintrieur du dossier /app/Plugin/[PluginName]/View/. Pour notre plugin ContactManager,
nous aurons besoin dune vue pour notre action ContactsController : :index(), ainsi incluons ceci aussi :
805
// /app/Plugin/ContactManager/View/Contacts/index.ctp:
<h1>Contacts</h1>
<p>Ce qui suit est une liste triable de vos contacts</p>
<!-- Une liste triable de contacts irait ici....-->
Note : Pour des informations sur la faon dutiliser les elements partir dun plugin, regardez Elements.
Assets du Plugin
Les assets web du plugin (mais pas les fichiers de PHP) peuvent tre servis travers le rpertoire webroot
du plugin, tout comme les assets de lapplication principale :
app/Plugin/ContactManager/webroot/
css/
js/
img/
flash/
pdf/
Vous pouvez mettre tout type de fichier dans tout rpertoire, juste comme un webroot habituel.
Mais garder lesprit que la gestion des assets statiques, comme les images, le Javascript et les fichiers
CSS des plugins travers le Dispatcher est incroyablement inefficace. Il est grandement recommand de les
symlinker pour la production. Par exemple comme ceci :
ln -s app/Plugin/YourPlugin/webroot/css/yourplugin.css app/webroot/css/yourplugin.css
806
servira
lasset
Chapitre 8. Plugins
Note : Il est important de noter le prfixe /votre_plugin/ avant le chemin de lasset. Et la magie opre !
Modifi dans la version 2.1 : Utilisez la syntaxe de plugin pour accder aux assets. Par exemple dans votre
View :
<?php echo $this->Html->css("ContactManager.style"); ?>
807
3. http ://plugins.cakephp.org
4. https ://github.com/FriendsOfCake/awesome-cakephp
5. https ://packagist.org/
808
Chapitre 8. Plugins
CHAPITRE 9
CakePHP ne dispose pas seulement dun framework web mais aussi dune console de framework pour la
cration dapplications. Les applications par la console sont idales pour la gestion dune varit de tches
darrire-plan comme la maintenance et lachvement du travail en-dehors du cycle de requte-rponse. Les
applications par la console CakePHP vous permettent de rutiliser les classes de votre application partir
de lignes de commande.
CakePHP dispose dun certain nombre dapplications fournies pour la console. Certaines de ces applications
sont utilises de concert avec les fonctionnalits de CakePHP (comme ACL ou i18n), et dautres sont pour
une utilisation gnrale pour que votre travail se fasse plus vite.
La console de CakePHP
Cette section fournit une introduction sur la ligne de commande dans CakePHP. Si vous avez besoin daccder vos classes MVC de CakePHP dans une tche cron ou tout autre script de ligne de commande, cette
section est pour vous.
PHP fournit un puissant client CLI qui rend linterfaage avec votre systme de fichier et vos applications
plus facile. La console CakePHP fournit un framework de cration de scripts shell. La console utilise un
ensemble de rpartiteur de types pour charger un shell ou une tche, et lui passer des paramtres.
Note : Une installation de PHP contruite avec la ligne de commande (CLI) doit tre disponible sur le
systme o vous prvoyez dutiliser la console.
Avant dentrer dans les spcificits, assurons-nous que vous pouvez excuter la console CakePHP. Tout
dabord, vous devrez ouvrir un shell systme. Les exemples prsents dans cette section sont issus du bash,
mais la console CakePHP est galement compatible Windows. Excutons le programme Console depuis le
bash. Cet exemple suppose que lutilisateur est actuellement connect dans linvite bash et quil en est root
sur une installation CakePHP.
Les applications CakePHP contiennent un rpertoire Console qui contient tous les shells et les tches pour
une application. Il est aussi livr avec un excutable :
809
$ cd /path/to/cakephp/app
$ Console/cake
Mais il est prfrable dajouter lexcutable du coeur de cake dans votre systme de path afin que vous
puissiez utiliser la commande cake de partout. Cest plus pratique quand vous crez de nouveaux projets.
Regardez Ajouter cake votre systme path pour voir la faon de rendre cake disponible dans tout le
systme.
Lancez la Console avec aucun argument entrane ce message daide :
Welcome to CakePHP v2.0.0 Console
--------------------------------------------------------------App : app
Path: /path/to/cakephp/app/
--------------------------------------------------------------Current Paths:
-app: app
-working: /path/to/cakephp/app
-root: /path/to/cakephp/
-core: /path/to/cakephp/core
Changing Paths:
your working path should be the same as your application path
to change your path use the '-app' param.
Example: -app relative/path/to/cakephp/app or -app /absolute/path/to/cakephp/app
Available Shells:
acl [CORE]
api [CORE]
bake [CORE]
command_list [CORE]
console [CORE]
i18n [CORE]
import [app]
schema [CORE]
testsuite [CORE]
upgrade [CORE]
La premire information affiche est en rapport avec les chemins. Ceci est particulirement pratique si vous
excutez la Console depuis diffrents endroits de votre systme de fichier.
Beaucoup dutilisateurs ajoutent la console CakePHP leur path systme afin quelle puisse tre facilement
accessible. Laffichage des chemins de workdir, root, app et core vous permet de voir o la Console fera
des changements. Pour changer le dossier app par celui dans lequel vous souhaitez travailler, vous pouvez
fournir son chemin comme premier argument de la ligne de commande cake. Lexemple suivant montre
comment spcifier un dossier app, en supposant que vous avez dj ajout le dossier de la console votre
PATH :
$ cake -app /path/to/cakephp/app
Le chemin fourni peut tre relatif au rpertoire courant ou fourni sous forme de chemin absolu.
810
3. Rechargez la configuration bash ou ouvrez un nouveau terminal, et cake devrait fonctionner nimporte o.
Si vous tes sur Windows Vista ou 7, vous devrez suivre les tapes suivantes.
1. Localisez lemplacement o se trouvent votre installation CakePHP et lexcutable cake. Par exemple
C:\xampp\htdocs\cakephp\lib\Cake\Console
2. Ouvrez la fentre des proprits du Systme de votre ordinateur. Vous essaierez le raccourci clavier
Windows Key + Pause ou Windows Key + Break. Ou, partir du Bureau, fates un clique droit sur
Mon Ordinateur, clickez sur Proprits et cliquez sur le lien Paramtres avancs du systme dans la
colonne de gauche.
3. Allez sous longlet Avanc et cliquez sur le bouton des Variables dEnvironnement.
4. Dans la portion des Variables Sytmes, cherchez le chemin de la variable et double-cliquez dessus
pour la modifier.
5. Ajoutez le chemin de linstallation de cake suivi par un point virgule. On pourrait avoir par exemple :
%SystemRoot%\system32;%SystemRoot%;C:\xampp\htdocs\cakephp\lib\Cake\Console;
Crer un Shell
Crons un shell pour lutilisation dans la Console. Pour cet exemple, nous crerons un simple shell Hello
world. Dans le rpertoire Console/Command de votre application, crez HelloShell.php. Mettez le
code suivant dedans :
class HelloShell extends AppShell {
public function main() {
$this->out('Hello world.');
}
}
Les conventions pour les classes de shell sont que les noms de classe doivent correspondre au nom du
fichier, avec Shell en suffixe. Dans notre shell, nous avons cre une mthode main(). Cette mthode est
appele quand un shell est appel avec aucune commande supplmentaire. Nous allons ajouter quelques
commandes en plus dans un moment, mais pour linstant lanons juste notre shell. Depuis le rpertoire de
votre application, lancez :
Crer un Shell
811
Console/cake hello
Comme mentionn avant, la mthode main() dans les shells est une mthode spciale appele tant quil
ny a pas dautres commandes ou arguments donns au shell. Vous pouvez aussi remarquer que HelloShell tend AppShell. Un peu comme Le Controller App, AppShell vous donne une classe de base
pour contenir toutes les fonctions ordinaires ou logiques. Vous pouvez dfinir un AppShell en crant
app/Console/Command/AppShell.php. Si vous nen avez pas un, CakePHP en utilisera une integre. Comme notre mthode principale ntait pas trs intressante, ajoutons une autre commande qui fait
quelque chose :
class HelloShell extends AppShell {
public function main() {
$this->out('Hello world.');
}
public function hey_there() {
$this->out('Hey there ' . $this->args[0]);
}
}
Aprs avois sauvegard ce fichier, vous devriez tre capable de lancer Console/cake hello
hey_there your-name et de voir vos noms affichs. Toute mthode publique non prfixe par un _
peut tre appele partir de ligne de commande. Dans notre mthode hey_there, nous utilisons aussi
$this->args, cette proprit contient un tableau de tous les arguments de position fournis une commande. Vous pouvez aussi utiliser des switches ou des options sur les shells des applications, ils sont
disponibles dans la variable $this->params et avec la mthode param(), mais nous verrons a bientt.
Lorsque vous utilisez la mthode main(), vous ntes pas capable dutiliser les arguments de position ou
les paramtres. Cela parce que le premier argument de position ou loption est interprt en tant que nom
de commande. Si vous voulez utiliser des arguments et des options, vous devriez utiliser un autre nom de
mthode que main.
812
Le shell ci-dessus rcuprera un utilisateur par son username et affichera linformation stocke dans la base
de donnes.
Vous pouvez utiliser les tches partir de plugins en utilisant la syntaxe de plugin standard. Les
tches sont stockes dans Console/Command/Task/ dans les fichiers nommes daprs leur classe.
Ainsi si vous tiez sur le point de crer une nouvelle tche FileGenerator, vous pourriez crer
Console/Command/Task/FileGeneratorTask.php.
Chaque tche doit au moins intgrer une mthode execute(). Le ShellDispatcher appelera cette mthode
quand la tche est invoque. une classe de tche ressemble cela :
class FileGeneratorTask extends Shell {
public $uses = array('User');
public function execute() {
}
}
Un shell peut aussi accder ses tches en tant que proprits, ce qui rend les tches meilleures pour la
rutilisation de fonctions identiques Components (Composants) :
// trouv dans Console/Command/SeaShell.php
class SeaShell extends AppShell {
public $tasks = array('Sound'); // trouv dans Console/Command/Task/SoundTask.php
public function main() {
$this->Sound->execute();
}
}
Vous pouvez aussi accder aux tches directement partir de la ligne de commande :
813
Note : Afin daccder aux tches directement partir de ligne de commande, la tche doit tre inclue dans
la proprit $tasks de la classe shell. Pour ce faire, soyez averti quune mthode appele sound dans la
classe SeaShell redfinira la capacit daccs la fonctionnalit de la tche Sound spcifie dans le tableau
$tasks.
Chargera et retournera une instance ProjectTask. Vous pouvez charger les tches partir des plugins en
utilisant :
$ProgressBar = $this->Tasks->load('ProgressBar.ProgressBar');
'Blog', '--plugin',
'Blog');
Ce qui est au-dessus montre comment vous pouvez appeler le shell schema pour un plugin partir du shell
de votre plugin.
VERBOSE - Les messages marqus qui peuvent tre trop ennuyeux pour une utilisation quotidienne,
mais aide au debugging en VERBOSE
Vous pouvez marquer la sortie comme suit :
// apparaitra tous les niveaux.
$this->out('Quiet message', 1, Shell::QUIET);
// n'apparaitra pas quand une sortie quiet est toggl
$this->out('message normal', 1, Shell::NORMAL);
$this->out('message loud', 1, Shell::VERBOSE);
// would only appear when verbose output is enabled.
$this->out('extra message', 1, Shell::VERBOSE);
Vous pouvez contrler le niveau de sortie des shells, en utilisant les options --quiet et --verbose. Ces
options sont ajoutes par dfaut, et vous autorise contrler la cohrence du niveau de sortie lintrieur de
vos shells CakePHP.
Style de sortie
La Style de sortie est fait en incluant les tags - juste comme le HTML - dans votre sortie.
ConsoleOutput remplacera ces tags avec la bonne squence de code ansi, ou supprimera les tags si vous tes
sur une console qui ne supporte pas les codes ansi. Il y a plusieurs styles intgrs, et vous pouvez en crer
plus. Ceux intgrs sont :
*
*
*
*
*
Vous pouvez crer des styles supplmentaires en utilisant $this->stdout->styles(). Pour dclarer un nouveau
style de sortie, vous pouvez faire :
$this->stdout->styles('flashy', array('text' => 'magenta', 'blink' => true));
Cela vous permettra dutiliser un tag <flashy> dans la sortie de votre shell, et si
les couleurs ansi sont actives, ce qui suit sera rendu en texte magenta clignotant
$this->out(<flashy>Whoooa</flashy> Quelque chose a pos problme);.
Quand vous dfinissez les styles, vous pouvez utiliser les couleurs suivantes pour les attributs text et
background :
black
red
green
yellow
blue
magenta
cyan
white
Style de sortie
815
Vous pouvez aussi utiliser les options suivantes en commutateurs bolens, en les dfinissant une valeur
true qui les active.
bold
underline
blink
reverse
Ajouter un style le rend aussi disponible pour toutes les instances de ConsoleOutput, donc vous navez pas
re-dclarer les styles pour les deux objets stdout et stderr.
Enlever la coloration
Bien que la coloration soit vraiment gniale, il peut y avoir des fois o vous voulez larrter, ou forcer
lavoir :
$this->stdout->outputAs(ConsoleOutput::RAW);
Ce qui est au-dessus met la sortie objet dans un mode de sortie en ligne. Dans le mode de sortie en ligne, il
ny a aucun style du tout. Il y a trois modes que vous pouvez utiliser :
ConsoleOutput::RAW - Sortie en ligne, aucun style ou format ne sera fait Cest un bon mode
utiliser si vous sortez du XML ou si voulez dbugger pourquoi votre style ne marche pas.
ConsoleOutput::PLAIN - Sortie en texte plein, les tags de style connus seront enlevs de la sortie.
ConsoleOutput::COLOR - La sortie avec couleur enlve les codes en place.
Par dfaut sur les systmes *nix, les objets ConsoleOutput ont par dfaut de la couleur. Sur les systmes
Windows, la sortie simple est mise par dfaut sauf si la variable denvironnement ANSICON est prsente.
816
return $parser;
}
ConsoleOptionParser::epilog($text = null)
Rcupre ou dfinit lepilog pour le parser doption. Lepilog est affiche aprs largument et linformation
doption. En passant un tableau ou une chane, vous pouvez dfinir la valeur de epilog. Lappeler avec aucun
argument va retourner la valeur actuelle :
817
Vous pouvez utiliser les options suivantes lors de la cration dun argument :
help Le texte daide afficher pour cet argument.
required Si le paramtre est obligatoire.
index Lindex pour largument, si non dfini gauche, largument sera mis la fin des arguments.
Si vous dfinissez le mme index deux fois, la premire option sera crase.
choices Un tableau de choix valides pour cet argument. Si vide gauche, toutes les valeurs sont
valides. Une exception sera lance quand parse() rencontre une valeur non valide.
Les arguments qui ont t marqus comme ncessaires vont lancer une exception lors du parsing de la
commande si ils ont t omis. Donc vous navez pas grer cela dans votre shell.
ConsoleOptionParser::addArguments(array $args)
Si vous avez un tableau avec plusieurs arguments, vous pouvez utiliser $parser->addArguments()
pour ajouter plusieurs arguments en une fois.
$parser->addArguments(array(
'node', array('help' => 'The node to create', 'required' => true),
'parent' => array('help' => 'The parent node', 'required' => true)
));
Comme avec toutes les mthodes de construction avec ConsoleOptionParser, addArguments peuvent tre
utiliss comme des parties dune chane de mthode courante.
818
$parser->addArgument('type', array(
'help' => 'Le type de noeud avec lequel intragir.',
'required' => true,
'choices' => array('aro', 'aco')
));
Ce qui est au-dessus va crer un argument qui est ncessaire et a une validation sur lentre. Si largument
est soit manquant, soit a une valeur incorrecte, une exception sera leve et le shell sera arret.
Ce qui est au-dessus vous permet lutilisation soit de cake myshell --connection=other, soit de
cake myshell --connection other, ou soit de cake myshell -c other lors de lappel au
shell. Vous pouvez aussi crer des switches de bolen, ces switches ne consomment pas de valeurs, et leur
prsence les active juste dans les paramtres parss.
$parser->addOption('no-commit', array('boolean' => true));
Avec cette option, lors de lappel dun shell comme cake myshell --no-commit something le
paramtre no-commit aurait une valeur true, et something serait trait comme un argument de position.
Les options intgres --help, --verbose, et --quiet utilisent cette fonctionnalit.
Lors de la cration doptions, vous pouvez utiliser les options suivantes pour dfinir le comportement de
loption :
short - La variante de la lettre unique pour cette option, laissez non dfinie pour nen avoir aucun.
help - Le texte daide pour cette option. Utilis lors de la gnration daide pour loption.
default - La valeur par dfaut pour cette option. Si elle nest pas dfinie, la valeur par dfaut sera true.
boolean - Loption nutilise aucune valeur, cest juste un switch de bolen. Par dfaut false.
choices Un tableau de choix valides pour cette option. Si elle est vide, toutes les valeurs sont valides.
Une exception sera lance lorsque parse() rencontre une valeur non valide.
ConsoleOptionParser::addOptions(array $options)
Si vous avez un tableau avec plusieurs options, vous pouvez utiliser $parser->addOptions() pour
ajouter plusieurs options en une fois.
819
$parser->addOptions(array(
'node', array('short' => 'n', 'help' => 'The node to create'),
'parent' => array('short' => 'p', 'help' => 'The parent node')
));
Comme avec toutes les mthodes de construcion de ConsoleOptionParser, addOptions peut tre utilise
comme une partie de la chane de mthode courante.
Loption suivante fera que $this->params[verbose] sera toujours disponible. Cela vous permet
doublier empty() ou isset() pour vrifier les flags de bolens :
if ($this->params['verbose']) {
// faire quelque chose
}
// Depuis 2.7
if ($this->param('verbose')) {
// faire quelque chose
}
Puisque les options bolennes sont toujours dfinies true ou false, vous pouvez omettre les mthodes
de vrification supplmentaires.
820
Les applications de Console sont souvent faites de sous-commandes, et ces sous-commandes ncessiteront
un parsing doptions spciales et ont leur propre aide. Un exemple parfait de cela est bake. Bake est fait de
plusieurs tches spares qui ont toutes leur propre aide et options. ConsoleOptionParser vous permet
de dfinir les sous-commandes et de fournir les parsers doption spcifiques donc le shell sait comment
parser les commandes pour ses tches :
$parser->addSubcommand('model', array(
'help' => 'Bake a model',
'parser' => $this->Model->getOptionParser()
));
Ce qui est au-dessus est un exemple de la faon dont vous pouvez fournir de laide et un parser doption
spcialis pour une tche du shell. En appelant le getOptionParser() de la tche, nous navons pas
dupliquer la gnration du parser doption, ou mixer les tches concerns dans notre shell. Ajoutez des souscommandes de cette faon a deux avantages. Premirement, cela laisse votre shell documenter facilement
ces sous-commandes dans laide gnre, et cela vous permet aussi un accs facile laide de la souscommande. Avec la sous-commande cre ci-dessus, vous pouvez appeler cake myshell --help et
regarder la liste des sous-commandes, et aussi lancer cake myshell model --help pour voir laide
uniquement pour la tche model.
Quand vous dfinissez une sous-commande, vous pouvez utiliser les options suivantes :
help - Le texte daide pour la sous-commande.
parser - Un ConsoleOptionParser pour la sous-commande. Cela vous permet de crer des mthodes de parsers doptions spcifiques. Quand laide est gnre pour une sous-commande, si un parser
est prsent, il sera utilis. Vous pouvez aussi fournir le parser en tableau qui est compatible avec
ConsoleOptionParser::buildFromArray()
Ajouter des sous-commandes peut tre fait comme une partie de la chane de mthode courante.
821
A lintrieur du parser spec, vous pouvez dfinir les cls pour arguments, options, description
et epilog. Vous ne pouvez pas dfinir les sous-commandes dans un constructeur de
type tableau. Les valeurs pour les arguments, et les options, doivent suivre le format que
ConsoleOptionParser::addArguments() et ConsoleOptionParser::addOptions()
utilisent. Vous pouvez aussi utiliser buildFromArray lui-mme, pour construire un parser doption :
public function getOptionParser() {
return ConsoleOptionParser::buildFromArray(array(
'description' => array(
__("Use this command to grant ACL permissions. Once executed, the ARO "),
__("specified (and its children, if any) will have ALLOW access to the"),
__("specified ACO action (and the ACO's children, if any).")
),
'arguments' => array(
'aro' => array('help' => __('ARO to check.'), 'required' => true),
'aco' => array('help' => __('ACO to check.'), 'required' => true),
'action' => array('help' => __('Action to check'))
)
));
}
Les deux gnreraient laide pour bake. Si le shell supporte les sous-commandes, vous pouvez obtenir de
laide pour ceux-l dun faon similaire :
cake bake model --help
cake bake model -h
Les commandes ci-dessus vont retourner un document XML contenant de laide propos des options, arguments et sous-commandes du shell selectionn. Voici un exemple de documentation :
822
<?xml version="1.0"?>
<shell>
<command>bake fixture</command>
<description>Generate fixtures for use with the test suite. You can use
`bake fixture all` to bake all fixtures.</description>
<epilog>Omitting all arguments and options will enter into an interactive mode.</epilog
<subcommands/>
<options>
<option name="--help" short="-h" boolean="1">
<default/>
<choices/>
</option>
<option name="--verbose" short="-v" boolean="1">
<default/>
<choices/>
</option>
<option name="--quiet" short="-q" boolean="1">
<default/>
<choices/>
</option>
<option name="--count" short="-n" boolean="">
<default>10</default>
<choices/>
</option>
<option name="--connection" short="-c" boolean="">
<default>default</default>
<choices/>
</option>
<option name="--plugin" short="-p" boolean="">
<default/>
<choices/>
</option>
<option name="--records" short="-r" boolean="1">
<default/>
<choices/>
</option>
</options>
<arguments>
<argument name="name" help="Name of the fixture to bake.
Can use Plugin.name to bake plugin fixtures." required="">
<choices/>
</argument>
</arguments>
</shell>
823
tenir lhte par dfaut http://localhost/ et cela va entrainer des URLs invalides. Dans ce cas,
vous devrez spcifier le domaine manuellement. Vous pouvez faire cela en utilisant la valeur de Configure App.fullBaseURL de votre bootstrap ou config, par exemple.
Pour envoyer des emails, vous devrez fournir la classe CakeEmail lhte avec lequel vous souhaitez envoyer lemail en faisant :
$Email = new CakeEmail();
$Email->domain('www.example.org');
Cela suppose que les ID du message gnr sont valides et correspondent au domaine duquel les emails sont
envoys.
API de Shell
class AppShell
AppShell peut tre utilise comme une classe de base pour tous vos shells. Elle devrait tendre Shell,
et tre localise dans Console/Command/AppShell.php.
class Shell($stdout = null, $stderr = null, $stdin = null)
Shell est une classe de base pour tous les shells, et fournit un certain nombre de fonctions pour linteraction avec lentre de lutilisateur, sortant un texte derreurs gnres.
property Shell::$tasks
Un tableau de tches que vous voulez charger pour ce shell/task.
property Shell::$uses
Un tableau de models qui devrait tre charg pour ce shell/task.
Shell::clear()
Efface la sortie courante tant affiche.
Shell::param($name)
Rcupre la valeur dune option/paramtre. Va retourner null si le paramtre nexiste pas.
Introduit dans la version 2.7.
Shell::createFile($path, $contents)
Paramtres
$path (string) Le chemin absolu du fichier que vous voulez crer.
$contents (string) Contenus mettre dans le fichier.
Cre un fichier dans un chemin donn. Si le Shell est interactif, un avertissement sera gnr, et il sera
demand lutilisateur si ils veulent craser le fichier si il existe dj. Si la proprit interactive du
shell est false, aucune question ne sera demande et le fichier sera simplement cras.
Shell::dispatchShell()
Dispatche une commande vers un autre Shell. Similaire Controller::requestAction()
mais pour lancer les shells partir dautres shells.
Regardez Invoquer dautres shells partir de votre shell.
Shell::err($message = null, $newlines = 1)
824
Paramtres
$method (string) Le message afficher.
$newlines (integer) Le nombre de nouvelles lignes qui suivent le message.
Sort une mthode vers stderr, fonctionne de la mme manire que Shell::out()
Shell::error($title, $message = null)
Paramtres
$title (string) Titre dune erreur.
$message (string) Un message derreur en option.
Affiche un message derreurs format et sort de lapplication avec le code de statut 1.
Shell::getOptionParser()
Devrait retourner un objet ConsoleOptionParser, avec tout sous-parsers pour le shell.
Shell::hasMethod($name)
Vrifie si ce shell a une mthode appelable par le nom donn.
Shell::hasTask($task)
Vrifie si le shell a une tche avec le nom fourni.
Shell::hr($newlines = 0, $width = 63)
Paramtres
$newlines (int) Le nombre de nouvelles lignes mettre avant et la suite de la
ligne.
$width (int) La largeur de la ligne dessiner.
Cre une ligne horizontale prcde et suivie par un nombre de nouvelles lignes.
Shell::in($prompt, $options = null, $default = null)
Paramtres
$prompt (string) Le prompt afficher lutilisateur.
$options (array) Un tableau de choix valides que lutilisateur peut choisir. Choisir
une option non valide va forcer lutilisateur re-choisir.
$default (string) Loption par dfaut si il y en a une.
Cette mthode vous aide interagir avec lutilisateur, et cre des shells interactifs. Elle va retourner la
rponse des utilisateurs au prompt, et vous permet de fournir une liste doptions valides dans laquelle
lutilisateur peut choisir :
$selection = $this->in('Red or Green?', array('R', 'G'), 'R');
825
Par dfaut sur les systmes *nix, les objets ConsoleOutput ont par dfaut une sortie colore. Sur
les systmes Windows, la sortie brute est la sortie par dfaut sauf si la variable denvironnement
ANSICON est prsente.
Shell::overwrite($message = null, $newlines = 1, $size = null)
Paramtres
$message (string) Le message afficher.
$newlines (integer) Le nombre de nouvelle ligne la suite du message.
$size (integer) Le nombre doctets surcharger
Cest une mthode utile pour gnrer des progess bars ou pour viter de gnrer trop de lignes.
Attention : Vous ne pouvez pas surcharger du texte qui contient des retours la ligne.
Introduit dans la version 2.6.
Shell::runCommand($command, $argv)
Lance le Shell avec argv fourni.
Dlgue les appels aux tches et rsoud les mthodes dans la classe. Les commandes sont regardes
avec lordre suivant :
Mthode sur le shell.
Correspondance du nom de la tche.
mthode main().
Si un shell intgre une mthode main(), toute appel de mthode perdu sera envoy main() avec le
nom de la mthode originale dans argv.
Shell::shortPath($file)
Rend les chemins de fichier absolus plus faciles lire.
Shell::startup()
Dmarre le Shell et affiche le message daccueil. Permet de vrifier et de configurer avant de faire la
commande ou lexcution principale.
826
Redfinit cette mthode si vous voulez retirer linformation de bienvenue, ou sinon modifier le precommand flow.
Shell::wrapText($text, $options = array())
Entoure un block de texte. Vous permet de configurer la largeur, et dindenter un block de texte.
Paramtres
$text (string) Le text formatter.
$options (array)
width La largeur entourer. Par dfaut 72.
wordWrap Entoure seulement les espaces de mots. Par dfaut true.
indent Indente le texte avec la chane de caractre fournie. Par dfaut null.
Plus de sujets
Shell Helpers
Introduit dans la version 2.8 : Les Shell Helpers ont t ajouts dans la version 2.8.0
Les Shell Helpers vous permettent de packager du code complexe pour gnrer un affichage. Les Shell
Helpers sont accessibles et utilisables partir dun shell ou dune task :
// Affiche les donnes $data sous forme de tableau.
$this->helper('table')->output($data);
// Rcupre le helper d'un plugin.
$this->helper('Plugin.HelperName')->output($data);
Vous pouvez aussi rcuprer les instances des helpers et appeler toute mthode publique quils contiennent :
// Rcupre et utilise le helper Progress.
$progress = $this->helper('Progress');
$progress->increment(10);
$progress->draw();
Plus de sujets
827
Nous pouvons ensuite utiliser ce nouvel helper dans une de nos commandes shell en lappelant :
// Avec ### de cahque ct
$this->helper('heading')->output('a marche!');
// Avec ~~~~ de chaque ct
$this->helper('heading')->output('a marche!', '~', 4);
Helpers Intgrs
Helper Table
TableHelper aide faire des tables ASCII artistiques bien formates. Son utilisation est trs simple :
$data = array(
array('Header 1', 'Header', 'Long Header'),
array('short', 'Longish thing', 'short'),
array('Longer thing', 'short', 'Longest Value'),
);
$this->helper('table')->output($data);
// Affiche
+--------------+---------------+---------------+
| Header 1
| Header
| Long Header
|
+--------------+---------------+---------------+
| short
| Longish thing | short
|
| Longer thing | short
| Longest Value |
+--------------+---------------+---------------+
Helper Progress
ProgressHelper peut tre utilis de deux manires. Le mode le plus simple vous permet de fournir un callback
qui est invoqu jusqu ce que la progression soit finie :
$this->helper('progress')->output(function ($progress) {
// Faire le travail ici.
$progress->increment(20);
});
Vous pouvez contrler encore plus la barre de progression en fournissant les options supplmentaires :
total Le nombre total de choses dans la barre de progression. Par dfaut 100.
width La largeur de la barre de progression. Defaults to 80.
callback Le callback qui va tre appel dans une boucle pour faire avancer la barre de progression.
Un exemple de toutes les options utilisables serait :
828
$this->helper('progress')->output(array(
'total' => 10,
'width' => 20,
'callback' => function ($progress) {
$progress->increment(2);
}
));
Le helper progress peut aussi tre utilis manuellement pour incrmenter et re-rendre la barre de progression
selon les besoins :
$progress = $this->helper('Progress');
$progress->init(array(
'total' => 10,
'width' => 20,
));
$this->helper->increment(4);
$this->helper->draw();
*/5 *
*
*
* cd /full/path/to/app && Console/cake myshell myparam
*
*
*
*
* command to execute
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\----- day of week (0 - 6) (0 6 sont Dimanche Samedi,
|
|
|
|
ou utilisez les noms)
|
|
|
\---------- month (1 - 12)
|
|
\--------------- day of month (1 - 31)
|
\-------------------- hour (0 - 23)
\------------------------- min (0 - 59)
Completion du Shell
Introduit dans la version 2.5.
Travailler avec la console donne au dveloppeur beaucoup de possibilits mais devoir compltement connatre et crire ces commandes peut tre fastidieux. Spcialement lors du dveloppement de nouveaux shells
o les commandes diffrent chaque itration. Les Shells de Completion aident ce niveau-l en fournissant
une API pour crire les scripts de completion pour les shells comme like bash, zsh, fish etc...
Plus de sujets
829
Sous Commandes
Les Shell de Completion se composent dun certain nombre de sous-commandes pour permettre au
dveloppeur de crer son script de completion. Chacun pour une tape diffrente dans le processus dautocompletion.
commandes
Pour les premires tapes, les commandes sortent les Commandes de Shell disponibles, y compris le nom du
plugin quand il est valable. (Toutes les possibilits retournes, pour celle-ci et les autres sous-commandes,
sont spares par un espace.) Par exemple :
./Console/cake Completion commands
Retourne :
acl api bake command_list completion console i18n schema server test testsuite upgrade
Votre script de completion peut slectionner les commandes pertinentes de cette liste pour continuer avec.
(Pour celle-l et les sous-commandes suivantes.)
subCommands
Une fois que la commande prfre a t choisie, les subCommands apparaissent la deuxime tape et sort
la sous-commande possible pour la commande de shell donne. Par exemple :
./Console/cake Completion subcommands bake
Retourne :
controller db_config fixture model plugin project test view
options
En troisime et dernire options, les options de sortie pour une (sous) commande donne comme dfini dans
getOptionParser. (Y compris les options par dfaut hrites du Shell.) Par exemple :
./Console/cake Completion options bake
Retourne :
--help -h --verbose -v --quiet -q --connection -c --theme -t
830
Exemple de Bash
Lexemple de bash suivant provient de lauteur original :
# bash completion for CakePHP console
_cake()
{
local cur prev opts cake
COMPREPLY=()
cake="${COMP_WORDS[0]}"
cur="${COMP_WORDS[COMP_CWORD]}"
prev="${COMP_WORDS[COMP_CWORD-1]}"
if [[ "$cur" == -* ]] ; then
if [[ ${COMP_CWORD} = 1 ]] ; then
opts=$(${cake} Completion options)
elif [[ ${COMP_CWORD} = 2 ]] ; then
opts=$(${cake} Completion options "${COMP_WORDS[1]}")
else
opts=$(${cake} Completion options "${COMP_WORDS[1]}" "${COMP_WORDS[2]}")
fi
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
if [[ ${COMP_CWORD} = 1 ]] ; then
opts=$(${cake} Completion commands)
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
return 0
fi
if [[ ${COMP_CWORD} = 2 ]] ; then
opts=$(${cake} Completion subcommands $prev)
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
if [[ $COMPREPLY = "" ]] ; then
COMPREPLY=( $(compgen -df -- ${cur}) )
return 0
fi
return 0
fi
Plus de sujets
831
Sinon, vous pouvez excuter chacune de ces commandes directement depuis la ligne de commande
$
$
$
$
$
$
$
cake
cake
cake
cake
cake
cake
cake
832
bake
bake
bake
bake
bake
bake
bake
db_config
model
view
controller
project
fixture
test
Modifi dans la version 2.5 : Les fichiers Test crs par bake test incluent les appels vers PHPunits
markTestIncomplete() 1 pour attirer votre attention sur les mthodes de test vides. Avant 2.5, les tests vides
passaient sans messages.
Modifier le HTML par dfaut produit par les templates de bake
Si vous souhaitez modifier la sortie HTML par dfaut produite par la commande bake, suivez les tapes
simples suivantes :
Pour fabriquer des vues sur mesure
Note :
Vous devez lancer la tche du projet spcifique cake bake project afin que le paramtre du chemin
soit pass.
Le chemin du template est relatif au chemin courant de lInterface de Commande en Ligne.
Puisque le chemin complet du squelette doit tre entr manuellement, vous pouvez spcifier nimporte
quel dossier avec le template que vous souhaitez construire, ainsi que lutilisation de plusieurs templates.
(Sauf si CakePHP commence par outrepasser le dossier squelette comme il fait pour les vues)
1. http ://phpunit.de/manual/3.7/en/incomplete-and-skipped-tests.html
Plus de sujets
833
Bakerait tous les models pour une application en une fois. De mme, cake bake controller all
bakerait tous les controllers et cake bake view all gnrerait tous les fichiers vues. Les paramtres de
834
la tche ControllerTask ont aussi chang. cake bake controller scaffold est maintenant
cake bake controller public. ViewTask a eu un drapeau -admin ajout, en utilisant -admin
cela vous autorise baker les vues pour les actions qui commencent par Routing.admin.
Comme mentionn avant cake bake fixture et cake bake test sont nouveaux, et ont plusieurs
sous-commandes chacun. cake bake fixture all va regnrer tous les fixtures basiques pour votre
application. Le paramtre -count vous autorise configurer le nombre denregistrements faux qui sont
crs. En lanant la tche de fixture de faon interactive, vous pouvez gnrer les fixtures en utilisant les
donnes dons vos tables live. Vous pouvez utiliser cake bake test <type> <class> pour crer les
cas de test pour les objets dj crs dans votre app. Le type doit tre lun des types standards de CakePHP
(component, controller, model, helper, behavior) mais peut ne pas exister. Les classes doivent tre
un objet existant dun type choisi.
Des templates en abondance
Une nouveaut dans bake pour 1.3 est lajout de plus de templates. Dans 1.2, les vues bakes utilisaient les templates qui pouvaient tre changs pour modifier les fichiers vues baks gnres. Dans
1.3, les templates sont utiliss pour gnrer toute sortie de bake gnre. Il y a des templates spars pour les controllers, les ensembles daction des controllers, les fixtures, les models, les cas de
test, et les fichiers de vue de 1.2. Comme de plus en plus de templates, vous pouvez aussi avoir
des ensembles de template multiple ou, de thmes baks. Les thmes baks peuvent tre fournis dans
votre app, ou dans une partie des plugins. Un exemple de chemin de plugin pour le thme bak
serait app/Plugin/BakeTheme/Console/Templates/dark_red/. Un thme dapp bake appel blue_bunny serait plac dans app/Console/Templates/blue_bunny. Vous pouvez regarder dans lib/Cake/Console/Templates/default/ pour voir quels rpertoires et fichiers sont
requis pour un thme bak. Cependant, comme les fichiers vues, si votre thme bak nimplmente pas un
template, les autres thmes installs seront vrifis jusqu ce que le template correct soit trouv.
Support de plugins supplmentaires.
Nouveau dans 1.3 sont les chemins supplmentaires pour spcifier les noms de plugin quand on utilise bake.
En plus de cake bake plugin Todo controller Posts, il y a deux nouvelles formes. cake
bake controller Todo.Posts et cake bake controller Posts --plugin Todo. Le
paramtre de plugin peut aussi exister en utilisant le bake interactif. cake bake controller
--plugin Todo, par exemple vous autorisera utiliser le bake interactif pour ajouter des controllers
votre plugin Todo. Des chemins de plugin supplmentaires / multiples sont aussi supports. Dans le pass,
bake ncessitait que le plugin soit dans app/plugins. Dans 1.3, bake trouvera le chemin du plugin pour le
plugin nomm, et y ajoutera les fichiers.
Plus de sujets
835
filename.sql est le nom souhait pour le fichier contenant le dump sql. Si vous omettez filename.sql, le dump
sql sera affich sur la console, mais ne sera pas crit dans un fichier.
callbacks de CakeSchema
Aprs avoir gnr un schema, vous voudrez peut-tre insrer des donnes de dpart des tables de votre
application. Ceci peut tre accompli avec les callbacks de CakeSchema. Chaque fichier de schema est gnr
avec les mthodes before($event = array()) et after($event = array()).
Le paramtre $event contient un tableau avec deux cls. Une pour dire si une table a t supprime ou
cre et une autre pour les erreurs. Exemples :
array('drop' => 'posts', 'errors' => null)
array('create' => 'posts', 'errors' => null)
Ajouter des donnes une table posts par exemple donnerait ceci :
App::uses('Post', 'Model');
public function after($event = array()) {
if (isset($event['create'])) {
switch ($event['create']) {
case 'posts':
App::uses('ClassRegistry', 'Utility');
$post = ClassRegistry::init('Post');
$post->create();
$post->save(
array('Post' =>
array('title' => 'CakePHP Schema Files')
)
);
break;
836
}
}
}
Les callbacks before() et after() se lancent chaque fois quune table est cre ou supprime sur le
schema courant.
Quand vous insrez des donnes plus dune table, vous devrez faire un flush du cache de la base de donnes
aprs la cration de chaque table. Le Cache peut tre dsactiv en configurant $db->cacheSources =
false dans laction before().
public $connection = 'default';
public function before($event = array()) {
$db = ConnectionManager::getDataSource($this->connection);
$db->cacheSources = false;
return true;
}
Si vous utilisez les models dans vos callbacks, assurez-vous de les initialiser avec la bonne source de donnes, pour ne pas quils sexcutent sur leurs sources de donnes par dfaut :
public function before($event = array()) {
$articles = ClassRegistry::init('Articles', array(
'ds' => $this->connection
));
// Do things with articles.
}
Plus de sujets
837
/**
* ACO - Access Control Object - Quelque chose qui est
*/
public $acos = array(
'id' => array(
'type' => 'integer',
'null' => false,
'default' => null,
'length' => 10,
'key' => 'primary'
),
'parent_id' => array(
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10
),
'model' => array('type' => 'string', 'null' =>
'foreign_key' => array(
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10
),
'alias' => array('type' => 'string', 'null' =>
'lft' => array(
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10
),
'rght' => array(
'type' => 'integer',
'null' => true,
'default' => null,
'length' => 10
),
'indexes' => array('PRIMARY' => array('column'
);
souhait
true),
true),
Colonnes
Chaque colonne est encode comme un tableau associatif avec cl et valeur. Le nom du champ est la cl du
champ, la valeur est un autre tableau avec certains des attributs suivants.
Exemple de colonne
'id' => array(
'type' => 'integer',
'null' => false,
'default' => null,
'length' => 10,
838
Plus de sujets
839
La cl de Table tableParameters
tableParameters sont supports uniquement dans MySQL.
Vous pouvez utiliser tableParameters pour dfinir un ensemble de paramtres spcifiques MySQL.
engine Controle le moteur de stockage utilis pour vos tables.
charset Controle le character set utilis pour les tables.
encoding Controle lencodage utilis pour les tables.
En plus du tableParameters de MySQL, dbos implmente fieldParameters. fieldParameters
vous permet de contrler les paramtres spcifiques MySQL par colonne.
charset Dfinit le character set utilis pour une colonne
encoding Dfinit lencodage utilis pour une colonne
Regardez ci-dessous pour des exemples sur la faon dutiliser les paramtres de table et de champ dans vos
fichiers de schema.
Utilisation de tableParameters dans les fichiers de schema
Vous utilisez tableParameters comme vous le feriez avec toute autre cl dans un fichier de schema.
Un peu comme les indexes :
var $comments => array(
'id' => array(
'type' => 'integer',
'null' => false,
'default' => 0,
'key' => 'primary'
),
'post_id' => array('type' => 'integer', 'null' => false, 'default' => 0),
'comment' => array('type' => 'text'),
'indexes' => array(
'PRIMARY' => array('column' => 'id', 'unique' => true),
'post_id' => array('column' => 'post_id'),
),
'tableParameters' => array(
'engine' => 'InnoDB',
'charset' => 'latin1',
'collate' => 'latin1_general_ci'
)
);
est un exemple dune table utilisant tableParameters pour dfinir quelques paramtres spcifiques de
base de donnes. Si vous utilisez un fichier de schema qui contient des options et des fonctionnalits que
votre base de donnes nintgre pas, ces options seront ignores.
Migrations avec le shell schema de CakePHP
Les migrations permettent de versionner votre schma de base de donnes, de telle faon que lorsque
vous dveloppez des fonctionnalits, vous avez une mthode facile et lgante pour relever les modifications
apportes votre base. Les migrations sont ralises soit grce aux fichiers de schmas, soit grce aux vues
instantanes. Versionner un fichier de schma avec le shell schema est assez facile. Si vous avez dj un
fichier schema cr en utilisant
840
Choisir [s] (snapshot - vue instantane) va crer un fichier schema.php incrment. Ainsi, si vous avez
schema.php, cela va crer schema_2.php et ainsi de suite. Vous pouvez ensuite restaurer chacun de ces
schmas en utilisant
$ cake schema update -s 2
O 2 est le numro de la vue instantane que vous voulez excuter. Le shell vous demandera de confirmer
votre intention dexcuter les dfinitions ALTER qui reprsentent les diffrences entre la base existante et le
fichier de schma excut ce moment.
Vous pouvez effectuer un lancement dessai (dry run) en ajoutant --dry votre commande.
Exemple dapplication
Crer un schma et committer
Sur un projet qui utilise le versioning, lutilisation du schema cake suivrait les tapes suivantes :
1. Crer ou modifier les tables de votre base de donnes.
2. Excuter cake schema pour exporter une description complte de votre base de donnes.
3. Committer et crer ou modifier le fichier schema.php :
$ # Une fois que votre base de donnes a t mise jour
$ Console/cake schema generate
$ git commit -a
Note : Si le projet nest pas versionn, la gestion des schmas se fera travers des vues instantanes. (voir
la section prcdente pour grer les vues instantanes)
Quand vous rcuprez les derniers changements de votre rpertoire, et dcouvrez des changements dans la
structure de la base de donnes (par exemple vous avez un message derreur disant quil manque une table) :
1. Excuter cake schema pour mettre jour votre base de donnes :
Plus de sujets
841
$ git pull
$ Console/cake schema create
$ Console/cake schema update
Si un moment donn vous avez besoin de revenir en arrire et de retourner un tat prcdent votre
dernire mise jour, vous devez tre inform que ce nest pas pour linstant pas possible avec cake schema.
Plus prcisment, vous ne pouvez pas supprimer automatiquement vos tables une fois quelles ont t cres.
Lutilisation de update supprimera, au contraire, nimporte quel champ qui diffrera de votre fichier
schema :
$ git revert HEAD
$ Console/cake schema update
The following statements will run. (Les requtes suivantes vont tre excutes)
ALTER TABLE `roles`
DROP `position`;
Are you sure you want to alter the tables? (y/n) (tes vous sur de vouloir modifier les tab
[n] >
Shell I18N
La fonctionnalit i18n de CakePHP utilise les fichiers po 2 comme source de traduction. Cela les rend faciles
intgrer avec des outils tels que poedit 3 ou dautres outils habituels de traduction.
Le Shell de i18n fournit une faon rapide et simple de gnrer les fichiers template po. Les fichiers templates
peuvent tre donns aux traducteurs afin quils traduisent les chanes de caractres dans votre application.
Une fois que votre traduction est fate, les fichiers pot peuvent tre fusionns avec les traductions existantes
pour aider la mise jour de vos traductions.
Gnrer les fichiers POT
Les fichiers POT peuvent tre gnrs pour une application existante en utilisant la commande extract.
Cette commande va scanner toutes les fonctions de type __() de lensemble de votre application, et extraire
les chanes de caractres. Chaque chane unique dans votre application sera combine en un seul fichier
POT :
2. http ://en.wikipedia.org/wiki/GNU_gettext
3. http ://www.poedit.net/
842
La commande du dessus va lancer le shell dextraction. En plus de lextraction des chanes de caractres
des mthodes __(), les messages de validation des models vont aussi tre extraits. Le rsultat de cette
commande va tre la cration du fichier app/Locale/default.pot. Vous utilisez le fichier pot comme
un template pour crer les fichiers po. Si vous crez manuellement les fichiers po partir du fichier pot,
pensez bien corriger le Plural-Forms de la ligne den-tte.
Gnrer les fichiers POT pour les plugins
Cela gnrera les fichiers POT requis utiliss dans les plugins.
Messages de Validation de Model
Vous pouvez dfinir le domaine utiliser pour les messages de validation extraits dans vos models. Si le
model a toujours une proprit $validationDomain, le domaine de validation donne va tre ignor :
./Console/cake i18n extract --validation-domain validation_errors
Vous pouvez aussi viter que le shell nextraie des messages de validation :
./Console/cake i18n extract --ignore-model-validation
Vous pouvez passer une liste de dossiers spare par une virgule que vous souhaitez exclure. Tout chemin
contenant une partie de chemin avec les valeurs fournies sera ignor :
./Console/cake i18n extract --exclude Test,Vendor
Plus de sujets
843
Shell ACL
Le Shell Acl est utile pour grer et inspecter les enregistrements de vos bases de donnes Acl. Il est souvent
plus pratique que lajout de modifications ponctuelles dans les controllers.
La plupart des sous-commandes shell acl implique le rfrencement des noeuds aco/aro. Comme il y a deux
formes de ces noeuds, il existe deux notations dans le shell :
# Un Model + rfrence de la cl trangre
./Console/cake acl view aro Model.1
# Un chemin alias de rfrence
./Console/cake acl view aco root/controllers
Utiliser . indique que vous allez utiliser une rfrence denregistrement lie au style, tandis quutiliser un /
indique un chemin alias.
Installer les tables de la base de donnes
Avant dutiliser la base de donnes ACL, vous aurez besoin de configurer les tables. Vous pouvez le faire en
utilisant :
./Console/cake acl initdb
844
Cette commande cre un enregistrement aco en utilisant un chemin alias. Vous pouvez aussi faire comme ce
qui suit :
./Console/cake acl create aro Group.1
La commande ci-dessus accorde tous les privilges. Vous pouvez naccorder que les privilges de lecture en
utilisant la commande suivante :
./Console/cake acl grant Group.1 controllers/Posts read
Refuser une permission fonctionne exactement de la mme faon. La seule diffrence est le remplacement
de grant en deny.
Vrification des permissions
Utilisez cette commande pour accorder les permissions ACL.
./Console/cake acl check Group.1 controllers/Posts read
Plus de sujets
845
Shell Testsuite
Une fois que vous avez commenc crire des Tests, vous pouvez les lancer en utilisant le shell testsuite.
Pour plus dinformations sur les utilisations classiques du shell testsuite, allez voir Lancer les tests partir
dune ligne de commande.
Modifi dans la version 2.1 : Le shell testa t ajout dans 2.1. Le shell
testsuite 2.0 est toujours disponible mais la nouvelle syntaxe est prfre.
Si vous voulez voir ce que le shell va faire sans modifier les fichiers, fates dabord une excution blanc
avec dry-run :
./Console/cake upgrade all --dry-run
Il est aussi possible de lancer chaque mise jour individuellement. Pour voir toutes les tapes possibles,
lancez la commande :
./Console/cake upgrade --help
4. http ://api.cakephp.org/2.4/class-UpgradeShell.html
846
La premire tape est de tlcharger (ou de faire git clone) la nouvelle version de CakePHP dans un
autre dossier en dehors de votre dossier monsiteweb, que nous appellerons cakephp. Nous ne souhaitons
pas que le dossier tlcharg app crase votre dossier app. Maintenant, il est grand temps de faire une
sauvegarde de votre dossier app, par exemple :cp -R app app-backup.
Copiez le dossier cakephp/lib dans votre dossier monsiteweb/lib pour mettre jour la nouvelle
version de CakePHP dans votre app, par exemple : cp -R ../cakephp/lib .. Symlinking est aussi
une bonne alternative pour copier, par exemple. : ln -s /var/www/cakephp/lib.
Avant de lancer notre shell de mise jour, nous avons aussi besoin des nouveaux scripts de console.
Copiez le dossier cakephp/app/Console dans le dossier monsiteweb/app, exemple. : cp -R
../cakephp/app/Console ./app.
La structure de votre dossier devrait ressembler cela maintenant :
monsiteweb/
app/
Console/
app-backup/
cake/
lib/
Cake/
plugins/
vendors/
.htaccess
index.php
<<<<<-
Votre App
Dossiers Copis app/Console
Sauvegarde de votre App
1.3 Version de CakePHP
2.x Version de CakePHP
Maintenant nous pouvons lancer la mise jour shell en tapant cd puis le chemin vers votre app et en lanant
la commande :
./Console/cake upgrade all
Cela fera la plupart du travail pour mettre jour votre app vers 2.x. Vrifiez dans votre dossier app mis
jour. Si tout a lair bien, flicitez vous vous-mmes et supprimez votre dossier mywebsite/cake. Bienvenue dans la version 2.x !
Plus de sujets
847
848
CHAPITRE 10
Dveloppement
Dans cette section, nous couvrirons les diffrents aspects du dveloppement dune application CakePHP.
Les sujets tels que la Configuration, la gestion des erreurs & des exceptions, le dbugging et le test seront
couverts.
Configuration
Configurer une application CakePHP cest du gteau. Aprs avoir install CakePHP, la cration dune application web basique ncessite seulement que vous dfinissiez une configuration la base de donnes.
Il y a toutefois dautres tapes optionnelles de configuration que vous pouvez suivre afin de tirer profit de
larchitecture flexible de CakePHP. Vous pouvez facilement ajouter des fonctionnalits provenant du cur
de CakePHP, configurer des mappings URLs supplmentaires/diffrentes (routes) et dfinir des inflexions
supplmentaires/diffrentes.
{
array(
=> 'Database/Mysql',
=> false,
=> 'localhost',
=> 'cakephpuser',
=> 'c4k3roxx!',
=> 'my_cakephp_project',
=> ''
849
Le tableau de connexion $default est utilis tant quaucune autre connexion nest spcifie dans un model,
par la proprit $useDbConfig. Par exemple, si mon application a une base de donnes pr-existante,
outre celle par dfaut, je pourrais lutiliser dans mes models, en crant un nouveau tableau de connexion la
base de donnes, intitul $ancienne, identique au tableau $default, puis en initialisant la proprit public
$useDbConfig = ancienne; dans les models appropris.
Compltez les couples cl/valeur du tableau de configuration pour rpondre au mieux vos besoins.
datasource Le nom de la source de donnes pour lequel ce tableau de configuration est destin. Exemples : Database/Mysql, Database/Sqlserver, Database/Postgres, Database/Sqlite. Vous pouvez utiliser
la syntaxe de plugin pour indiquer la source de donnes du plugin utiliser.
persistent Indique si lon doit ou non utiliser une connexion persistante la base. Si vous utilisez
SQLServer, vous ne devriez pas activer les connections persistantes car cela entrane des problmes
pour diagnostiquer des crashes.
host Le nom du serveur de base de donnes (ou son adresse IP).
login Le nom dutilisateur pour ce compte.
password Le mot de passe pour ce compte.
database Le nom de la base de donnes utiliser pour cette connexion.
prefix (optionel) La chane qui prfixe le nom de chaque table dans la base de donnes. Si vos tables nont
pas de prfixe, laissez une chane vide pour cette valeur.
port (optionel) Le port TCP ou le socket Unix utilis pour se connecter au serveur.
encoding Indique quel jeu de caractres utiliser pour envoyer les instructions SQL au serveur. Ces valeurs
pour lencodage par dfaut de la base de donnes sont valables pour toutes les bases autres que DB2.
Si vous souhaitez utiliser lencodage UTF-8 avec des connexions mysql/mysqli, vous devez crire
utf8 sans le tiret.
schema Utilis dans les paramtres dune base PostgreSQL pour indiquer quel schma utiliser.
datasource Source de donnes Non-DBO utiliser, ex : ldap, twitter.
unix_socket Utilis par les pilotes qui le supportent pour connecter via les fichiers socket unix. Si vous
utilisez PostgreSQL et voulez utiliser les sockets unix, laissez la cl host vide.
ssl_key Le chemin vers le fichier de cl SSL. (Seulement support par MySQL, ncessite PHP 5.3.7+).
ssl_cert Le chemin vers le fichier de certificat SSL. (Seulement support par MySQL, ncessite PHP
5.3.7+).
ssl_ca Le chemin vers lautorit de certification SSL. (Seulement support par MySQL, ncessite PHP
5.3.7+).
settings Un tableau de cl/valeur qui doit tre envoy la base de donnes du serveur en tant que commandes SET quand la connexion est cre. Cette option est seulement supporte par Mysql, Postgres, et
Sqlserver en ce moment.
Modifi dans la version 2.4 : Les cls settings, ssl_key, ssl_cert et ssl_ca ont t ajoutes dans
2.4.
Note : Le paramtrage du prfixe est valable pour les tables, pas pour les models. Par exemple, si vous
crez une table de liaison entre vos models Apple et Flavor, vous la nommerez prefix_apples_flavors (et
non pas prefix_apples_prefix_flavors) et vous paramtrerez votre proprit prefix sur prefix_.
850
A prsent, vous aurez peut-tre envie de jeter un il aux Conventions de CakePHP. Le nommage correct de
vos tables (et de quelques colonnes en plus) peut vous rapporter quelques fonctionnalits supplmentaires et
vous viter trop de configuration. Par exemple, si vous nommer votre table big_boxes, votre model BigBox,
votre controller BigBoxesController, tout marchera ensemble automatiquement. Par convention, utilisez les
underscores, les minuscules et les formes plurielles pour les noms de vos tables - par exemple : bakers,
pastry_stores, et savory_cakes.
Configuration
851
),
'View' => array(
'/path/to/views',
'/next/path/to/views'
),
'View/Helper' => array(
'/path/to/helpers',
'/next/path/to/helpers'
),
'Console' => array(
'/path/to/consoles',
'/next/path/to/consoles'
),
'Console/Command' => array(
'/path/to/commands',
'/next/path/to/commands'
),
'Console/Command/Task' => array(
'/path/to/tasks',
'/next/path/to/tasks'
),
'Lib' => array(
'/path/to/libs',
'/next/path/to/libs'
),
'Locale' => array(
'/path/to/locales',
'/next/path/to/locales'
),
'Vendor' => array(
'/path/to/vendors',
'/next/path/to/vendors'
),
'Plugin' => array(
'/path/to/plugins',
'/next/path/to/plugins'
),
));
Note : Tout chemin de configuration supplmentaire doit tre fait en haut du bootstrap.php de votre application. Cela va assurer que les chemins sont disponibles pour le reste de votre application.
Configuration du Coeur
Chaque application dans CakePHP contient un fichier de configuration pour dterminer le comportement
interne de CakePHP. app/Config/core.php. Ce fichier est une collection de dfinitions de variables
et de constantes de la classe Configure qui dterminent comment votre application se comporte. Avant que
nous creusions ces variables particulires, vous aurez besoin dtre familier avec la classe de configuration
registry Configure de CakePHP.
852
Configuration
853
Cache.disable Quand dfini true, la mise en cache persistante est dsactive ct-site. Cela mettra toutes
les lectures/critures du Cache en chec.
Cache.check Si dfini true, active la mise en cache de la vue. Lactivation est toujours ncessaire dans les
controllers, mais cette variable permet la dtection de ces configurations.
Session Contient un tableau de configurations utiliser pour la configuration de session. La cl par dfaut
est utilise pour dfinir un preset par dfaut pour utiliser les sessions, toute configuration dclare ici
va craser les configurations de la config par dfaut.
Sous-cls
name - Le nom du cookie utiliser. Par dfaut CAKEPHP.
timeout - Le nombre de minutes de vie des sessions. Le timeout est gr par CakePHP.
cookieTimeout - Le nombre de minutes de vie des cookies de session.
checkAgent - Voulez-vous que luser agent soit vrifi quand on dmarre les sessions ? Vous
voudrez peut-tre dfinir la valeur false, quand il sagit de vieilles versions de IE, Chrome Frame
ou certains navigateurs et AJAX.
defaults - La configuration par dfaut dfinie utiliser comme base pour votre session. Il y en
a quatre intgres : php, cake, cache, database.
handler - Peut tre utilis pour activer un gestionnaire de session personnalis. Attend un tableau
de callables, qui peut tre utilis avec session_save_handler. Lutilisation de cette option va automatiquement ajouter session.save_handler au tableau ini.
autoRegenerate - Activer cette configuration allume un renouveau automatique des sessions, et des ids de session qui changent frquemment. Regardez
CakeSession::$requestCountdown.
ini - Un tableau associatif de valeurs ini supplmentaires dfinir.
Les paramtres par dfaut intgrs sont :
php - Utilise les configurations dfinies dans votre php.ini.
cake - Sauvegarde les fichiers de session dans le rpertoire /tmp de CakePHPs /tmp.
database - Utilise les sessions de base de donnes de CakePHP.
cache - Utilise la classe de Cache pour sauvegarder les sessions.
Pour dfinir un gestionnaire de session personnalis, sauvegardez le dans
app/Model/Datasource/Session/<name>.php. Assurez-vous que la classe implmente
CakeSessionHandlerInterface et de dfinir Session.handler <name>.
Pour
utiliser
les
sessions
en
base
de
donnes,
lancez
le
schma
app/Config/Schema/sessions.php en utilisant la commande de shell de cake : cake
schema create Sessions.
Security.salt Une chane au hasard est utilise dans le hashage de scurit.
Security.cipherSeed Une chane numrique au hasard (nombres seulement) est utilise pour
crypter/dcrypter les chanes.
Asset.timestamp Ajoute un timestamp de dernire modification du fichier particulier la fin des URLs des
asset fichiers (CSS, JavaScript, Image) lors de lutilisation de vos propres helpers. Valeurs valides :
(boolean) false - Ne fait rien (par dfaut). (boolean) true - Ajoute le timestamp quand debug > 0.
(string) force - Ajoute le timestamp quand debug >= 0.
Acl.classname, Acl.database Constantes utilises pour la fonctionnalit dAccess Control List de
CakePHP. Regardez le chapitre sur les Access Control Lists pour plus dinformation.
Note : La configuration de mise en Cache est aussi trouve dans core.php Nous couvrirons cela plus
tard, donc restez concentrs.
854
La classe Configure peut tre utilise pour lire et crire des paramtres de configuration du coeur la
vole. Cela peut tre spcialement pratique si vous voulez changer le paramtre de debug sur une section
limite de logique dans votre application, par exemple.
Constantes de Configuration
Alors que la plupart des options de configuration sont gres par Configure, il y a quelques constantes que
CakePHP utilise durant lexcution.
constant LOG_ERROR
Constante dError. Utilise pour diffrencier les erreurs de log et celles de debug. Actuellement PHP
supporte LOG_DEBUG.
Configuration du Cache du Coeur
CakePHP utilise deux configurations de cache en interne. _cake_model_ et _cake_core_.
_cake_core_ est utilis pour stocker les chemins de fichier et les localisations dobjet. _cake_model_
est utilis pour stocker les descriptions de schma, et sourcer les listes pour les sources de donnes. Lutilisation dun stockage de cache rapide comme APC ou MemCached est recommande pour ces configurations,
puisquelles sont lues chaque requte. Par dfaut, ces eux configurations expirent toutes les 10 secondes
quand le debug est suprieur 0.
Comme toutes les donnes de cache sont stockes dans Cache, vous pouvez effacer les donnes en utilisant
Cache::clear().
Classe Configure
class Configure
Malgr quelques petites choses configurer dans CakePHP, il est parfois utile davoir vos propres rgles de
configuration pour votre application. Dans le pass, vous aviez peut-tre dfini des valeurs de configuration
personnalises en dfinissant des variables ou des constantes dans certains fichiers. Faire cela, vous force
inclure ce fichier de configuration chaque fois que vous souhaitez utiliser ces valeurs.
La nouvelle classe Configure de CakePHP peut tre utilise pour stocker et rcupr des valeurs spcifiques
dexcution ou dapplication. Attention, cette classe vous permet de stocker tout dedans, puis de lutiliser
dans toute autre partie de votre code : une tentative vidente de casser le modle MVC avec lequel CakePHP
a t conu. Le but principal de la classe Configure est de garder les variables centralises qui peuvent
tre partages entre beaucoup dobjets. Souvenez-vous dessayer de suivre la rgle convention plutt que
configuration et vous ne casserez pas la structure MVC que nous avons mis en place.
Cette classe peut tre appele de nimporte o dans lapplication dans un contexte statique :
Configure::read('debug');
855
$key (string) La cl crire, peut utiliser une valeur de notation avec points.
$value (mixed) La valeur stocker.
Utilisez write() pour stocker les donnes dans configuration de lapplication :
Configure::write('Company.name','Pizza, Inc.');
Configure::write('Company.slogan','Pizza for your body and soul');
Note : La notation avec points utilise dans le paramtre $key peut tre utilise pour organiser vos
paramtres de configuration dans des groupes logiques.
Lexemple ci-dessus pourrait aussi tre crit en un appel unique :
Configure::write(
'Company', array('name' => 'Pizza, Inc.', 'slogan' => 'Pizza for your body and sou
);
Vous pouvez utiliser Configure::write(debug, $int) pour intervertir les modes de debug et de production la vole. Cest particulirement pratique pour les intractions AMF et SOAP
quand les informations de debug peuvent entraner des problmes de parsing.
static Configure::read($key = null)
Paramtres
$key (string) La cl lire, peut utiliser une valeur avec notation avec points
Utilise pour lire les donnes de configuration partir de lapplication. Par dfaut, la valeur de debug
de CakePHP est au plus important. Si une cl est fournie, la donne est retourne. En utilisant nos
exemples du write() ci-dessus, nous pouvons lire cette donne :
Configure::read('Company.name');
Configure::read('Company.slogan');
Configure::read('Company');
//yields:
array('name' => 'Pizza, Inc.', 'slogan' => 'Pizza for your body and soul');
Si $key est laiss null, toutes les valeurs dans Configure seront retournes. Si la valeur correspondant
la $key spcifie nexiste pas alors null sera retourn.
static Configure::consume($key)
Paramtres
$key (string) La cl lire, peut utiliser une valeur en notation avec points
Lit et supprime une cl de Configure. Cest utile quand vous voulez combiner la lecture et la suppression de valeurs en une seule opration.
static Configure::check($key)
Paramtres
$key (string) La cl vrifier.
Utilis pour vrifier si une cl/chemin existe et a une valeur non-null.
Introduit dans la version 2.3 : Configure::check() a t ajoute dans 2.3.
static Configure::delete($key)
856
Paramtres
$key (string) La cl supprimer, peut tre utilise avec une valeur en notation
avec points
Utilis pour supprimer linformation partir de la configuration de lapplication :
Configure::delete('Company.name');
static Configure::version
Retourne la version de CakePHP pour lapplication courante.
static Configure::config($name, $reader)
Paramtres
$name (string) Le nom du reader tant attach.
$reader (ConfigReaderInterface) Linstance du reader tant attache.
Attachez un reader de configuration Configure. Les readers attachs peuvent ensuite tre utiliss
pour charger les fichiers de configuration. Regardez Chargement des fichiers de configuration pour
plus dinformations sur la faon de lire les fichiers de configuration.
static Configure::configured($name = null)
Paramtres
$name (string) Le nom du reader vrifier, si null une liste de tous les readers
attachs va tre retourne.
Soit vrifie quun reader avec un nom donne est attach, soit rcupre la liste des readers attachs.
static Configure::drop($name)
Retire un objet reader connect.
Vous pouvez avoir de multiples readers attachs Configure, chacun lisant diffrents types de fichiers de
configuration, ou lisant partir de diffrents types de sources. Vous pouvez intragir avec les readers attachs
en utilisant quelques autres mthodes de Configure. Pour voir, vrifier quels alias de reader sont attachs,
vous pouvez utiliser Configure::configured() :
1. http ://php.net/parse_ini_file
Configuration
857
Vous pouvez aussi retirer les readers attachs. Configure::drop(default) retirerait lalias du
reader par dfaut. Toute tentative future pour charger les fichiers de configuration avec ce reader serait en
chec.
Les fichiers de configuration chargs fusionnent leurs donnes avec la configuration excute existante dans
Configure. Cela vous permet dcraser et dajouter de nouvelles valeurs dans la configuration existante
excute. En configurant $merge true, les valeurs ne vont pas toujours craser la configuration existante.
Crer et modifier les fichiers de configuration
static Configure::dump($key, $config = default, $keys = array())
Paramtres
$key (string) Le nom du fichier/configuration stocke crer.
$config (string) Le nom du reader avec lequel stocker les donnes.
$keys (array) La liste des cls de haut-niveau sauvegarder. Par dfaut, pour
toutes les cls.
Dverse toute ou quelques donnes de Configure dans un fichier ou un systme de stockage support par
le reader. Le format de srialisation est dcid en configurant le reader de config attach dans $config. Par
exemple, si ladaptateur default est un PhpReader, le fichier gnr sera un fichier de configuration PHP
quon pourra charger avec PhpReader
Etant donn que le reader default est une instance de PhpReader. Sauvegarder toutes les donnes de Configure dans le fichier my_config.php :
Configure::dump('my_config.php', 'default');
858
Configure::dump() peut tre utilis pour soit modifier, soit surcharger les fichiers de configuration qui
sont lisibles avec Configure::load()
Introduit dans la version 2.2 : Configure::dump() a t ajout dans 2.2.
Stocker la configuration de runtime
static Configure::store($name, $cacheConfig = default, $data = null)
Paramtres
$name (string) La cl de stockage pour le fichier de cache.
$cacheConfig (string) Le nom de la configuration de cache pour y stocker les
donnes de configuration.
$data (mixed) Soit la donne stocker, soit laisser null pour stocker toutes les
donnes dans Configure.
Vous pouvez aussi stocker les valeurs de configuration excutes pour lutilisation dans une requte future.
Depuis que configure ne se souvient seulement que des valeurs pour la requte courante, vous aurez besoin de stocker toute information de configuration modifie si vous souhaitez lutiliser dans des requtes
suivantes :
// Stocke la configuration courante dans la cl 'user_1234' dans le cache 'default'.
Configure::store('user_1234', 'default');
Les donnes de configuration stockes persistent dans la classe Cache. Cela vous permet de stocker les
informations de Configuration dans tout moteur de stockage avec lequel Cache peut parler.
Restaurer la configuration de runtime
static Configure::restore($name, $cacheConfig = default)
Paramtres
$name (string) La cl de stockage charger.
$cacheConfig (string) La configuration de cache partir de laquelle on charge les
donnes.
Une fois que vous avez stock la configuration excute, vous aurez probablement besoin de la restaurer afin
que vous puissiez y accder nouveau. Configure::restore() fait exactement cela :
// restaure la configuration excute partir du cache.
Configure::restore('user_1234', 'default');
Quand on restaure les informations de configuration, il est important de les restaurer avec la mme cl, et la
configuration de cache comme elle tait utilise pour les stocker. Les informations restaures sont fusionnes
en haut de la configuration existante excute.
Configuration
859
Avertissement : Ce ndest pas une bonne ide de nommer votre classe de configuration XmlReader
car ce nom de classe est dj utilis en interne par PHP XMLReader a
a. http ://php.net/manual/fr/book.xmlreader.php
La mthode read() du reader de config, doit retourner un tableau dinformations de configuration que la
ressource nomm $key contient.
interface ConfigReaderInterface
Dfinit linterface utilise par les classes qui lisent les donnes de configuration et les stocke dans
Configure.
ConfigReaderInterface::read($key)
Paramtres
$key (string) Le nom de la cl ou lidentifieur charger.
860
Cette mthode devrait charger/parser les donnes de configuration identifies par $key et retourner
un tableau de donnes dans le fichier.
ConfigReaderInterface::dump($key, $data)
Paramtres
$key (string) Lidentifieur dans lequel crire.
$data (array) La donne supprimer.
Cette mthode doit supprimer/stocker la donne de configuration fournie une cl identifi par $key.
Introduit dans la version 2.3 : ConfigReaderInterface::dump() a t ajoute dans 2.3.
exception ConfigureException
Lanc quand les erreurs apparaissent quand le chargement/stockage/restauration des donnes de configuration. Les implmentations de ConfigReaderInterface devraient lancer cette exception
quand elles rencontrent une erreur.
Readers de Configuration intgrs
class PhpReader
Vous permet de lire les fichiers de configuration qui sont stocks en fichiers PHP simples. Vous pouvez
lire soit les fichiers partir de votre app/Config, soit des rpertoires configs du plugin en utilisant
la syntaxe de plugin. Les fichiers doivent contenir une variable $config. Un fichier de configuration
dexemple ressemblerait cela :
$config = array(
'debug' => 0,
'Security' => array(
'salt' => 'its-secret'
),
'Exception' => array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'ExceptionRenderer',
'log' => true
)
);
ce
qui
suit
dans
Configure::load('customConfig');
class IniReader
Vous permet de lire les fichiers de configuration qui sont stocks en fichiers .ini simples. Les fichiers
ini doivent tre compatibles avec la fonction PHP parse_ini_file, et bnficie des amliorations
suivantes :
Les valeurs spares par des points sont tendues dans les tableaux.
Les valeurs de la famille des bolens comme on et off sont converties en bolens.
Un fichier ini dexemple ressemblerait cela :
Configuration
861
debug = 0
Security.salt = its-secret
[Exception]
handler = ErrorHandler::handleException
renderer = ExceptionRenderer
log = true
Le fichier ini ci-dessus aboutirait aux mmes donnes de configuration que dans lexemple PHP du
dessus. Les structures de tableau peuvent tre cres soit travers des valeurs spares de point, soit
des sections. Les sections peuvent contenir des cls spares de point pour des imbrications plus
profondes.
Configuration de Inflection
Les conventions de nommage de CakePHP peuvent tre vraiment sympas - vous pouvez nommer votre table
de base de donnes big_boxes, votre model BigBox, votre controller BigBoxesController, et tout fonctionne
ensemble automatiquement. La faon dont CakePHP sait comment lier les choses ensemble est en inflctant
les mots entre leurs formes singulire et plurielle.
Il y a des occasions (spcialement pour nos amis ne parlant pas Anglais) o vous pouvez tre dans des
situations o lInflector de CakePHP (la classe qui met au pluriel, au singulier, en CamelCase, et en
underscore) ne fonctionne pas comme vous voulez. Si CakePHP ne reconnait pas vos Foci ou Fish, vous
pouvez dire CakePHP vos cas spciaux.
Chargement dinflections personnalises Vous pouvez utiliser Inflector::rules() dans le fichier app/Config/bootstrap.php pour
charger des inflections personnalises :
Inflector::rules('singular', array(
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
'uninflected' => array('singulars'),
'irregular' => array('spins' => 'spinor')
));
ou :
Inflector::rules('plural', array('irregular' => array('phylum' => 'phyla')));
Va fusionner les rgles fournies dans les ensembles dinflection dfinies dans lib/Cake/Utility/Inflector.php,
avec les rgles ajoutes prenant le pas sur les rgles du coeur.
Bootstrapping CakePHP
Si vous avez des besoins de configuration en plus, utilisez le fichier bootstrap de CakePHP dans
app/Config/bootstrap.php. Ce fichier est excut juste aprs le bootstrapping du coeur de CakePHP.
Ce fichier est idal pour un certain nombre de tches de bootstrapping courantes :
Dfinir des fonctions commodes.
862
Routing
Routing est une fonctionnalit qui mappe les URLs aux actions du controller. Elle a t ajoute CakePHP
pour rendre les URLs belles et plus configurables et flexibles. Lutilisation du mod_rewrite de Apache nest
pas ncessaire pour utiliser les routes, mais cela rendra votre barre dadresse beaucoup plus lgante.
Le Routing dans CakePHP englobe aussi lide de routing invers, o un tableau de paramtres peut tre invers en une chane URL. En utilisant le routing invers, vous pouvez facilement reconstruire votre structure
dURL des applications sans avoir mis jour tous vos codes.
Routing
863
dans toute application. Vous pouvez accder une action directement par lURL en mettant son nom dans
la requte. Vous pouvez aussi passer des paramtres aux actions de votre controller en utilisant lURL.
// modle URL des routes par dfaut:
http://example.com/controller/action/param1/param2/param3
Le premier paramtre est utilis pour dire au routeur quelle sorte dURL vous essayez de contrler. LURL
est une chane normale dlimite par des slashes, mais peut aussi contenir une wildcard (*) ou Les Elments
de Route. Utiliser une wildcard dit au routeur que vous tes prt accepter tout argument supplmentaire
fourni. Les Routes sans un * ne matchent que le pattern template exact fourni.
Une fois que vous spcifiez une URL, vous utilisez les deux derniers paramtres de connect() pour
dire CakePHP quoi faire avec une requte une fois quelle a t matche. Le deuxime paramtre est
un tableau associatif. Les cls du tableau devraient tre appeles aprs les lments de route dans lURL,
ou les lments par dfaut : :controller, :action, et :plugin. Les valeurs dans le tableau sont
les valeurs par dfaut pour ces cls. Regardons quelques exemples simples avant que nous commencions
lutilisation le troisime paramtre de connect() :
Router::connect(
'/pages/*',
array('controller' => 'pages', 'action' => 'display')
);
864
Cette route est trouve dans le fichier routes.php distribu avec CakePHP. Cette route matche toute URL
commenant par /pages/ et il tend vers laction display() de PagesController();. La requte
/pages/products serait mapp vers PagesController->display(products).
En plus de ltoile greedy /* il y aussi la syntaxe de ltoile trailing /**. Utiliser une toile double trailing,
va capturer le reste de lURL en tant quargument unique pass. Ceci est utile quand vous voulez utilisez un
argument qui incluait un / dedans :
Router::connect(
'/pages/**',
array('controller' => 'pages', 'action' => 'show')
);
Cet exemple montre comment vous pouvez utiliser le deuxime paramtre de connect() pour dfinir les
paramtres par dfaut. Si vous construisez un site qui propose des produits pour diffrentes catgories de
clients, vous pourriez considrer la cration dune route. Cela vous permet de vous lier /government
plutt qu /pages/display/5.
Note : Bien que vous puissiez connecter des routes alternatives, les routes par dfaut vont continuer
fonctionner. Avec cette configuration, vous pouvez accder 1 contenu partir de 2 URLs diffrentes.
Regardez Dsactiver les routes par dfaut pour dsactiver les routes par dfaut, et fournir seulement les
URLs que vous dfinissez.
Une autre utilisation ordinaire pour le Router est de dfinir un alias pour un controller. Disons quau lieu
daccder notre URL rgulire /users/some_action/5, nous aimerions tre capable de laccder
avec /cooks/some_action/5. La route suivante soccupe facilement de cela :
Router::connect(
'/cooks/:action/*', array('controller' => 'users')
);
Cela dit au Router que toute URL commenant par /cooks/ devrait tre envoye au controller users.
Laction appele dpendra de la valeur du paramtre :action. En utilisant Les Elments de Route, vous
pouvez crer des routes variables, qui acceptent les entres utilisateur ou les variables. La route ci-dessus
utilise aussi ltoile greedy. Ltoile greedy indique au Router que cette route devrait accepter tout argument de position supplmentaire donn. Ces arguments seront rendus disponibles dans le tableau Arguments
Passs.
Routing
865
Quand on gnre les URLs, les routes sont aussi utilises. Utiliser array(controller =>
users, action => some_action, 5) en URL va sortir /cooks/some_action/5 si la route
ci-dessus est la premire correspondante trouve.
Par dfaut tous les paramtres nomms passs et les arguments sont extraits des URLs qui matchent ces
templates gourmands. Cependant, vous pouvez configurer comment et quels arguments nomms sont parss
en utilisant Router::connectNamed() si vous en avez besoin.
Les Elments de Route
Vous pouvez spcifier vos propres lments de route et ce faisant cela vous donne le pouvoir de dfinir des
places dans lURL o les paramtres pour les actions du controller doivent reposer. Quand une requte est
faite, les valeurs pour ces lments de route sont trouves dans $this->request->params dans le controller. Ceci est diffrent de la faon dont les paramtres sont grs, donc notez la diffrence : les paramtres
nomms (/controller/action/name :value) sont trouvs dans $this->request->params[named],
alors que la donne de llment de route personnalis est trouv dans $this->request->params.
quand vous dfinissez un lment de route personnalis, vous pouvez spcifier en option une expression
rgulire - cela dit CakePHP comment savoir si lURL est correctement forme ou non. Si vous choisissez de ne pas fournir une expression rgulire, toute expression non / sera traite comme une partie du
paramtre :
Router::connect(
'/:controller/:id',
array('action' => 'view'),
array('id' => '[0-9]+')
);
Cet exemple simple montre comment crer une manire rapide de voir les models partir de tout controller
en laborant une URL qui ressemble /controllername/:id. LURL fourni connect() spcifie deux
lments de route : :controller et :id. Llment :controller est llment de route par dfaut
de CakePHP, donc le routeur sait comment matcher et identifier les noms de controller dans les URLs. Llment :id est un lment de route personnalis, et doit tre clarifi plus loin en spcifiant une expression
rgulire correspondante dans le troisime paramtre de connect().
Note : Les Patrons utiliss pour les lments de route ne doivent pas contenir de groupes capturs. Si ils le
font, le Router ne va pas fonctionner correctement.
Une fois que cette route a t dfinie, requtant /apples/5 est la mme que celle requtant
/apples/view/5. Les deux appeleraient la mthode view() de ApplesController. A lintrieur de la
mthode view(), vous aurez besoin daccder lID pass $this->request->params[id].
Si vous avez un unique controller dans votre application et que vous ne ne voulez pas que le nom du controller apparaisse dans lURL, vous pouvez mapper tous les URLs aux actions dans votre controller. Par
exemple, pour mapper toutes les URLs aux actions du controller home, par ex avoir des URLs comme
/demo la place de /home/demo, vous pouvez faire ce qui suit :
Router::connect('/:action', array('controller' => 'home'));
866
Si vous souhaitez fournir une URL non sensible la casse, vous pouvez utiliser les modificateurs en ligne
dexpression rgulire :
Router::connect(
'/:userShortcut',
array('controller' => 'teachers', 'action' => 'profile', 1),
array('userShortcut' => '(?i:principal)')
);
Cest assez complexe, mais montre comme les routes peuvent vraiment devenir puissantes. LURL fourni
a quatre lments de route. Le premier nous est familier : cest une route par dfaut qui dit CakePHP
dattendre un nom de controller.
Ensuite, nous spcifions quelques valeurs par dfaut. Quelque soit le controller, nous voulons que laction
index() soit appele. Nous dfinissons le paramtre jour (le quatrime lment dans lURL) null pour le
marquer en option.
Finalement, nous spcifions quelques expressions rgulires qui vont matcher les annes, mois et jours sous
forme numrique. Notez que les parenthses (le groupement) ne sont pas supportes dans les expressions
rgulires. Vous pouvez toujours spcifier des alternatives, comme dessus, mais ne pas grouper avec les
parenthses.
Une fois dfinie, cette route va matcher /articles/2007/02/01, /posts/2004/11/16, grant
les requtes pour les actions index() de ses controllers respectifs, avec les paramtres de date dans
$this->request->params.
Il y a plusieurs lments de route qui ont une signification spciale dans CakePHP, et ne devraient pas tre
utiliss moins que vous souhaitiez spcifiquement la signification.
controller Utilis pour nommer le controller pour une route.
action Utilis pour nommer laction de controller pour une route.
plugin Utilis pour nommer le plugin dans lequel un controller est localis.
prefix Utilis pour Prefix de Routage.
ext Utilis pour le routing Extensions de Fichier.
Passer des Paramtres lAction
Quand vous connectez les routes en utilisant Les Elments de Route vous voudrez peut-tre que des lments
routs soient passs aux arguments la place. En utilisant le 3me argument de Router::connect(),
vous pouvez dfinir quels lments de route doivent aussi tre rendus disponibles en arguments passs :
Routing
867
// SomeController.php
public function view($articleId = null, $slug = null) {
// du code ici...
}
// routes.php
Router::connect(
'/blog/:id-:slug', // E.g. /blog/3-CakePHP_Rocks
array('controller' => 'blog', 'action' => 'view'),
array(
// order matters since this will simply map ":id" to $articleId in your action
'pass' => array('id', 'slug'),
'id' => '[0-9]+'
)
);
et maintenant, grce aux possibilits de routing invers, vous pouvez passer dans le tableau dURL comme
ci-dessous et CakePHP sait comment former lURL comme dfinie dans les routes :
// view.ctp
// cela va retourner un lien vers /blog/3-CakePHP_Rocks
echo $this->Html->link('CakePHP Rocks', array(
'controller' => 'blog',
'action' => 'view',
'id' => 3,
'slug' => 'CakePHP_Rocks'
));
La dfinition de la route ci-dessus utilise la cl named pour dfinir comment plusieurs paramtres nomms
devraient tre traites. Regardons chacune des diffrentes rgles une par une :
wibble na pas dinformation en plus. Cela signifie quil va toujours parser si il est trouv dans une URL
matchant cette route.
868
fish a un tableau de conditions, contenant la cl action. Cela signifie que fish va tre seulement pars
en paramtre nomm si laction est aussi indice.
fizz a aussi un tableau de conditions. Cependant, il contient deux controllers, cela signifie que fizz va
seulement tre pars si le controller matche un des noms dans le tableau.
buzz a une condition de type chane de caractres. Les conditions en chane sont traites comme des
fragments dexpression rgulire. Seules les valeurs pour buzz matchant le pattern vont tre parses.
Si un paramtre nomm est utilis et quil ne matche pas le critre fourni, il sera trait comme un argument
pass au lieu dun paramtre nomm.
Prefix de Routage
De nombreuses applications ncessitent une section dadministration dans laquelle les utilisateurs privilgis peuvent faire des modifications. Ceci est souvent ralis grce une URL spciale telle que
/admin/users/edit/5. Dans CakePHP, les prfixes de routage peuvent tre activs depuis le fichier
de configuration du cur en configurant les prfixes avec Routing.prefixes. Notez que les prefixes, bien que
lis au routeur sont configurs dans app/Config/core.php :
Configure::write('Routing.prefixes', array('admin'));
Dans votre controller, toute action avec le prfixe admin_ sera appele. En utilisant notre exemple des
users, accder lURL /admin/users/edit/5 devrait appeler la mthode admin_edit de notre
UsersController en passant 5 comme premier paramtre. Le fichier de vue correspondant devra tre
app/View/Users/admin\_edit.ctp.
Vous pouvez faire correspondre lURL /admin votre action admin_index du controller Pages en utilisant
la route suivante :
Vous pouvez aussi configurer le Router pour utiliser plusieurs prfixes. En ajoutant des valeurs supplmentaires dans Routing.prefixes. Si vous dfinissez :
Configure::write('Routing.prefixes', array('admin', 'manager'));
CakePHP va automatiquement gnrer les routes pour les deux prefixes admin et manager. Chaque prfixe
configur va avoir les routes gnres suivantes pour cela :
Un peu comme le routing admin, toutes les actions prfixes doivent tre prfixes avec le nom du prfixe.
Ainsi /manager/posts/add map vers PostsController::manager_add().
De plus, le prfixe courant
$this->request->prefix
sera
disponible
partir
des
mthodes
du
controller
avec
Quand on utilise les routes prfixes, il est important de se rappeler quen utilisant le helper HTML pour
construire vos liens va aider maintenir les appels prfixs. Voici comment construire le lien en utilisant le
helper HMTL :
Routing
869
// laissez un prfixe
echo $this->Html->link('View Post', array('manager' => false, 'controller' => 'posts', 'act
Inversement, si la requte active est une requte de plugin et que vous voulez crer un lien qui ne pointe pas
vers un plugin, vous pouvez faire ce qui suit :
echo $this->Html->link('New todo', array('plugin' => null, 'controller' => 'users', 'action
En dfinissant plugin => null, vous indiquez au Routeur que vous souhaitez crer un lien qui nest
pas une partie dun plugin.
Extensions de Fichier
Pour manipuler diffrentes extensions de fichier avec vos routes, vous avez besoin dune ligne supplmentaire dans votre fichier de config des routes :
Router::parseExtensions('html', 'rss');
Ceci indiquera au routeur de supprimer toutes extensions de fichiers correspondantes et ensuite danalyser
ce qui reste.
Si vous voulez crer une URL comme /page/titre-de-page.html, vous devriez crer votre route comme illustr
ci-dessous :
Router::connect(
'/page/:title',
array('controller' => 'pages', 'action' => 'view'),
array(
'pass' => array('title')
)
);
Ensuite pour crer des liens qui sadapteront aux routes, utilisez simplement :
$this->Html->link(
'Link title',
array('controller' => 'pages', 'action' => 'view', 'title' => 'super-article', 'ext' =>
);
870
Les extensions de Fichier sont utilises par RequestHandlerComponent pour faire automatiquement
le changement de vue bas sur les types de contenu. Regardez RequestHandlerComponent pour plus dinformations.
Utiliser des conditions supplmentaires de correspondance des routes
Quand vous crez des routes, vous souhaitez restreindre certaines URL bases sur des configurations requte/environnement spcifique. Un bon exemple de cela est le routing REST. Vous pouvez spcifier des conditions supplmentaires dans largument $defaults pour Router::connect(). Par dfaut, CakePHP
propose 3 conditions denvironnement, mais vous pouvez en ajouter plus en utilisant Classes de Route Personnalises. Les options intgres sont :
[type] Seulement les requtes correspondantes pour des types de contenu spcifiques.
[method] Seulement les requtes correspondantes avec des verbes HTTP spcifiques.
[server] Correspond seuelement quand $_SERVER[SERVER_NAME] correspond la valeur donne.
Nous allons fournir un exemple simple ici pour montrer comment vous pouvez utiliser loptions [method]
pour crer une route Restful personnalise :
Router::connect(
"/:controller/:id",
array("action" => "edit", "[method]" => "PUT"),
array("id" => "[0-9]+")
);
La route ci-dessus va seulement correspondre aux requtes PUT. En utilisant ces conditions, vous pouvez
crer un routing REST personnalis, ou dautres requtes de donnes dpendant dinformation.
Arguments Passs
Les arguments passs sont des arguments supplmentaires ou des segments du chemin qui sont utiliss lors
dune requte. Ils sont souvent utiliss pour transmettre des paramtres aux mthodes de vos controllers.
http://localhost/calendars/view/recent/mark
Dans lexemple ci-dessus, recent et mark tous deux des arguments passs
CalendarsController::view(). Les arguments passs sont transmis aux controllers de trois
manires. Dabord comme arguments de la mthode de laction appele, deuximement en tant accessibles
dans $this->request->params[pass] sous la forme dun tableau index numriquement.
Enfin, il y a $this->passedArgs disponible de la mme faon que la deuxime faon. Lorsque vous
utilisez des routes personnalises il est possible de forcer des paramtres particuliers comme tant des
paramtres passs galement. Voir passer des paramtres une action pour plus dinformations.
Si vous alliez visiter lURL mentionn prcdemment, et que vous aviez une action de controller qui ressemblait cela :
CalendarsController extends AppController{
public function view($arg1, $arg2) {
debug(func_get_args());
Routing
871
}
}
Note : $this->passedArgs peut aussi contenir des paramtres nomms dans un tableau mixte nomm avec
des arguments passs.
Quand vous gnrez des URLs, en utilisant un tableau de routing, vous ajoutez des arguments passs en
valeurs sans cls de type chane dans le tableau :
array('controller' => 'posts', 'action' => 'view', 5)
Paramtres Nomms
Vous pouvez nommer les paramtres et envoyer leurs valeurs en utilisant lURL. Une requte pour
/posts/view/title:first/category:general rsultera en un appel laction view() du controller PostsController. Dans cette action, vous trouverez les valeurs des paramtres title et category
dans $this->params[named]. Vous pouvez galement accder aux paramtres nomms depuis
$this->passedArgs. Dans les deux cas, vous pouvez accder aux paramtres nomms en utilisant
leur nom en index. Si les paramtres nomms sont omis, ils ne seront pas dfinis.
Quelques exemples de routes par dfaut seront plus parlants.
Note : Ce qui est pars en paramtre nomm est contrl par Router::connectNamed(). Si vos
paramtres nomms ne sont pas du routing invers, ou ne sont pas parss correctement, vous aurez besoin
dinformer Router sur eux.
872
Quelques exemples pour rsumer les routes par dfaut peuvent prouver leur aide :
URL vers le mapping de l'action du controller utilisant les routes par
dfaut:
URL: /monkeys/jump
Mapping: MonkeysController->jump();
URL: /products
Mapping: ProductsController->index();
URL: /tasks/view/45
Mapping: TasksController->view(45);
URL: /donations/view/recent/2001
Mapping: DonationsController->view('recent', '2001');
URL: /contents/view/chapter:models/section:associations
Mapping: ContentsController->view();
$this->passedArgs['chapter'] = 'models';
$this->passedArgs['section'] = 'associations';
$this->params['named']['chapter'] = 'models';
$this->params['named']['section'] = 'associations';
Lorsque lon fait des routes personnalises, un pige classique est dutiliser des paramtres nomms qui
casseront vos routes. Pour rsoudre cela vous devez informer le Router des paramtres qui sont censs tre
des paramtres nomms. Sans cette information, le Routeur est incapable de dterminer si les paramtres
nomms doivent en effet tre des paramtres nomms ou des paramtres router, et supposera par dfaut que ce sont des paramtres router. Pour connecter des paramtres nomms dans le routeur utilisez
Router::connectNamed() :
Router::connectNamed(array('chapter', 'section'));
Va sassurer que votre chapitre et les paramtres de section inversent les routes correctement.
Quand vous gnrez les URLs, en utilisant un tableau de routing, vous ajoutez les paramtres nomms en
valeurs avec les cls en chane matchant le nom :
array('controller' => 'posts', 'action' => 'view', 'chapter' => 'association')
Puisque chapter ne matche aucun lment de route dfini, il est trait en paramtre nomm.
Note : Les deux paramtres nomms et les lments de route partagent le mme espace-cl. Il est mieux
dviter de rutiliser une cl pour les deux, lment de route et paramtre nomm.
Les paramtres nomms supportent aussi lutilisation de tableaux pour gnrer et parser les URLs. La syntaxe fonctionne de faon trs similaire la syntaxe de tableau utilise pour les paramtres GET. Quand vous
gnrez les URLs, vous pouvez utiliser la syntaxe suivante :
Routing
873
$url = Router::url(array(
'controller' => 'posts',
'action' => 'index',
'filter' => array(
'published' => 1,
'frontpage' => 1
)
));
Les tableaux peuvent aussi tre imbriqus en profondeur, vous autorisant mme plus de flexibilit dans les
arguments passs :
$url = Router::url(array(
'controller' => 'posts',
'action' => 'search',
'models' => array(
'post' => array(
'order' => 'asc',
'filter' => array(
'published' => 1
)
),
'comment' => array(
'order' => 'desc',
'filter' => array(
'spam' => 0
)
),
),
'users' => array(1, 2, 3)
));
Vous finiriez avec une longue et belle URL comme ceci (entour pour une lecture facile) :
posts/search
/models[post][order]:asc/models[post][filter][published]:1
/models[comment][order]:desc/models[comment][filter][spam]:0
/users[]:1/users[]:2/users[]:3
Et le tableau rsultant qui serait pass au controller matcherait ceci que vous avez pass au routeur :
$this->passedArgs['models'] = array(
'post' => array(
'order' => 'asc',
874
Parsez seulement les paramtres par dfaut utiliss pour la pagination de CakePHP :
Router::connectNamed(false, array('default' => true));
Parsez seulement le paramtre de la page si laction courante est index et le controller est pages :
Router::connectNamed(
array('page' => array('action' => 'index', 'controller' => 'pages')),
array('default' => false, 'greedy' => false)
);
875
reset Dfinissez true pour effacer les rgles existantes et recommencer zro.
separator Changez la chane utilise pour sparer la cl & valeur dans un paramtre nomm. Par
dfaut :
Routing invers
Le routing invers est une fonctionnalit dans CakePHP qui est utilise pour vous permettre de changer
facilement votre structure dURL sans avoir modifier tout votre code. En utilisant des tableaux de routing
pour dfinir vos URLs, vous pouvez configurer les routes plus tard et les URLs gnrs vont automatiquement tre mises jour.
Si vous crez des URLs en utilisant des chanes de caractres comme :
$this->Html->link('View', '/posts/view/' . $id);
Et ensuite plus tard, vous dcidez que /posts devrait vraiment tre appel articles la place, vous devrez
aller dans toute votre application en renommant les URLs. Cependant, si vous dfinissiez votre lien comme :
$this->Html->link(
'View',
array('controller' => 'posts', 'action' => 'view', $id)
);
Ensuite quand vous dcidez de changer vos URLs, vous pouvez le faire en dfinissant une route. Cela
changerait la fois le mapping dURL entrant, ainsi que les URLs gnrs.
Quand vous utilisez les URLs en tableau, vous pouvez dfinir les paramtres chane de la requte et les
fragments de document en utilisant les cls spciales :
Router::url(array(
'controller' => 'posts',
'action' => 'index',
'?' => array('page' => 1),
'#' => 'top'
));
// va gnrer une URL comme.
/posts/index?page=1#top
Routing invers
Rediriger le routing vous permet de dlivrer des redirections ltat HTTP 30x pour les routes entrantes,
et les pointent aux diffrentes URLs. Ceci est utilis quand vous voulez informer les applications clientes
quune ressource a t dplace et que vous ne voulez pas avoir deux URLs pour le mme contenu.
Les routes de redirection sont diffrentes des routes normales puisquelles effectuent une redirection du
header actuel si une correspondance est trouve. La redirection peut survenir vers une destination dans votre
application ou une localisation en-dehors :
876
Router::redirect(
'/home/*',
array('controller' => 'posts', 'action' => 'view',
array('persist' => true) // ou array('persist'=>array('id')) pour un routing par dfaut
);
Redirige /home/* vers /posts/view et passe les paramtres vers /posts/view. Utiliser un tableau
en une destination de redirection vous permet dutiliser dautres routes pour dfinir o une chane URL
devrait tre redirige. Vous pouvez rediriger vers des localisations externes en utilisant les chanes URLs en
destination :
Router::redirect('/posts/*', 'http://google.com', array('status' => 302));
Cela redirigerait /posts/* vers http://google.com avec un tat statut HTTP 302.
Cette route crerait une instance de SlugRoute et vous permet dimplmenter la gestion de paramtre
personnalise.
Routing
877
API du Router
class Router
Le Router gre la gnration des URLs sortants, et le parsing de la requte URL entrante dans les
ensembles de paramtre que CakePHP peut dispatcher.
static Router::connect($route, $defaults = array(), $options = array())
Paramtres
$route (string) Une chane dcrivant le template de la route.
$defaults (array) Un tableau dcrivant les paramtres de la route par dfaut. Ces
paramtres seront utiliss par dfaut et peuvent fournir des paramtres de routing
qui ne sont pas dynamiques.
$options (array) Un tableau matchant les lments nomms dans la route aux expressions rgulires avec lesquels cet lment devrait correspondre. Contient aussi
des paramtres supplmentaires comme les paramtres routs doivent tre passs
dans les arguments passs, en fournissant les patterns pour les paramtres de routing et fournir le nom dune classe de routing personnalise.
Les routes ont une faon de connecter les requtes URLs aux objets dans votre application. Dans
les routes du coeur, il y a un ensemble dexpressions rgulires qui sont utilises pour matcher les
requtes aux destinations.
Exemples :
Router::connect('/:controller/:action/*');
Le premier paramtre va tre utilis comme nom de controller alors que le second est utilis en
nom daction. La syntaxe /* rend cette route greedy puisquelle ca matcher les requtes comme
/posts/index ainsi que les requtes comme /posts/edit/1/foo/bar .
Ce qui est au-dessus montre lutilisation dun paramtre de route par dfaut. Et fournit les paramtres
de routing pour une route statique.
Router::connect(
'/:lang/:controller/:action/:id',
array(),
array('id' => '[0-9]+', 'lang' => '[a-z]{3}')
);
Montre la connexion dune route avec les paramtres de route personnalis ainsi que fournit les patterns pour ces paramtres. Les patterns pour les paramtres de routing nont pas besoin de capturer
les groupes, puisque lun deux sera ajout pour chaque paramtre de route.
$options propose trois cls special. pass, persist et routeClass ont une signification spciale
dans le tableau $options.
pass est utilis pour dfinir lesquels des paramtres routs devrait tre pass dans le tableau
pass. Ajouter un paramtre pass le retirera du tableau de route rgulire. Ex. pass =>
array(slug).
persist est utilis pour dfinir lesquels des paramtres de route devrait tre automatiquement
inclus quand on gnre les nouvels URLs. Vous pouvez craser les paramtres persistentes en les
redfinissant dans une URL ou les retirer en configurant le paramtre false. Ex. persist
=> array(lang).
878
routeClass est utilis pour tendre et changer la faon dont les routes individuelles parsent les
requtes et grent le routing invers, via une classe de routing personnalise. Ex. routeClass
=> SlugRoute.
named est utilis pour configurer les paramtres nomms au niveau de la route. Cette cl utilise les
mmes options que Router::connectNamed().
static Router::redirect($route, $url, $options = array())
Paramtres
$route (string) Un template de route qui dicte quels URLs devraient tre
rediriges.
$url (mixed) Soit un tableau de routing, soit une chane URL pour la destination
du redirect.
$options (array) Un tableau doptions pour le redirect.
Connecte une nouvelle redirection de Route dans le routeur. Regardez Routing invers pour plus
dinformations.
static Router::connectNamed($named, $options = array())
Paramtres
$named (array) Une liste des paramtres nomms. Les paires de valeur cl sont
acceptes o les valeurs sont soit des chanes regex matcher, soit des tableaux.
$options (array) Permet le contrle de toutes les configurations : separator,
greedy, reset, default.
Spcifie quels paramtres nomms CakePHP devrait parss en URLs entrantes Par dfaut, CakePHP
va parser tout paramtre nomm en-dehors des URLS entrantes. Regardez Contrler les Paramtres
Nomms pour plus dinformations.
static Router::promote($which = null)
Paramtres
$which (integer) Un indice de tableau 0 reprsentant la route dplacer. Par
exemple, si 3 routes ont t ajoute, la dernire route serait 2.
Favorise une route (par dfaut, le dernier ajout) au dbut de la liste.
static Router::url($url = null, $full = false)
Paramtres
$url (mixed) Une URL relative Cake, comme /products/edit/92 ou /presidents/elect/4 ou un tableau de routing.
$full (mixed) Si (boolean) true, lURL entirement base sera prcde au rsultat. Si un tableau accepte les cls suivantes.
escape - utilis quand on fait les URLs intgres dans les chanes de requte
HTML chappes &.
full - Si true, lURL de base complte sera prcde.
Gnre une URL pour laction spcfie. Retourne une URL pointant vers une combinaison de controller et daction. $url peut tre :
Empty - la mthode trouve ladresse du controller/de laction actuel.
/ - la mthode va trouver lURL de base de lapplication.
Une combinaison de controller/action - la mthode va trouver lURL pour cela.
Il y a quelques paramtres spciaux qui peuvent changer la chane dURL finale qui est gnre :
Routing
879
base - dfini false pour retirer le chemin de base partir dURL gnre. Si votre application
nest pas le rpertoire root, ceci peut tre utilis pour gnrer les URLs qui sont cake relative. Les
URLs CakePHP relative sont ncessaires quand on utilise requestAction.
? - Prend un tableau de paramtres de chane requt.
# - Vous permet de dfinir les fragments hashs dURL.
full_base - Si true, la valeur de Router::fullBaseUrl() sera ajoute avant aux URLs
gnres.
static Router::mapResources($controller, $options = array())
Cre les routes de ressource REST pour les controller(s) donn. Regardez la section REST pour plus
dinformations.
static Router::parseExtensions($types)
Utilis dans routes.php pour dclarer quelle Extensions de Fichier de votre application supporte. En
ne fournissant aucun argument, toutes les extensions de fichiers seront supportes.
Introduit dans la version 2.1.
static Router::setExtensions($extensions, $merge = true)
Introduit dans la version 2.2.
Dfini ou ajoute des extensions valides. Pour avoir des extensions parses, vous avez toujours besoin
dappeler Router::parseExtensions().
static Router::defaultRouteClass($classname)
Dfinit la route par dfaut utiliser quand on connecte les routes dans le futur.
static Router::fullBaseUrl($url = null)
Introduit dans la version 2.4.
Rcupre ou dfinit la baseURL utilise pour la gnration dURLs. Quand vous dfinissez cette
valeur, vous devez vous assurer dinclure le nom de domaine compltement comptent en incluant le
protocole.
Dfinir les valeurs avec cette mthode va aussi mettre jour App.fullBaseUrl dans
Configure.
class CakeRoute
La classe de base pour les routes personnalises sur laquelle on se base.
CakeRoute::parse($url)
Paramtres
$url (string) La chane URL parser.
Parse une URL entrante, et gnre un tableau de paramtres requts sur lequel le Dispatcher peut agir.
Etendre cette mthode vous permet de personnaliser comment les URLs entrantes sont converties en
un tableau. Retourne false partir dune URL pour indiquer un chec de match.
CakeRoute::match($url)
Paramtres
$url (array) Le tableau de routing convertir dans une chane URL.
Tente de matcher un tableau URL. Si lURL matche les paramtres de route et les configurations,
alors retourne une chane URL gnre. Si lURL ne match pas les paramtres de route, false sera
retourn. Cette mthode gre le routing invers ou la conversion de tableaux dURL dans des chanes
URLs.
880
CakeRoute::compile()
Forcer une route compiler son expression rgulire.
Sessions
CakePHP fournit des fonctionnalits de wrapper et un ensemble doutils qui sajoutent lextension native
session de PHP. Les Sessions vous permettent didentifier les utilisateurs uniques pendant leurs requtes
et de stocker les donnes persistantes pour les utilisateurs spcifiques. Au contraire des Cookies, les donnes
de session ne sont pas disponibles du ct client. Lutilisation de $_SESSION est gnralement viter dans
CakePHP, et la place lutilisation des classes de Session est prfrable.
Session Configuration
La configuration de Session est stocke dans Configure dans la cl de top niveau Session, et un certain
nombre doptions sont disponibles :
Session.cookie - Change le nom du cookie de session.
Session.timeout - Le nombre de minutes avant que le gestionnaire de session de CakePHP ne fasse
expirer la session. Cela affecte Session.autoRegenerate (ci-dessous), et cela est gr par CakeSession.
Session.cookieTimeout - Le nombre de minutes avant que le cookie de session nexpire. Sil nest
pas dfini, il utilisera la mme valeur que Session.timeout. Cela affecte le cookie de session, et est
ger directement par PHP.
Session.checkAgent - Le user agent doit-il tre vrifi, sur chaque requte. Si le useragent ne
matche pas, la session sera dtruite.
Session.autoRegenerate - Activer cette configuration, allume automatiquement des renouvellements de sessions, et les ids de session qui changent frquemment. Activer cette valeur va utiliser
la valeur Config.countdown de la session pour garder une trace des demandes. Une fois que
le compte rebours atteint 0, lid de session sera regnr. Cest une bonne option utiliser pour
les applications qui necssitent de changer frquemment les ids de session pour des raisons de scurit. Vous pouvez contrler le nombre de requtes ncessaires pour regnrer la session en modifiant
CakeSession::$requestCountdown.
Session.defaults - Vous permet dutiliser les configurations de session intgres par dfaut comme
une base pour votre configuration de session.
Session.handler - Vous permet de dfinir un gestionnaire de session personnalis. La base de
donnes du coeur et les gestionnaires de cache de session utilisent celui-ci. Cette option remplace
Session.save dans les versions prcdentes. Regardez ci-dessous pour des informations supplmentaires sur les gestionnaires de Session.
Session.ini - Vous permet de dfinir les configurations ini de session supplmentaire pour votre
config. Ceci combin avec Session.handler remplace les fonctionnalits de gestionnaire de session
personnalis des versions prcdentes.
Session.cacheLimiter - Vous permet de dfinir les en-ttes du cache control utilises pour le
cookie de session. La valeur par dfaut est must-revalidate. Cette option a t ajoute dans 2.8.0.
CakePHP met par dfaut la configuration de session.cookie_secure true, quand votre application
est sur un protocole SSL. Si votre application utilise la fois les protocoles SSL et non-SSL, alors vous
aurez peut-tre des problmes de sessions perdues. Si vous avez besoin daccder la session sur les deux
domaines SSL et non-SSL, vous devrez dsactiver cela :
Sessions
881
Configure::write('Session', array(
'defaults' => 'php',
'ini' => array(
'session.cookie_secure' => false
)
));
Les chemins des cookies de Session sont par dfaut / dans 2.0. Pour changer cela, vous pouvez utiliser le
drapeau ini session.cookie_path vers le chemin du rpertoire de votre application :
Configure::write('Session', array(
'defaults' => 'php',
'ini' => array(
'session.cookie_path' => '/app/dir'
)
));
Si vous utilisez les configurations par dfaut de la session de php, rappelez-vous que session.gc_maxlifetime
peut surcharger la configuration de votre timeout. Par dfaut, il est 24 minutes. Changez ceci dans vos
configurations ini pour avoir des sessions plus longues :
Configure::write('Session', array(
'defaults' => 'php',
'timeout' => 2160, // 36 heures
'ini' => array(
'session.gc_maxlifetime' => 129600 // 36 heures
)
));
Le code prcdent va utiliser la configuration de session intgre dans php. Vous pourriez la modifier
compltement ou en partie en faisant ce qui suit :
Configure::write('Session', array(
'defaults' => 'php',
'cookie' => 'my_app',
'timeout' => 4320 //3 days
));
Le code prcdent surcharge le timeout et le nom du cookie pour la configuration de session php. Les
configurations intgres sont :
882
php - Sauvegarde les sessions avec les configurations standard dans votre fichier php.ini.
cake - Sauvegarde les sessions en tant que fichiers lintrieur de app/tmp/sessions. Ceci est une
bonne option lorsque les htes ne vous autorisent pas crire en dehors de votre propre dir home.
database - Utiliser les sessions de base de donnes intgres. Regardez ci-dessous pour plus dinformations.
cache - Utiliser les sessions de cache intgres. Regardez ci-dessous pour plus dinformations.
Gestionnaires de Session
Les gestionnaires de Session peuvent tre aussi dfinis dans le tableau de config de session. Quand ils
sont dfinis, ils vous permettent de mapper les multiples valeurs session_save_handler vers une
classe ou un objet que vous souhaitez utiliser pour sauvegarder la session. Il y a deux faons dutiliser le
handler. La premire est de fournir un tableau avec 5 callables. Ces callables sont ensuite appliqus
session_set_save_handler :
Configure::write('Session', array(
'userAgent' => false,
'cookie' => 'my_cookie',
'timeout' => 600,
'handler' => array(
array('Foo', 'open'),
array('Foo', 'close'),
array('Foo', 'read'),
array('Foo', 'write'),
array('Foo', 'destroy'),
array('Foo', 'gc'),
),
'ini' => array(
'cookie_secure' => 1,
'use_trans_sid' => 0
)
));
La deuxime faon consiste dfinir une cl engine. Cette cl devrait tre un nom de classe qui implmente CakeSessionHandlerInterface. Implmenter cette interface va autoriser CakeSession
mapper automatiquement les mthodes pour le gestionnaire. Les deux gestionnaires de Session du Cache du
Coeur et de la base de donnes utilisent cette mthode pour sauvegarder les sessions. Les configurations supplmentaires pour le gestionnaire doivent tre places lintrieur du tableau handler. Vous pouvez ensuite
lire ces valeurs partir de lintrieur de votre handler.
Vous pouvez aussi utiliser les gestionnaires de session partir des plugins. En configurant le moteur
avec quelque chose comme MyPlugin.PluginSessionHandler. Cela va charger et utiliser la classe
PluginSessionHandler partir de lintrieur du MyPlugin de votre application.
CakeSessionHandlerInterface
Cette interface est utilise pour tous les gestionnaires de session personnaliss lintrieur
de CakePHP, et peut tre utilise pour crer des gestionnaires de session personnalises
de lutilisateur. En implmentant simplement linterface dans votre classe et en dfinissant
Sessions
883
Session.handler.engine au nom de classe que vous avez cr. CakePHP va tenter de charger le
gestionnaire partir de lintrieur de app/Model/Datasource/Session/$classname.php.
Donc si votre nom de classe est AppSessionHandler, le fichier devrait tre
app/Model/Datasource/Session/AppSessionHandler.php.
Les sessions de la Base de Donnes
Les changements dans la configuration de session changent la faon dont vous dfinissez les sessions de base
de donnes. La plupart du temps, vous aurez seulement besoin de dfinir Session.handler.model
dans votre configuration ainsi que de choisir la base de donnes par dfaut :
Configure::write('Session', array(
'defaults' => 'database',
'handler' => array(
'model' => 'CustomSession'
)
));
Le code au-dessus va dire CakeSession dutiliser la base de donne intgre par dfaut, et spcifier quun
model appel CustomSession sera celui dlgu pour la sauvegarde dinformation de session dans la
base de donnes.
Si vous navez pas besoin dun gestionnaire de session compltement personnalisable, mais que vous avez
tout de mme besoin de stockage de session en base de donne, vous pouvez simplifier le code prcdent
comme ceci :
Configure::write('Session', array(
'defaults' => 'database'
));
Cette configuration ncessitera quune table de base de donnes soit ajoute avec au moins ces champs :
CREATE TABLE `cake_sessions` (
`id` varchar(255) NOT NULL DEFAULT '',
`data` text,
`expires` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
Vous pouvez aussi utiliser le schema dans le terminal pour crer cette table en utilisant le fichier de schema
fourni dans le squelette app par dfaut :
$ Console/cake schema create sessions
Pour utiliser les sessions bases sur le Cache, vous pouvez configurer votre config Session comme ceci
Configure::write('Session', array(
'defaults' => 'cache',
'handler' => array(
'config' => 'session'
)
));
Cela va configurer CakeSession pour utiliser la classe CacheSession dlgue pour sauvegarder les sessions. Vous pouvez utiliser la cl config qui va mettre en cache la configuration utiliser. La configuration
par dfaut de la mise en cache est default.
Sessions
885
Notre classe tend la classe intgre DatabaseSession donc nous ne devons pas dupliquer toute sa
logique et son comportement. Nous entourons chaque opration avec une opration Cache. Cela nous
permet de rcuprer les sessions de la mise en cache rapide, et nous vite de nous inquiter sur ce qui arrive
quand nous remplissons le cache. Utiliser le gestionnaire de session est aussi facile. Dans votre core.php
imitez le block de session ressemblant ce qui suit :
Configure::write('Session', array(
'defaults' => 'database',
'handler' => array(
'engine' => 'ComboSession',
'model' => 'Session',
'cache' => 'apc'
)
));
// Assurez vous d'ajouter une config de cache apc
Cache::config('apc', array('engine' => 'Apc'));
Maintenant notre application va se lancer en utilisant notre gestionnaire de session personnalis pour la
lecture & lcriture des donnes de session.
class CakeSession
886
static CakeSession::delete($key)
Quand vous avez besoin de supprimer des donnes partir de la session, vous pouvez utiliser delete :
CakeSession::delete('Config.language');
Vous devriez aussi voir la documentation sur Sessions et SessionHelper sur la faon daccder aux donnes
de Session dans le controller et la vue.
Exceptions
Les Exceptions peuvent tre utilises pour une varit dutilisations dans votre application. CakePHP utilise
les exceptions en interne pour indiquer les erreurs logiques ou les erreurs dutilisation. Toutes les exceptions
leves de CakePHP tendent CakeException, et il y a des exceptions spcifiques selon les classes/tches
qui tendent la classe de base.
CakePHP fournit aussi un nombre de classes dexceptions qui peuvent tre utilises pour les erreurs HTTP.
Regardez la section sur Exceptions intgres pour CakePHP pour plus dinformations.
Configuration de Exception
Il y a certaines cls disponibles pour configurer les exceptions :
Configure::write('Exception', array(
'handler' => 'ErrorHandler::handleException',
'renderer' => 'ExceptionRenderer',
'log' => true
));
handler - callback - Le callback pour grer les exceptions. Vous pouvez dfinir ceci pour nimporte
quel type de callback, incluant les fonctions anonymes.
Exceptions
887
renderer - string - La classe responsable du rendu des exceptions non attrapes. Si vous choisissez une
classe personnalise, vous devriez placer ce fichier pour cette classe dans app/Lib/Error. Cette classe a
besoin dimplmenter une mthode render().
log - boolean - Quand true, les exceptions + leurs stack traces seront logged CakeLog.
consoleHandler - callback - The callback used to handle exceptions, in a console context. If undefined, CakePHPs default handler will be used.
Le rendu dException par dfaut affiche une page HTML, vous pouvez personnaliser soit le gestionnaire soit
le rendu en changeant les configurations. Changer le gestionnaire, vous permet de prendre le contrle total
sur le processus de gestion dexception, tandis que changer le rendu vous permet de changer facilement la
sortie type/contenu, ainsi que dajouter une gestion dexception spcifique dans lapplication.
Introduit dans la version 2.2 : Loption Exception.consoleHandler a t ajoute dans 2.2.
Classes dException
Il y a un certain nombre de classes dexception dans CakePHP. Chaque exception remplace un message
derreur cakeError() du pass. Les Exceptions offrent une flexibilit supplmentaire dans laquelle elles
peuvent tendre et contenir de la logique. Lexception intgre va capturer toute exception non attrape et
rendre une page utile. Les Exceptions qui nutilisent pas spcifiquement un code 400, seront traites comme
une Erreur Interne du Serveur.
888
En utilisant les exceptions pour les erreurs HTTP, vous pouvez garder la fois votre code propre, et donner
les rponses compltement REST aux applications clientes et aux utilisateurs.
De plus, les exceptions de couche du framework suivantes sont disponibles, et seront lances partir de
certains components du coeur de CakePHP :
exception MissingViewException
Le fichier de vue choisi na pas pu tre trouv.
exception MissingLayoutException
Le layout choisi na pas pu tre trouv.
exception MissingHelperException
Un helper na pas pu tre trouv.
exception MissingBehaviorException
Un behavior configur na pas pu tre trouv.
exception MissingComponentException
Un component configur na pas pu tre trouv.
exception MissingTaskException
Une tche configure na pas pu tre trouve.
exception MissingShellException
La classe shell na pas pu tre trouve.
exception MissingShellMethodException
La classe de shell choisi na pas de mthode avec ce nom.
exception MissingDatabaseException
La base de donne configure nexiste pas.
exception MissingConnectionException
Une connexion un model nexiste pas.
exception MissingTableException
Une table de model est manquante du cache de CakePHP ou de la source de donnes. Aprs lajout
dune nouvelle table une source de donnes, le cache du model (trouv dans tmp/cache/models par
dfaut) devra tre retir.
exception MissingActionException
Laction du controller requt na pas pu tre trouv.
exception MissingControllerException
Le controller requt na pas pu tre trouv.
Exceptions
889
exception PrivateActionException
Accs priv laction. Soit les actions ont un accs priv/proteg/prfix par _, ou essaient daccder
aux routes prfixs de manire incorrecte.
exception CakeException
Classe dexception de base dans CakePHP. Toutes les exceptions lances par CakePHP tendront cette
classe.
Ces classes dexception tendent toutes CakeException. En tendant CakeException, vous pouvez crer
vos propres erreurs framework. Toutes les Exceptions standards que CakePHP va aussi lancer les CakeException tendues.
Introduit dans la version 2.3 : CakeBaseException a t ajoute
exception CakeBaseException
La classe dexception de base dans CakePHP. Toutes les CakeExceptions et HttpExceptions ci-dessus
tendent cette classe.
CakeBaseException::responseHeader($header = null, $value = null)
Voir CakeResponse::header().
Toutes les exceptions Http et CakePHP tendent la classe CakeBaseException, qui a une mthode pour
ajouter les en-ttes la rponse. Par exemple quand vous lancez une MethodNotAllowedException 405, le
rfc2616 dit : La rponse DOIT inclure un en-tte contenant une liste de mthodes valides pour la ressource
requte.
Exception Renderer
class ExceptionRenderer(Exception $exception)
La classe ExceptionRenderer avec laide de CakeErrorController soccupe du rendu des pages derreur pour toutes les exceptions lances par votre application.
Les vues de la page derreur sont localises dans app/View/Errors/. Pour toutes les erreurs 4xx et 5xx,
les fichiers de vue error400.ctp et error500.ctp sont utilises respectivement. Vous pouvez les
890
personnaliser selon vos besoins. Par dfaut, votre app/Layouts/default.ctp est utilis aussi pour les
pages derreur. Si par exemple, vous voulez utiliser un autre layout app/Layouts/my_error.ctp pour
vos pages derreur, alors modifiez simplement les vues derreur et ajoutez le statement $this->layout
= my_error; error400.ctp et error500.ctp.
Chaque exception de layer framework a son propre fichier de vue localis dans les templates du
coeur mais vous navez pas besoin de personnaliser les deux puisquils sont utiliss seulement pendant le dveloppement. Avec debug teint, toutes les exceptions du layer framework sont converties en
InternalErrorException.
Vous
pourriez
fournir
des
erreurs
de
bon
dveloppement,
en
crant
app/View/Errors/missing_widget.ctp. Quand on est en mode production, lerreur du
dessus serait traite comme une erreur 500. Le constructeur pour CakeException a t tendu, vous
autorisant passer des donnes hashes. Ces hashs sont interpols dans le messageTemplate, ainsi que dans
la vue qui est utilise pour reprsenter lerreur dans le mode dveloppement. Cela vous permet de crer des
exceptions de donnes riches, en fournissant plus de contexte pour vos erreurs. Vous pouvez aussi fournir
un template de message qui permet les mthodes natives __toString() pour fonctionner normalement :
class MissingWidgetException extends CakeException {
protected $_messageTemplate = 'Il semblerait que %s soit manquant.';
}
throw new MissingWidgetException(array('widget' => 'Pointy'));
Quand attrap par le gestionnaire dexception intgr, vous obtiendriez une variable $widget dans
votre template de vue derreur. De plus, si vous attrapez lexception en chane ou utilisez sa mthode
getMessage(), vous auriez Il semblerait que Pointy soit manquant.. Cela vous permet de crer facilement et rapidement vos propres erreurs de dveloppement riche, juste comme CakePHP
en interne.
Crer des codes de statut personnaliss
Vous pouvez crer des codes de statut HTTP personnaliss en changeant le code utilis quand vous crez
une exception :
2. http ://php.net/manual/en/spl.exceptions.php
Exceptions
891
Va crer un code de rponse 501, vous pouvez utiliser le code de statut HTTP que vous souhaitez. En
dveloppement, si votre exception na pas de template spcifique, et que vous utilisez un code gal ou
suprieur 500, vous verrez le template error500. Pour tout autre code derreur, vous aurez le template
error400. Si vous avez dfini un template derreur pour votre exception personnalise, ce template va
tre utilis en mode dveloppement. Si vous souhaitez votre propre gestionnaire dexception logique mme
en production, regardez la section suivante.
Vous pouvez lancer tout code que vous souhaitez lintrieur de handleException. Le code ci-dessus
afficherait simplement Oh noes ! plus le message dexception. Vous pouvez dfinir des gestionnaires
dexception comme tout type de callback, mme une fonction anonyme si vous utilisez PHP 5.3 :
892
En crant un gestionnaire dexception personnalis, vous pouvez fournir un gestionnaire derreur personnalis pour les exceptions de lapplication. Dans la mthode fournie comme un gestionnaire dexception, vous
pourriez faire comme suit :
// dans app/Lib/AppErrorHandler.php
class AppErrorHandler {
public static function handleException($error) {
if ($error instanceof MissingWidgetException) {
return self::handleMissingWidget($error);
}
// faire d'autres trucs.
}
}
Exceptions
893
Ce qui est au-dessus grerait tout exception de type MissingWidgetException, et vous permettrait de
fournir une logique daffichage/de gestionnaire personnalis pour ces applications. Les mthodes de gestion
dexception rcuprent lexception en tant gr comme leur argument.
Note : Votre rendu personnalis devrait avoir une exception comme constructeur, et implmenter une mthode de rendu. Ne pas le faire entranera des erreurs supplmentaires.
Note : Si vous utilisez un Exception.handler personnalis, cette configuration naura aucun effet. A
moins que vous le rfrenciez lintrieur de votre implmentation.
894
Vous avez 5 options intgres quand vous grez la configuration des erreurs :
handler - callback - Le callback pour la gestion des erreurs. Vous pouvez dfinir ceci nimporte quel
type, incluant des fonctions anonymes.
level - int - Le niveau derreurs qui vous interesse dans la capture. Utilisez les constantes derreur
intgres dans PHP, et bitmasks pour slctionner le niveau derreur qui vous intressent.
trace - boolean - Inclut stack traces pour les erreurs dans les fichiers de log. Les Stack traces seront
inclus dans le log aprs chaque erreur. Cest utile pour trouver o/quand les erreurs ont t faites.
consoleHandler - callback - Le callback utilis pour grer les erreurs quand vous lancez la console.
Si il nest pas dfini, les gestionnaires par dfaut de CakePHP seront utiliss.
ErrorHandler par dfaut, affiche les erreurs quand debug > 0, et les erreurs de logs quand debug = 0. Le
type derreurs capt dans les deux cas est contrl par Error.level. Le gestionnaire derreurs fatales
va tre appel indpendamment du niveau de debug ou de la configuration de Error.level, mais le
rsultat va tre diffrent, bas sur le niveau de debug.
Note : Si vous utilisez un gestionnaire derreur personnalis, le trace setting naura aucun effet, moins
que vous y fassiez rfrence dans votre fonction de gestion derreur.
Introduit dans la version 2.2 : Loption Error.consoleHandler a t ajoute dans 2.2.
Modifi dans la version 2.2 : Les Error.handler et Error.consoleHandler vont recevoir aussi
les codes derreur fatal. Le comportement par dfaut est de montrer une page derreur interne du serveur
(debug dsactiv) ou une page avec le message, fichier et la ligne (debug activ).
895
//dans app/Lib/AppError.php
class AppError {
public static function handleError($code, $description, $file = null, $line = null, $co
echo 'Il y a eu une erreur!';
}
}
Cette classe/mthode va afficher Il y a eu une erreur ! chaque fois quune erreur apparat. Depuis que
vous pouvez dfinir un gestionnaire derreur comme tout type de callback, vous pouvez utiliser une fonction
anonyme si vous utilisez PHP5.3 ou suprieur.
Il est important de se rappeler que les erreurs captes par le gestionnaire derreurs configur seront des
erreurs php, et si vous avez besoin de gestion derreurs personnalise, vous aurez probablement aussi envie
de configurer la gestion des Exceptions.
//dans app/Lib/AppError.php
class AppError {
public static function handleError($code, $description, $file = null, $line = null, $co
list(, $level) = ErrorHandler::mapErrorCode($code);
if ($level === LOG_ERR) {
// Ignore l\'erreur fatale. Cela ne va garder seulement le message d\'erreur PH
return false;
}
return ErrorHandler::handleError($code, $description, $file, $line, $context);
}
}
896
Si vous voulez garder le comportement derreur fatal par dfaut, vous pouvez appeler
ErrorHandler::handleFatalError() partir du gestionnaire personnalis.
Debugger
Le debug est une invitable et ncessaire partie de tout cycle de dveloppement. Tandis que CakePHP noffre
pas doutils qui se connectent directement avec tout IDE ou diteur, CakePHP fournit plusieurs outils pour
laide au debug et ce qui est lanc sous le capot de votre application.
Debug basique
debug(mixed $var, boolean $showHtml = null, $showFrom = true)
Paramtres
$var (mixed) Les contenus afficher. Les tableaux et objets fonctionnent bien.
$showHTML (boolean) Dfini true, pour activer lchappement. Lchappement est activ par dfaut dans 2.0 quand on sert les requtes web.
$showFrom (boolean) Montre la ligne et le fichier pour lesquels le debug() apparat.
La fonction debug() est une fonction disponible partout qui fontionne de la mme manire que la fonction
PHP print_r(). La fonction debug() vous permet de montrer les contenus dun variable de diffrentes faons.
Premirement, si vous voulez que vos donnes soient montres dune faon sympa en HTML, dfinissez le
deuxime paramtre true. La fonction affiche aussi la ligne et le fichier dont ils sont originaires par dfaut.
La sortie de cette fonction est seulement montre si la variable de debug du coeur a t dfinie une valeur
suprieure 0.
Modifi dans la version 2.1 : La sortie de debug() ressemble plus var_dump(), et utilise Debugger
en interne.
Classe Debugger
La classe debugger a t introduite avec CakePHP 1.2 et offre mme plus doptions pour obtenir les informations de debug. Elle a plusieurs fonctions qui sont appeles statiquement, et fournissent le dumping,
logging et les fonctions de gestion des erreurs.
La Classe Debugger crase la gestion des erreurs PHP par dfaut, le remplaant avec bien plus de rapports
derreurs utiles. La gestion des erreurs de Debugger est utilise par dfaut dans CakePHP. Comme pour
toutes les fonctions de debug, Configure::debug doit tre dfini une valeur suprieure 0.
Quand une erreur est leve, Debugger affiche la fois linformation de la page et fait une entre dans le
fichier error.log. Le rapport derreurs qui est gnr a les deux stack trace et un extrait de o lerreur a t
leve. Cliquez sur le type de lien Error pour revler le stack trace, et sur le lien Code pour revler les
lignes derreurs en cause.
Debugger
897
Modifi dans la version 2.1 : Dans 2.1 forward, la sortie a t modifie pour la lisibilit. Regardez
Debugger::exportVar().
Modifi dans la version 2.5.0 : Le paramtre depth a t ajout.
static Debugger::log($var, $level = 7, $depth = 3)
Cre un stack trace log dtaill au moment de linvocation. La mthode log() affiche les donnes
identiques celles faites par Debugger : :dump(), mais dans debug.log au lieu de les sortir buffer.
Notez que votre rpertoire app/tmp directory (et son contenu) doit tre ouvert en criture par le serveur
web pour que le log() fonctionne correctement.
Modifi dans la version 2.5.0 : Le paramtre depth a t ajout.
static Debugger::trace($options)
Retourne le stack trace courant. Chaque ligne des traces inclut la mthode appele, incluant chaque
fichier et ligne do est originaire lappel.
898
//Dans PostsController::index()
pr( Debugger::trace() );
//sorties
PostsController::index() - APP/Controller/DownloadsController.php, line 48
Dispatcher::_invoke() - CORE/lib/Cake/Routing/Dispatcher.php, line 265
Dispatcher::dispatch() - CORE/lib/Cake/Routing/Dispatcher.php, line 237
[main] - APP/webroot/index.php, line 84
Ci-dessus se trouve le stack trace gnr en appelant Debugger : :trace() dans une action dun controller. Lire le stack trace de bas en haut montre lordre des fonctions lances actuellement (stack
frames). Dans lexemple du dessus, index.php appel Dispatcher : :dispatch(), qui est appel in-turn
Dispatcher : :_invoke(). La mthode _invoke() appel ensuite par PostsController : :index(). Cette
information est utile quand vous travaillez avec des oprations rcursives ou des stacks profonds,
puisquil identifie les fonctions qui sont actuellement lances au moment du trace().
static Debugger::excerpt($file, $line, $context)
Rcuprer un extrait du fichier dans $path (qui est un chemin de fichier absolu), mettant en vidence
le numro de la ligne $line avec le nombre de lignes $context autour.
pr( Debugger::excerpt(ROOT.DS.LIBS.'debugger.php', 321, 2) );
Bien que cette mthode est utilise en interne, elle peut tre pratique si vous crez vos propres messages derreurs ou les logs pour les situations personnalises.
static Debugger::exportVar($var, $recursion = 0)
Convertir une variable de tout type en une chane de caractres pour lutilisation dans la sortie de
debug. Cette mthode est aussi utilise par la plupart de Debugger pour les conversions de variable en
interne, et peut aussi tre utilise dans vos propres Debuggers.
Modifi dans la version 2.1 : Cette fonction gnre une sortie diffrente dans 2.1 et suivants.
static Debugger::invoke($debugger)
Remplace le Debugger de CakePHP avec une nouvelle instance.
static Debugger::getType($var)
Rcupre le type de variable. Les objets retourneront leur nom de classe.
Introduit dans la version 2.1.
Debugger
899
Ce qui est au-dessus crit Got here dans le debug du log. Vous pouvez utiliser les logs (log entries) pour
aider les mthodes de dbug qui impliquent les redirections ou les boucles compliques. Vous pouvez aussi
utiliser CakeLog::write() pour crire les messages de log. Cette mthode peut tre appele statiquement partout dans votre application o CakeLog a t charge :
// Dans app/Config/bootstrap.php
App::uses('CakeLog', 'Log');
// N'importe o dans votre application
CakeLog::write('debug', 'Got here');
Kit de Debug
DebugKit est un plugin qui fournit un nombre de bons outils de debug. Il fournit principalement une barre
doutils dans le HTML rendu, qui fournit une plthore dinformations sur votre application et la requte
courante. Vous pouvez tlcharger DebugKit 3 sur github.
Xdebug
Si votre environnement a lextension PHP Xdebug, des erreurs fatales vont montrer des dtails de stack trace
supplmentaires de Xdebug. Plus de dtails sur Xdebug 4 .
Testing
CakePHP est fourni avec un support de test intgr comprhensible. CakePHP permet lintgration de PHPUnit 5 . En plus de toutes les fonctionnalits offertes par PHPUnit, CakePHP offre quelques fonctionnalits
supplmentaires pour faciliter le test. Cette section va couvrir linstallation de PHPUnit, comment commencer avec le Test Unitaire, et comment vous pouvez utiliser les extensions que CakePHP offre.
Installer PHPUnit
CakePHP utilise PHPUnit as its underlying test framework. PHPUnit est le standard de-facto pour le test
unitaire dans PHP. Il offre un ensemble de fonctionnalits profondes et puissantes pour sassurer que votre
code fait ce que vous pensez quil doit faire.
3. https ://github.com/cakephp/debug_kit/tree/2.2
4. https ://xdebug.org
5. http ://phpunit.de
900
Note : PHPUnit 4 nest pas compatible avec les Tests Unitaires de CakePHP.
Selon la configuration de votre systme, vous devrez lancer les commandes prcdentes avec sudo.
Note : A partir de 2.5.7, vous pouvez placer le phar directement dans votre dossier vendors ou App/Vendor.
Astuce : Toute sortie est swallowed lors de lutilisation de PHPUnit 3.6+. Ajoutez le modificateur
--debug si vous utiliser le CLI ou ajoutez &debug=1 lURL si vous utilisez le navigateur web pour
afficher la sortie.
Note : Cest une bonne ide de faire une base de donnes de test diffrente de votre base de donnes
actuelle. Cela vitera toute erreur embarrassante pouvant arriver plus tard.
Testing
901
902
Cest un exemple trs simple, mais ce sera utile pour montrer comment vous pouvez crer un cas de
test simple. Aprs avoir cr et sauvegard notre helper, nous allons crer le fichier de cas de tests dans
app/Test/Case/View/Helper/ProgressHelperTest.php. Dans ce fichier, nous allons commencer avec ce qui suit :
App::uses('Controller', 'Controller');
App::uses('View', 'View');
App::uses('ProgressHelper', 'View/Helper');
class ProgressHelperTest extends CakeTestCase {
public function setUp() {
}
public function testBar() {
}
}
Nous complterons ce squelette dans une minute. Nous avons ajout deux mthodes pour commencer. Tout
dabord setUp(). Cette mthode est appele avant chaque mthode de test dans une classe de cas de test.
Les mthodes de configuration devraient initialiser les objets souhaits pour le test, et faire toute configuration souhaite. Dans notre configuration nous ajouterons ce qui suit :
public function setUp() {
parent::setUp();
$Controller = new Controller();
$View = new View($Controller);
$this->Progress = new ProgressHelper($View);
}
Appeler la mthode parente est importante dans les cas de test, puisque CakeTestCase : :setUp() fait un
nombre de choses comme fabriquer les valeurs dans Configure et, stocker les chemins dans App.
Ensuite, nous allons remplir les mthodes de test. Nous utiliserons quelques assertions pour nous assurer
que notre code cre la sortie que nous attendions :
public function testBar() {
$result = $this->Progress->bar(90);
$this->assertContains('width: 90%', $result);
$this->assertContains('progress-bar', $result);
$result = $this->Progress->bar(33.3333333);
$this->assertContains('width: 33%', $result);
}
Le test ci-dessus est simple mais montre le bnfice potentiel de lutilisation des cas de test. Nous utilisons
assertContains() pour nous assurer que notre helper retourne une chane qui contient le contenu que
nous attendons. Si le rsultat ne contient pas le contenu attendu le test serait un chec, et saurait que notre
code est incorrect.
En utilisant les cas de test, vous pouvez facilement dcrire la relation entre un ensemble dentres connus et
leur sortie attendue. Cela vous aide tre plus confiant sur le code que vous crivez puisque vous pouvez
Testing
903
facilement vrifier que le code que vous crivez remplit les attentes et les assertions que vos tests font. De
plus, puisque les tests sont du code, ils peuvent facilement tre re-lancs ds que vous fates un changement.
Cela vite la cration de nouveaux bugs.
Si vous avez Xdebug 6 install, vous pouvez voir les rsultats de la couverture du code. La couverture du
Code est utile pour vous dire quelles parties de votre code vos tests natteignent pas. La couverture est utile
pour dterminer o vous devriez ajouter les tests dans le futur, et vous donne une mesure pour marquer la
progression de vos tests.
6. http ://xdebug.org
904
La couverture du code inline utilise les lignes vertes pour indiquer les lignes qui ont t excutes. Si vous
vous placez sur une ligne verte, une info-bulle indiquera quels tests couvre la ligne. Les lignes en rouge
nont pas t lances, et nont pas t testes par vos tests. Les lignes grises sont considres comme du
code non excut par Xdebug.
Lancer les tests partir dune ligne de commande
CakePHP fournit un shell test pour lancer les tests. Vous pouvez lancer les tests de app, core et plugin
facilement en utilisant le shell test. Il accepte aussi tous les arguments que vous vous attendez trouver sur
loutil de ligne de commande du PHPUnit normal. A partir de votre rpertoire app, vous pouvez faire ce qui
suit pour lancer les tests :
# Lancer un test de model dans app
./Console/cake test app Model/Article
# Lancer un test de component dans un plugin
./Console/cake test DebugKit Controller/Component/ToolbarComponent
# Lancer le test de la classe de configuration dans CakePHP
./Console/cake test core Core/Configure
Note : Si vous lancez des tests qui interagissent avec la session, cest gnralement une bonne ide dutiliser
loption --stderr. Cela rglera les problmes des checs de test ds aux avertissements des headers_sent.
Testing
905
Modifi dans la version 2.1 : Le shell test a t ajout dans 2.1. Le shell testsuite de 2.0 est toujours
disponible mais la nouvelle syntaxe est prfrable.
Vous pouvez aussi lancer le shell test dans le rpertoire de projet racine. Cela vous montre une liste
complte de tous les tests que vous avez actuellement. Vous pouvez ainsi choisir librement quel(s) test(s)
lancer :
# Lancer test dans le rpertoire de projet racine pour le dossier application appel app
lib/Cake/Console/cake test app
# Lancer test dans le rpertoire de projets racine pour une application dans ./myapp
lib/Cake/Console/cake test -app myapp app
Quand vous avez des cas de test plus larges, vous voulez souvent lancer un sous-ensemble de mthodes de
test quand vous essayez de travailler sur un cas unique dchec. Avec lexcuteur cli vous pouvez utiliser
une option pour filtrer les mthodes de test :
./Console/cake test core Console/ConsoleOutput --filter testWriteArray
Le paramtre filter est utilis comme une expression rgulire sensible la casse pour filtrer les mthodes
de test lancer.
Gnrer une couverture de code
Vous pouvez gnrer un rapport de couverture de code partir dune ligne de commande en utilisant les
outils de couverture de code intgrs dans PHPUnit. PHPUnit va gnrer un ensemble de fichiers en HTML
statique contenant les rsultats de la couverture. Vous pouvez gnrer une couverture pour un cas de test en
faisant ce qui suit :
./Console/cake test app Model/Article --coverage-html webroot/coverage
Cela mettra la couverture des rsultats dans le rpertoire webroot de votre application. Vous pourrez voir les
rsultats en allant http://localhost/votre_app/coverage.
Lancer les tests qui utilisent des sessions
Quand vous lancez des tests en ligne de commande qui utilisent des sessions, vous devrez inclure le flag
--stderr. Ne pas le faire ne fera pas fonctionner les sessions. PHPUnit outputs test progress to stdout par
dfaut, cela entraine le fait que PHP suppose que les headers ont t envoys ce qui empche les sessions de
dmarrer. En changeant PHPUnit pour quil output on stderr, ce problme sera vit.
906
Fixtures
Quand on teste du code qui dpend de models et dune base de donnes, on peut utiliser les fixtures comme
une faon de gnrer temporairement des tables de donnes charges avec des donnes dexemple qui peuvent tre utilises par le test. Le bnfice de lutilisation de fixtures est que votre test na aucune chance
dabimer les donnes de lapplication qui tourne. De plus, vous pouvez commencer tester votre code avant
de dvelopper rellement en live le contenu pour une application.
CakePHP utilise la connexion nomme $test dans votre fichier de configuration
app/Config/database.php Si la connexion nest pas utilisable, une exception sera leve et
vous ne serez pas capable dutiliser les fixtures de la base de donnes.
CakePHP effectue ce qui suit pendant le chemin dune fixture base sur un cas de test :
1. Cre les tables pour chacun des fixtures ncessaires.
2. Remplit les tables avec les donnes, si les donnes sont fournies dans la fixture.
3. Lance les mthodes de test.
4. Vide les tables de fixture.
5. Retire les tables de fixture de la base de donnes.
Crer les fixtures
A la cration dune fixture, vous pouvez dfinir principalement deux choses : comment la table est cre
(quels champs font partie de la table), et quels enregistrements seront remplis initialement dans la table.
Crons notre premire fixture, qui sera utilise pour tester notre propre model Article. Cre un fichier nomm
ArticleFixture.php dans votre rpertoire app/Test/Fixture avec le contenu suivant :
class ArticleFixture extends CakeTestFixture {
// Optionel
// Dfinir cette proprit pour charger les fixtures dans une source
// de donnes de test diffrente
public $useDbConfig = 'test';
public $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
Testing
907
'title' => array('type' => 'string', 'length' => 255, 'null' => false),
'body' => 'text',
'published' => array('type' => 'integer', 'default' => '0', 'null' => false),
'created' => 'datetime',
'updated' => 'datetime'
);
public $records =
array('id' =>
array('id' =>
array('id' =>
);
array(
1, 'title' => 'First Article', 'body' => 'First Article Body', 'pub
2, 'title' => 'Second Article', 'body' => 'Second Article Body', 'p
3, 'title' => 'Third Article', 'body' => 'Third Article Body', 'pub
La proprit $useDbConfig dfinit la source de donnes que la fixture va utiliser. Si votre application
utilise plusieurs sources de donnes, vous devriez faire correspondre les fixtures avec les sources de donnes
du model, mais prfix avec test_. Par exemple, si votre model utilise la source de donnes mydb, votre
fixture devra utiliser la source de donnes test_mydb. Si la connexion test_mydb nexiste pas, vos
models vont utiliser la source de donnes test par dfaut. Les sources de donnes de fixture doivent
tre prfixes par test pour rduire la possibilit de trucher accidentellement toutes les donnes de votre
application quand vous lancez des tests.
Nous utilisons $fields pour spcifier les champs qui feront partie de cette table, et comment ils sont
dfinis. Le format utilis pour dfinir ces champs est le mme quutilis avec CakeSchema. Les cls
disponibles pour la dfinition de la table sont :
type
Type de donnes interne CakePHP. Actuellement supports :
string : redirige vers VARCHAR.
text : redirige vers TEXT.
biginteger : redirige vers BIGINT.
integer : redirige vers INT.
float : redirige vers FLOAT.
decimal : redirige vers DECIMAL.
datetime : redirige vers DATETIME.
timestamp : redirige vers TIMESTAMP.
time : redirige vers TIME.
date : redirige vers DATE.
binary : redirige vers BLOB.
boolean : redirige vers TINYINT.
key Dfini primary pour que le champ soit en AUTO_INCREMENT, et une PRIMARY KEY pour la
table.
length Dfini la longueur spcifique que le champ doit prendre.
null Dfini soit true (pour permettre les NULLs) soit false (pour ne pas permettre les NULLs).
default Valeur par dfaut que le champ prend.
Nous pouvons dfinir un ensemble denregistrements qui seront remplis aprs que la table de fixture est
cre. Le format est directement fairly forward, $records est un tableau denregistrements. Chaque item
dans $records devrait tre une unique ligne. A lintrieur de chaque ligne, il devrait y avoir un tableau
associatif des colonnes et valeurs pour la ligne. Gardez juste lesprit que chaque enregistrement dans le
tableau $records doit avoir une cl pour chaque champ spcifi dans le tableau $fields. Si un champ
908
pour un enregistrement particulier a besoin davoir une valeur null, spcifiez juste la valeur de cette cl
null.
Les donnes dynamiques et les fixtures
Depuis que les enregistrements pour une fixture sont dclares en proprit de classe, vous ne pouvez pas
facilement utiliser les fonctions ou autres donnes dynamiques pour dfinir les fixtures. Pour rsoudre ce
problme, vous pouvez dfinir $records dans la fonction init() de votre fixture. Par exemple, si vous
voulez tous les timestamps crs et mis jours pour reflter la date daujourdhui, vous pouvez faire ce qui
suit :
class ArticleFixture extends CakeTestFixture {
public $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'title' => array('type' => 'string', 'length' => 255, 'null' => false),
'body' => 'text',
'published' => array('type' => 'integer', 'default' => '0', 'null' => false),
'created' => 'datetime',
'updated' => 'datetime'
);
public function init() {
$this->records = array(
array(
'id' => 1,
'title' => 'First Article',
'body' => 'First Article Body',
'published' => '1',
'created' => date('Y-m-d H:i:s'),
'updated' => date('Y-m-d H:i:s'),
),
);
parent::init();
}
}
909
Cette dclaration dit la suite test dimporter la dfinition de votre table partir de la table lie au model
appel Article. Vous pouvez utiliser tout model disponible dans votre application. La dclaration va seulement importer le schma Article, et nimporte pas denregistrements. Pour importer les enregistrements,
vous pouvez faire ce qui suit :
class ArticleFixture extends CakeTestFixture {
public $import = array('model' => 'Article', 'records' => true);
}
Si dun autre ct vous avez une table cre mais pas de model disponible pour elle, vous pouvez spcifier
que votre import se fera en lisant linformation de la table la place. Par exemple :
class ArticleFixture extends CakeTestFixture {
public $import = array('table' => 'articles');
}
Va importer la dfinition de la table partir de la table appele articles en utilisant la connexion la base
de donne CakePHP nomme default. Si vous voulez utiliser une connexion diffrente, utilisez :
class ArticleFixture extends CakeTestFixture {
public $import = array('table' => 'articles', 'connection' => 'other');
}
Puisquon utilise votre connexion la base de donnes CakePHP, sil y a un prfixe de table dclar, il sera
automatiquement utilis quand on rcupre linformation de la table. Pour forcer la fixture et aussi importer
ses enregistrements, changez limportation en
class ArticleFixture extends CakeTestFixture {
public $import = array('table' => 'articles', 'records' => true);
}
Vous pouvez naturellement importer la dfinition de votre table partir dun model/dune table existante,
mais vous avez vos enregistrements directement dfinis dans le fixture comme il a t montr dans la section
prcdente. Par exemple :
910
Ce qui est au-dessus va charger les fixtures dArticle et de Comment partir du rpertoire de fixture de
lapplication. Vous pouvez aussi charger les fixtures partir du coeur de CakePHP ou des plugins :
class ArticleTest extends CakeTestCase {
public $fixtures = array('plugin.debug_kit.article', 'core.comment');
}
Utiliser le prfixe core va charger les fixtures partir de CakePHP, et utiliser un nom de plugin en prfixe
chargera le fixture partir dun plugin nomm.
Vous
pouvez
contrler
quand
vos
fixtures
sont
chargs
en
CakeTestCase::$autoFixtures false et plus tard les charger
CakeTestCase::loadFixtures() :
configurant
en utilisant
Depuis 2.5.0, vous pouvez charger les fixtures dans les sous-rpertoires. Utiliser plusieurs rpertoires peut
faciliter lorganisation de vos fixtures si vous avez une application plus grande. Pour charger les fixtures
dans les sous-rpertoires, incluez simplement le nom du sous-rpertoire dans le nom de la fixture :
class ArticleTest extends CakeTestCase {
public $fixtures = array('app.blog/article', 'app.blog/comment');
}
Dans lexemple ci-dessus, les deux fixtures seront chargs partir de App/Test/Fixture/blog/.
Modifi dans la version 2.5 : Depuis 2.5.0 vous pouvez charger les fixtures dans des sous-rpertoires.
Testing
911
Nous voulons maintenant configurer un test qui va utiliser la dfinition du model, mais travers les fixtures,
pour tester quelques fonctionnalits dans le model. Le test suite de CakePHP charge un petit ensemble
minimum de fichiers (pour garder les tests isols), ainsi nous devons commencer par charger notre model dans ce cas le model Article que nous avons dj dfini.
Crons
maintenant
un
fichier
nomm
ArticleTest.php
app/Test/Case/Model, avec les contenus suivants :
dans
votre
rpertoire
App::uses('Article', 'Model');
class ArticleTestCase extends CakeTestCase {
public $fixtures = array('app.article');
}
Dans notre variable de cas de test $fixtures, nous dfinissons lensemble des fixtures que nous utiliserons. Vous devriez vous rappeler dinclure tous les fixtures qui vont avoir des requtes lances contre elles.
Note : Vous pouvez craser la base de donnes du model test en spcifiant la proprit $useDbConfig.
Assurez-vous que la fixture utilise la mme valeur afin que la table soit cre dans la bonne base de donnes.
912
$expected = array(
array('Article' => array('id' => 1, 'title' => 'First Article')),
array('Article' => array('id' => 2, 'title' => 'Second Article')),
array('Article' => array('id' => 3, 'title' => 'Third Article'))
);
$this->assertEquals($expected, $result);
}
}
Vous pouvez voir que nous avons ajout une mthode appele testPublished(). Nous commenons
par crer une instance de notre model Article, et lanons ensuite notre mthode published(). Dans
$expected, nous dfinissons ce que nous en attendons, ce qui devrait tre le rsultat appropri (que nous
connaissons depuis que nous avons dfini quels enregistrements sont remplis initialement dans la table articles.). Nous testons que les rsultats correspondent nos attentes en utilisant la mthode assertEquals.
Regarder la section sur les Lancer les Tests pour plus dinformations sur la faon de lancer les cas de test.
Note :
Quand vous configurez votre Model pour le test, assurez-vous dutiliser
ClassRegistry::init(YourModelName); puisquil sait comment utiliser la connexion
la base de donnes de votre test.
Testing
913
App::uses('AppController', 'Controller');
class ArticlesController extends AppController {
public $helpers = array('Form', 'Html');
public function index($short = null) {
if (!empty($this->request->data)) {
$this->Article->save($this->request->data);
}
if (!empty($short)) {
$result = $this->Article->find('all', array('id', 'title'));
} else {
$result = $this->Article->find('all');
}
if (isset($this->params['requested'])) {
return $result;
}
$this->set('title', 'Articles');
$this->set('articles', $result);
}
}
Crez
un
fichier
nomm
ArticlesControllerTest.php
app/Test/Case/Controller et mettez ce qui suit lintrieur :
dans
votre
rpertoire
914
debug($result);
}
public function testIndexPostData() {
$data = array(
'Article' => array(
'user_id' => 1,
'published' => 1,
'slug' => 'new-article',
'title' => 'New Article',
'body' => 'New Body'
)
);
$result = $this->testAction(
'/articles/index',
array('data' => $data, 'method' => 'post')
);
debug($result);
}
}
Cet exemple montre quelques faons dutiliser testAction pour tester vos controllers. Le premier paramtre
de testAction devrait toujours tre lURL que vous voulez tester. CakePHP va crer une requte et
dispatcher le controller et laction.
Quand vous testez les actions qui contiennent redirect() et dautres codes suivants le redirect, il est
gnralement bon de retourner quand il y a redirection. La raison pour cela est que redirect() est
mocked dans les tests, et nchappe pas comme la normale. Et la place de votre code existant, il va
continuer de lancer le code suivant le redirect. Par exemple :
App::uses('AppController', 'Controller');
class ArticlesController extends AppController {
public function add() {
if ($this->request->is('post')) {
if ($this->Article->save($this->request->data)) {
$this->redirect(array('action' => 'index'));
}
}
// plus de code
}
}
Quand vous testez le code ci-dessus, vous allez toujours lancer // plus de code mme si le redirect
est atteint. A la place, vous devriez crire le code comme ceci :
App::uses('AppController', 'Controller');
class ArticlesController extends AppController {
public function add() {
if ($this->request->is('post')) {
if ($this->Article->save($this->request->data)) {
return $this->redirect(array('action' => 'index'));
Testing
915
}
}
// plus de code
}
}
Dans ce cas // plus de code ne sera pas excut puisque la mthode retourne une fois que le redirect
est atteint.
Simuler les requtes GET
Comme vu dans lexemple testIndexPostData() ci-dessus, vous pouvez utiliser testAction()
pour tester les actions POST ainsi que les actions GET. En fournissant la cl data, la requte faite par le
controller sera POST. Par dfaut, toutes les requtes seront des requtes POST. Vous pouvez simuler une
requte GET en configurant la mthode cl :
public function testAdding() {
$data = array(
'Post' => array(
'title' => 'New post',
'body' => 'Secret sauce'
)
);
$this->testAction('/posts/add', array('data' => $data, 'method' => 'get'));
// some assertions.
}
La cl data sera utilise en paramtres de recherche de chanes quand on va simuler une requte GET.
Choisir le type de retour
Vous pouvez choisir plusieurs faons pour inspecter le succs de laction de votre controller. Chacun offre
une manire diffrente de sassurer que votre code fait ce que vous en attendez :
vars Rcupre lensemble des variables de vue.
view Rcupre la vue rendue, sans un layout.
contents Rcupre la vue rendue en incluant le layout.
result Rcupre la valeur de retour de laction du controller. Utile pour tester les mthodes requestAction.
La valeur par dfaut est result. Tant que votre type de retour nest pas result, vous pouvez aussi
accder aux autres types de retour en proprits dans les cas de test :
public function testIndex() {
$this->testAction('/posts/index');
$this->assertInternalType('array', $this->vars['posts']);
}
916
Ce qui est au-dessus crerait un PostsController mock, stubbing out la mthode isAuthorized.
Le model Post attach aura un save() stubbed, et les components attachs auront leurs mthodes respectives stubbed. Vous pouvez choisir de stub une classe entire en ne leur passant pas les mthodes, comme
Session dans lexemple ci-dessus.
Les controllers gnrs sont automatiquement utiliss en tant que controller de test tester. Pour activer la
gnration automatique, dfinissez la variable autoMock dans le cas de test true. Si autoMock est
false, votre controller original sera utilis dans le test.
La rponse objet dans le controller gnr est toujours remplace par un mock qui nenvoie pas les headers. Aprs utilisation de generate() ou testAction(), vous pouvez accder lobjet controller
$this->controller.
Un exemple plus complexe
Dans sa plus simple forme, testAction() lancera PostsController::index() dans votre controller de test (ou en gnrera un automatiquement), en incluant tous les models mocks et les components.
Les rsultats du test sont stocks dans les proprits vars, contents, view, et return. Une proprit
headers est aussi disponible qui vous donne accs headers qui aurait t envoye, vous permettant de
vrifier les redirects :
public function testAdd() {
$Posts = $this->generate('Posts', array(
'components' => array(
'Session',
'Email' => array('send')
)
));
$Posts->Session
Testing
917
->expects($this->once())
->method('setFlash');
$Posts->Email
->expects($this->once())
->method('send')
->will($this->returnValue(true));
$this->testAction('/posts/add', array(
'data' => array(
'Post' => array('title' => 'New Post')
)
));
$this->assertContains('/posts', $this->headers['Location']);
}
public function testAddGet() {
$this->testAction('/posts/add', array(
'method' => 'GET',
'return' => 'contents'
));
$this->assertRegExp('/<html/', $this->contents);
$this->assertRegExp('/<form/', $this->view);
}
Cet exemple montre une utilisation lgrement plus complexe des mthodes testAction() et
generate(). Tout dabord, nous gnrons un controller de test et mock le SessionComponent. Maintenant que SessionComponent est mock, nous avons la possibilit de lancer des mthodes de test dessus.
En supposant que PostsController::add() nous redirige lindex, envoie un email et dfinit un
message flash, le test va passer. Pour le bnfice de lexemple, nous vrifions aussi si le layout a t charg
en vrifiant les contenus entirement rendus, et vrifions la vue pour un tag form. Comme vous pouvez le
voir, votre libert pour tester les controllers et facilement mocker ses classes est grandement tendue avec
ces changements.
Quand vous fates des tests de controller en utilisant les mocks qui utilisent les mthodes statiques, vous
devrez utiliser une mthode diffrente pour inscrire vos attentes de mock. Par exemple si vous voulez mock
out AuthComponent::user() vous devrez faire ce qui suit :
public function testAdd() {
$Posts = $this->generate('Posts', array(
'components' => array(
'Session',
'Auth' => array('user')
)
));
$Posts->Auth->staticExpects($this->any())
->method('user')
->with('id')
->will($this->returnValue(2));
}
En utilisant staticExpects vous serez capable de mock et de manipuler les mthodes statiques sur les
components et models.
918
Testing
919
$this->Controller = $controller;
// Assurez-vous que le controller utilise la pagination
if (!isset($this->Controller->paginate)) {
$this->Controller->paginate = array();
}
}
public function adjust($length = 'short') {
switch ($length) {
case 'long':
$this->Controller->paginate['limit'] = 100;
break;
case 'medium':
$this->Controller->paginate['limit'] = 50;
break;
default:
$this->Controller->paginate['limit'] = 20;
break;
}
}
}
Maintenant nous pouvons crire des tests pour nous assurer que notre paramtre de pagination
limit est dfini correctement par la mthode adjust dans notre component. Nous crons le fichier
app/Test/Case/Controller/Component/PagematronComponentTest.php :
App::uses('Controller', 'Controller');
App::uses('CakeRequest', 'Network');
App::uses('CakeResponse', 'Network');
App::uses('ComponentCollection', 'Controller');
App::uses('PagematronComponent', 'Controller/Component');
// Un faux controller pour tester against
class PagematronControllerTest extends Controller {
public $paginate = null;
}
class PagematronComponentTest extends CakeTestCase {
public $PagematronComponent = null;
public $Controller = null;
public function setUp() {
parent::setUp();
// Configurer notre component et faire semblant de tester le controller
$Collection = new ComponentCollection();
$this->PagematronComponent = new PagematronComponent($Collection);
$CakeRequest = new CakeRequest();
$CakeResponse = new CakeResponse();
$this->Controller = new PagematronControllerTest($CakeRequest, $CakeResponse);
$this->PagematronComponent->startup($this->Controller);
}
public function testAdjust() {
920
Ici nous dfinissons la dcimale 2 aprs la virgule, le sparateur de dcimal, le sparateur des centaines
avec une virgule, et le nombre format avec la chane USD en prfixe.
Maintenant nous crons nos tests :
// app/Test/Case/View/Helper/CurrencyRendererHelperTest.php
App::uses('Controller', 'Controller');
App::uses('View', 'View');
App::uses('CurrencyRendererHelper', 'View/Helper');
class CurrencyRendererHelperTest extends CakeTestCase {
public $CurrencyRenderer = null;
// Ici nous instancions notre helper
public function setUp() {
parent::setUp();
$Controller = new Controller();
Testing
921
Ici nous appelons usd() avec des paramtres diffrents et disons test suite de vrifier si les valeurs
retournes sont gales ce que nous en attendons.
Sauvegardons cela et excutons le test. Vous devriez voir une barre verte et un message indiquant 1 pass et
4 assertions.
Le code ci-dessus va grouper tous les cas de test trouvs dans le dossier /app/Test/Case/Model/.
Pour ajouter un fichier individuel, utilisez $suite->addTestFile($filename);. Vous pouvez
ajouter de faon rcursive un rpertoire pour tous les tests en utilisant :
$suite->addTestDirectoryRecursive(TESTS . 'Case/Model');
Ajouterait de faon rcursive tous les cas de test dans le rpertoire app/Test/Case/Model. Vous pouvez
utiliser les suites de test pour construire une suite qui excute tous les tests de votre application :
class AllTestsTest extends CakeTestSuite {
public static function suite() {
$suite = new CakeTestSuite('All tests');
$suite->addTestDirectoryRecursive(TESTS . 'Case');
922
return $suite;
}
}
Ils travaillent comme des tests normaux mais vous devrez vous souvenir dutiliser les conventions de nommage pour les plugins quand vous importez des classes. Ceci est un exemple dun testcase pour le model
BlogPost partir du chapitre des plugins de ce manuel. Une diffrence par rapport aux autres tests est
dans la premire ligne o Blog.BlogPost est import. Vous devrez aussi prfixer les fixtures de votre plugin
avec plugin.blog.blog_post :
App::uses('BlogPost', 'Blog.Model');
class BlogPostTest extends CakeTestCase {
// Les fixtures de plugin localis dans /app/Plugin/Blog/Test/Fixture/
public $fixtures = array('plugin.blog.blog_post');
public $BlogPost;
public function testSomething() {
// ClassRegistry dit au model d'utiliser la connexion la base de donnes test
$this->BlogPost = ClassRegistry::init('Blog.BlogPost');
// faire des tests utiles ici
$this->assertTrue(is_object($this->BlogPost));
}
}
Si vous voulez utiliser les fixures de plugin dans les app tests, vous pouvez y faire rfrence en utilisant la
syntaxe plugin.pluginName.fixtureName dans le tableau $fixtures.
Testing
923
test. Cela aide sassurer que tous les tests passent et que votre application est dj prte.
Intgrer une application CakePHP avec Jenkins est fairly straightforward. Ce qui suit suppose que vous avez
dj install Jenkins sur un systme *nix, et que vous tes capable de ladministrer. Vous savez aussi comment crer des jobs, et lancer des builds. Si vous ntes pas sur de tout cela, rferez vous la documentation
de Jenkins 9 .
Crer un job
Commenons par crer un job pour votre application, et connectons votre rpertoire afin que jenkins puisse
accder votre code.
Ajouter une config de base de donnes de test
Utiliser une base de donnes spare juste pour Jenkins est gnralement une bonne ide, puisque cela
vite au sang de couler et vite un certain nombre de problmes basiques. Une fois que vous avez cr une
nouvelle base de donnes dans un serveur de base de donnes auquel jenkins peut accder (habituellement
localhost). Ajoutez une tape de script shell au build qui contient ce qui suit :
cat > app/Config/database.php <<'DATABASE_PHP'
<?php
class DATABASE_CONFIG {
public $test = array(
'datasource' => 'Database/Mysql',
'host'
=> 'localhost',
'database'
=> 'jenkins_test',
'login'
=> 'jenkins',
'password'
=> 'cakephp_jenkins',
'encoding'
=> 'utf8'
);
}
DATABASE_PHP
Cela sassure que vous aurez toujours la bonne configuration de la base de donnes dont Jenkins a besoin.
Faites la mme chose pour tout autre fichier de configuration dont vous auriez besoin. Il est souvent une
bonne ide de supprimer et re-crer la base de donnes avant chaque build aussi. Cela vous vite des checs
de chanes, o un buid cass entrane lechec des autres. Ajoutez une autre tape de script shell au build qui
contient ce qui suit :
924
Si vous utilisez le clover coverage, ou les rsultats junit, assurez-vous de les configurer aussi dans Jenkins.
Ne pas configurer ces tapes signifiera que vous ne verrez pas les rsultats.
Lancer un build
Vous devriez tre capable de lancer un build maintenant. Vrifiez la sortie de la console et faites tous les
changements ncessaires pour obtenir un build prcdent.
REST
Quelques programmeurs nophytes dapplication ralisent le besoin douvrir leurs fonctionnalits du coeur
un public plus important. Fournir facilement, un accs sans entrave votre API du coeur peut aider ce que
votre plateforme soit accepte, et permettre les mashups et une intgration facile avec les autres systmes.
Alors que dautres solutions existent, REST est un bon moyen de fournir facilement un accs la logique
que vous avez cre dans votre application. Cest simple, habituellement bas sur XML (nous parlons de
XML simple, rien de semblable une enveloppe SOAP), et dpend des headers HTTP pour la direction.
Exposer une API via REST dans CakePHP est simple.
La premire ligne met en place un certain nombre de routes par dfaut pour un accs facile par REST l o
la mthode parseExtensions() spcifie le format de rsultat souhait (ex : xml, json, rss). Ces routes
correspondent aux mthodes de requtes HTTP.
REST
925
HTTP format
GET
GET
POST
POST
PUT
DELETE
format URL
/recipes.format
/recipes/123.format
/recipes.format
/recipes/123.format
/recipes/123.format
/recipes/123.format
La classe Router de CakePHP utilise un certain nombre dindicateurs diffrents pour dtecter la mthode
HTTP utilise. Les voici par ordre de prfrence :
1. La variable POST _method
2. X_HTTP_METHOD_OVERRIDE
3. Le header REQUEST_METHOD
La _method variable POST est utile lors de lutilisation dun navigateur en tant que client REST (ou nimporte quoi dautre capable de faire facilement du POST). Il suffit dinitialiser la valeur de _method au nom
de la mthode de requte HTTP que vous souhaitez muler.
Une fois que le router est paramtr pour faire correspondre les requtes REST certaines actions de controller, nous pouvons nous mettre crer la logique dans nos actions de controller. Un controller basique
pourrait ressembler ceci :
// Controller/RecipesController.php
class RecipesController extends AppController {
public $components = array('RequestHandler');
public function index() {
$recipes = $this->Recipe->find('all');
$this->set(array(
'recipes' => $recipes,
'_serialize' => array('recipes')
));
}
public function view($id) {
$recipe = $this->Recipe->findById($id);
$this->set(array(
'recipe' => $recipe,
'_serialize' => array('recipe')
));
}
public function add() {
$this->Recipe->create();
if ($this->Recipe->save($this->request->data)) {
$message = 'Saved';
} else {
$message = 'Error';
}
$this->set(array(
'message' => $message,
926
Depuis que nous avons ajout un appel Router::parseExtensions(), Le router CakePHP est dj
prt servir diffrentes vues sur la base de diffrents types de requtes. Puisque nous avons affaire des
requtes REST, le type de vue est le XML. Vous pouvez aussi facilement faire des vues JSON en utilisant
le Vues JSON et XML intgr dans CakePHP. En utilisant le XmlView intgr, nous pouvons dfinir une
variable de vue _serialize. Cette variable de vue spciale est utilise pour dfinir quelles variables de
vue XmlView devrait srialiser dans XML.
Si vous souhaitez modifier les donnes avant dtre converties en XML, nous ne devrions pas _serialize
une variable de vue, et la place utiliser les fichiers de vue. Nous plaons les vues REST pour nos
RecipesController lintrieur de app/View/recipes/xml. Nous pouvons aussi utiliser Xml pour une
sortie XML facile et rapide dans ces vues. Voici ce quoi notre index pourrait ressembler :
// app/View/Recipes/xml/index.ctp
// Faire du formatage et des manipulations sur
// le tableau $recipes.
$xml = Xml::fromArray(array('response' => $recipes));
echo $xml->asXML();
Quand on sert un type de contenu spcifique en utilisant parseExtensions(), CakePHP recherche automatiquement un helper de vue qui correspond au type. Puisque nous utilisons XML en type de contenu, il ny a
pas de helper intgr, cependant si vous en crez un, il sera automatiquement charger pour notre utilisation
dans ces vues.
REST
927
Crer la logique pour laction edit est un peu vicieux, mais pas de beaucoup. Puisque nous fournissons un
API qui sort du XML, cest un choix naturel pour recevoir le XML en entre. Ne vous inquitez pas, les
classes RequestHandler et Router facilitent beaucoup les choses. Si une requte POST ou PUT a un
content-type XML, alors lentre est lance travers la classe Xml de CakePHP, et la reprsentation en
tableau des donnes est assigne $this->request->data. A cause de cette fonctionnalit, grer les donnes
en XML et POST en parallle est transparente : aucun changement nest requis dans le code du controller
ou du model. Tout ce dont vous avez besoin devrait finir dans $this->request->data.
En crivant par dessus la ressource map par dfaut, les appels futurs mapResources() vont utiliser les
nouvelles valeurs.
928
tableau $options
personnalis
utilis
pour
par
Router::mapResources('books', array(
'connectOptions' => array(
'routeClass' => 'ApiRoute',
)
));
Filtres du Dispatcher
Introduit dans la version 2.2.
Il y a plusieurs raisons de vouloir un bout de code lancer avant que tout code de controller soit lanc
ou juste avant que la rponse soit envoye au client, comme la mise en cache de la rponse, le header
tuning, lauthentication spciale ou juste pour fournir laccs une rponse de lAPI critique plus rapidement
quavec un cycle complet de dispatchement de requtes.
CakePHP fournit une interface propre et extensible pour de tels cas pour attacher les filtres au cycle de
dispatchement, de la mme faon quune couche middleware pour fournir des services empilables ou des
routines pour chaque requte. Nous les appelons Dispatcher Filters.
Chacune de ces valeurs de tableaux sont des noms de classe qui seront instancis et ajouts en couteurs
des vnements gnrs au niveau du dispatcher. Le premier, AssetDispatcher est l pour vrifier si la
requte se rfre au theme ou au fichier dasset du plugin, comme le CSS, le JavaScript ou une image stocke
Filtres du Dispatcher
929
dans soit un dossier du webroot du plugin, soit dans celui correspondant au Theme. Il servira le fichier selon
sil est trouv ou non, stoppant le reste du cycle de dispatchement. Le filtre CacheDispatcher, quand
la variable de config Cache.check est active, va vrifier si la rponse a dj t mise en cache dans le
systme de fichier pour une requte similaire et servir le code mis en cache immdiatement.
Comme vous pouvez le voir, les deux filtres fournis ont la responsabilit darrter tout code plus loin et
denvoyer la rponse juste aprs au client. Mais les filtres ne sont pas limits au role, puisque nous allons
montrons rapidement dans cette section.
Vous pouvez ajouter vos propres noms de classes la liste des filtres, et ils seront excuts dans lordre
dans lequel ils ont t dfini. Il y aussi une faon alternative pour attacher les filtres qui nimpliquent pas les
classes spciales DispatcherFilter :
Configure::write('Dispatcher.filters', array(
'my-filter' => array('callable' => array($classInstance, 'methodName'), 'on' => 'after'
));
Comme montr ci-dessus, vous pouvez passer tout type de callback 10 PHP valide, puisque vous vous en
souvenez peut-tre, un callback est tout ce que PHP peut excuter avec call_user_func. Nous faisons
une petite exception, si une chane est fournie, elle sera traite comme un nom de classe, et pas comme
un nom de fonction possible. Ceci bien sur donne la capacit aux utilisateurs de PHP5.3 dattacher des
fonctions anonymes en tant que filtres :
Configure::write('Dispatcher.filters', array(
'my-filter' => array('callable' => function($event) {...}, 'on' => 'before'),
//plus de filtres ici
));
La cl on prend seulement before et after comme valeurs valides, et cela signifie bien videmment si
le filtre doit tre lanc avant ou aprs que tout code du controller soit excut. En plus de dfinir les filtres
avec la cl callable, vous pouvez aussi dfinir une priorit pour vos filtres, si aucun nest spcifi alors
par dfaut 10 et slectionn pour vous.
Puisque tous les filtres auront une priorit par dfaut 10, vous aurez envie de lancer un filtre avant tout
autre dans la liste, slectionner des nombres dune priorit plus faible comme souhait :
Configure::write('Dispatcher.filters', array(
'my-filter' => array(
'callable' => function($event) {...},
'on' => 'before',
'priority' => 5
),
'other-filter' => array(
'callable' => array($class, 'method'),
'on' => 'after',
'priority' => 1
),
//plus de filtres ici
));
10. http ://php.net/callback
930
Evidemment, quand vous dfinissez les priorits, lordre dans lequel les filtres sont dclars na pas dimportance mais pour ceux qui ont la mme priorit. Quand vous dfinissez les filtres en tant que noms de
classe, il ny a pas doptions pour dfinir la priorit in-line, nous y viendront bientt. Au final, la notation de
plugin de CakePHP peut tre utilise pour dfinir les filtres localiss dans les plugins :
Configure::write('Dispatcher.filters', array(
'MyPlugin.MyFilter',
));
Nhsitez pas retirer les filtres attachs par dfaut si vous choisissiez dutiliser une faon plus
avance/rapide pour servir les thmes les assets de plugin ou si vous ne souhaitez pas utiliser la mise en
cache intgre de la page entire, ou pour juste implmenter le votre.
Si vous avez besoin de passer des paramtres ou des configurations au constructeur vos classes de dispatch
filter, vous pouvez le faire en fournissant un tableau de paramtres :
Configure::write('Dispatcher.filters', array(
'MyAssetFilter' => array('service' => 'google.com')
));
Quand la cl filter est un nom de classe valide, la valeur peut tre un tableau de paramtres qui sont passs
au dispatch filter. Par dfaut, la classe de base va assigner ces paramtres la proprit $settings aprs
les avoir fusionns avec les valeurs par dfaut dans la classe.
Modifi dans la version 2.5 : Vous pouvez maintenant fournir des paramtres au constructeur pour dispatcher
les filtres dans 2.5.
Classes Filter
Les filtres de Dispatcher, quand dfinis en tant que noms de classe dans configuration, doivent tendre la
classe DispatcherFilter fournie dans le rpertoire Routing de CakePHP. Crons un simple filtre pour
rpondre une URL spcifique avec un texte Hello World :
App::uses('DispatcherFilter', 'Routing');
class HelloWorldFilter extends DispatcherFilter {
public $priority = 9;
public function beforeDispatch($event) {
$request = $event->data['request'];
$response = $event->data['response'];
if ($request->url === 'hello-world') {
$response->body('Hello World');
$event->stopPropagation();
return $response;
}
}
}
Filtres du Dispatcher
931
Ce filtre enverra une expiration du header 1 jour dans le futur pour toutes les rponses produites par le
controller pages. Vous pourriez bien sr faire la mme chose dans le controller, ceci est juste un exemple de
ce qui peut tre fait avec les filtres. Par exemple, au lieu de modifier la rponse, vous pourriez la mettre en
cache en utilisant la classe Cache et servir la rponse partir du callback beforeDispatch.
Filtres Inline
Notre dernier exemple va utiliser une fonction anonyme (seulement disponible sur PHP 5.3+) pour servir
une liste de posts dans un format JSON, nous vous encourageons faire ainsi lutilisation des controllers
932
et la classe JsonView, mais imaginons que vous ayez besoin de gagner une tout petite milliseconde pour
cette mission-critical API endpoint :
$postsList = function($event) {
if ($event->data['request']->url !== 'posts/recent.json') {
return;
}
App::uses('ClassRegistry', 'Utility');
$postModel = ClassRegistry::init('Post');
$event->data['response']->body(json_encode($postModel->find('recent')));
$event->stopPropagation();
return $event->data['response'];
};
Configure::write('Dispatcher.filters', array(
'AssetDispatcher',
'CacheDispatcher',
'recent-posts' => array(
'callable' => $postsList,
'priority' => 9,
'on'=> 'before'
)
));
Dans lexemple prcdent, nous avons selectionn une priorit 9 pour notre filtre, donc pour sauter toute
autre logique, soit plac dans des filtres personnaliss, soit dans des filtres du coeur comme le systme de
routing interne de CakePHP. Bien que cela ne soit pas ncessaire, cela montre comment faire pour que votre
code important se lance en premier au cas o vous auriez besoin de trim au plus gros possible partir de
certaines requtes.
Pour des raisons videntes, ceci a le potentiel de rendre la maintenance de votre app trs difficile. Les filtres
sont un outil extrmement puissant quand on les utilise sagement, ajoutez les gestionnaires de rponse pour
chaque URL dans votre app nest pas une bonne utilisation pour cela. Mais si vous avez une raison valide
de le faire, alors vous avez une solution propre porte de main. Gardez lesprit que tout ne doit pas tre
un filtre, les Controllers et les Components sont habituellement un choix plus prcis pour ajouter tout code
de gestion de requte votre app.
Filtres du Dispatcher
933
934
CHAPITRE 11
Dploiement
Une fois que votre application est termine, ou mme avant que vous souhaitiez la dployer. Il y a quelques
choses que vous devriez faire quand vous dployez une application CakePHP.
935
936
CHAPITRE 12
Suivez notre exemple Tutoriel dun Blog, imaginons que nous souhaitions scuriser laccs de certaines
URLs, bases sur la connexion de luser. Nous avons aussi une autre condition requise, qui est dautoriser
notre blog avoir des auteurs multiples, afin que chacun deux puisse crer ses propres posts, les modifier
et les supprimer selon le besoin interdisant dautres auteurs apporter des modifications sur ses messages.
Nous avons respect les conventions de CakePHP pour le nommage des tables, mais nous profitons dune
autre convention : en utilisant les colonnes du nom duser et du mot de passe dans une table users, CakePHP
sera capable de configurer automatiquement la plupart des choses pour nous quand on ralisera la connexion
de luser.
La prochaine tape est de crer notre model User, qui a la responsablilit de trouver, sauvegarder et valider
toute donne duser :
// app/Model/User.php
App::uses('AppModel', 'Model');
937
Creons aussi notre UsersController, le contenu suivant correspond la classe cuisine basique UsersController en utilisant les utilitaires de gnration de code fournis avec CakePHP :
// app/Controller/UsersController.php
class UsersController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add', 'logout');
}
public function index() {
$this->User->recursive = 0;
$this->set('users', $this->paginate());
}
public function view($id = null) {
if (!$this->User->exists($id)) {
throw new NotFoundException(__('User invalide'));
}
$this->set('user', $this->User->findById($id));
}
public function add() {
if ($this->request->is('post')) {
$this->User->create();
if ($this->User->save($this->request->data)) {
$this->Flash->success(__('L\'user a t sauvegard'));
938
939
votre
application,
ouvrez
app/Controller/AppController.php et ajoutez les lignes suivantes :
votre
fichier
// app/Controller/AppController.php
class AppController extends Controller {
//...
Il ny a pas grand chose configurer, puisque nous avons utilis les conventions pour la table des users. Nous
avons juste configur les URLs qui seront charges aprs que la connexion et la dconnexion des actions
sont effectues, dans notre cas, respectivement /posts/ et /.
Ce que nous avons fait dans la fonction beforeFilter a t de dire au AuthComponent de ne pas exiger
un login pour toutes les actions index et view, dans chaque controller. Nous voulons que nos visiteurs
soient capables de lire et lister les entres sans sinscrire dans le site.
Maintenant, nous avons besoin dtre capable dinscrire des nouveaux users, de sauvegarder leur nom duser
et mot de passe, et plus important de hasher leur mot de passe afin quil ne soit pas stock en texte plain
940
dans notre base de donnes. Disons AuthComponent de laisser des users non-authentifis daccder la
fonction add des users et de raliser laction connexion et deconnexion :
// app/Controller/UsersController.php
public function beforeFilter() {
parent::beforeFilter();
// Permet aux utilisateurs de s'enregistrer et de se dconnecter
$this->Auth->allow('add', 'logout');
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Flash->error(__("Nom d'user ou mot de passe invalide, ressayer"));
}
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
Le hash du mot de passe nest pas encore fait, ouvrez votre fichier de model app/Model/User.php et
ajoutez ce qui suit :
// app/Model/User.php
App::uses('AppModel', 'Model');
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
// ...
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$passwordHasher = new SimplePasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}
// ...
Ainsi, maintenant chaque fois quun user est sauvegard, le mot de passe est hash en utilisant la classe
SimplePasswordHasher. Il nous manque juste un fichier template de vue pour la fonction de connexion :
941
//app/View/Users/login.ctp
<div class="users form">
<?php echo $this->Flash->render('auth'); ?>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend>
<?php echo __('Please enter your username and password'); ?>
</legend>
<?php echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>
Vous pouvez maintenant inscrire un nouvel user en rentrant lURL /users/add et vous connecter avec
ce profil nouvellement cr en allant sur lURL /users/login. Essayez aussi daller sur nimporte quel
URL qui na pas t explicitement autorise telle que /posts/add, vous verrez que lapplication vous
redirige automatiquement vers la page de connexion.
Et cest tout ! Cela semble trop simple pour tre vrai. Retournons en arrire un peu pour expliquer ce qui
sest pass. La fonction beforeFilter dit au component AuthComponent de ne pas exiger de connexion pour laction add en plus des actions index et view qui taient dj autorises dans la fonction
beforeFilter de lAppController.
Laction login appelle la fonction $this->Auth->login() dans AuthComponent, et cela fonctionne
sans autre config car nous suivons les conventions comme mentionnes plus tt. Cest--dire, avoir un model
User avec les colonnes username et password, et utiliser un formulaire post un controller avec les donnes
duser. Cette fonction retourne si la connexion a russi ou non, et en cas de succs, alors nous redirigeons
luser vers lURL configur de redirection que nous utilisions quand nous avons ajout AuthComponent
notre application.
La dconnexion fonctionne juste en allant lURL /users/logout et redirigera luser vers
lUrl de Dconnexion configure dcrite prcedemment. Cette URL est le rsultat de la fonction
AuthComponent::logout() en cas de succs.
Aussi, un petit changement dans PostsController est ncessaire pour stocker luser connect courant en
rfrence pour le post cr :
// app/Controller/PostsController.php
public function add() {
if ($this->request->is('post')) {
942
La fonction user() fournie par le component retourne toute colonne partir de luser connect courant.
Nous avons utilis cette mthode pour ajouter les donnes dans les infos requtes qui sont sauvegardes.
Scurisons maintenant notre app pour empcher certains auteurs de modifier ou supprimer les posts des
autres. Des rgles basiques pour notre app sont que les users admin peuvent accder tout URL, alors que
les users normaux (le role auteur) peuvent seulement accder aux actions permises. Ouvrez encore la classe
AppController et ajoutez un peu plus doptions la config de Auth :
// app/Controller/AppController.php
public $components = array(
'Flash',
'Auth' => array(
'loginRedirect' => array('controller' => 'posts', 'action' => 'index'),
'logoutRedirect' => array(
'controller' => 'pages',
'action' => 'display',
'home'
),
'authenticate' => array(
'Form' => array(
'passwordHasher' => 'Blowfish'
)
),
'authorize' => array('Controller') // Ajout de cette ligne
)
);
public function isAuthorized($user) {
// Admin peut accder toute action
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
// Refus par dfaut
return false;
}
Nous venons de crer un mcanisme trs simple dautorisation. Dans ce cas, les users avec le role admin
sera capable daccder tout URL dans le site quand ils sont connects, mais les autres (par ex le role
auteur) ne peut rien faire dautre par rapport aux users non connects.
Ce nest pas exactement ce que nous souhaitions, donc nous avons besoin de dterminer et fournir plus de
rgles notre mthode isAuthorized(). Mais plutt que de le faire dans AppController, dleguons
chaque controller la fourniture de ces rgles supplmentaires. Les rgles que nous allons ajouter PostsConAutorisation (Qui est autoris accder quoi)
943
troller permettront aux auteurs de crer des posts mais empcheront ldition des posts si lauteur ne correspond pas. Ouvrez le fichier PostsController.php et ajoutez le contenu suivant :
// app/Controller/PostsController.php
public function isAuthorized($user) {
// Tous les users inscrits peuvent ajouter les posts
if ($this->action === 'add') {
return true;
}
// Le propritaire du post peut l'diter et le supprimer
if (in_array($this->action, array('edit', 'delete'))) {
$postId = (int) $this->request->params['pass'][0];
if ($this->Post->isOwnedBy($postId, $user['id'])) {
return true;
}
}
return parent::isAuthorized($user);
}
Ceci conclut notre tutoriel simple sur lauthentification et les autorisations. Pour scuriser lUsersController,
vous pouvez suivre la mme technique que nous faisions pour PostsController, vous pouvez aussi tre plus
cratif et coder quelque chose de plus gnral dans AppController bas sur vos propres rgles.
Si vous avez besoin de plus de contrle, nous vous suggrons de lire le guide complet Auth dans la section Authentification o vous en trouverez plus sur la configuration du component, la cration de classes
dautorisation personnalise, et bien plus encore.
944
CHAPITRE 13
Note : Ce nest pas un tutoriel pour dbutants. Si vous commencez juste avec CakePHP, nous vous conseillons davoir un meilleur exprience densemble des fonctionnalits du framework avant dessayer ce
tutoriel.
Dans ce tutoriel, vous allez crer une application simple avec Authentification et Liste de contrle daccs
(ACL). Ce tutoriel suppose que vous avez lu le tutoriel du Tutoriel dun Blog, et que vous tes familier avec
Gnration de code avec Bake. Vous devrez avoir un peu dexprience avec CakePHP, et tre familier avec
les concepts MVC. Ce tutoriel est une brive introduction AuthComponent et AclComponent.
Ce dont vous aurez besoin
1. Un serveur web oprationnel. Nous allons supposer que vous utilisez Apache, cependant les instructions pour utiliser dautres serveurs devraient tre trs similaires. Nous pourrions avoir jouer un peu
avec la configuration du serveur, mais la plupart de gens peuvent se procurer CakePHP et le faire
fonctionner sans quaucune configuration soit ncessaire.
2. Un serveur de base de donnes. Nous utiliserons MySQL dans ce tutoriel. Vous aurez besoin de connatre suffisamment de chose en SQL, notamment pour pouvoir crer une base de donnes : CakePHP
prendra les rnes partir dici.
3. Une connaissance des bases PHP. Plus vous aurez pratiqu la programmation oriente objet, mieux a
vaudra : mais nayez pas peur si vous tes un fan de programmation procdurale.
945
Une fois que vous avez votre copie toute rcente de CakePHP, changez votre branche vers la dernire version
de 2.0, configurez votre fichier database.php et changez la valeur du Security.salt (grain de scurit)
dans votre fichier app/Config/core.php. A ce stade, nous construirons un schma simple de base
de donnes sur lequel btir notre application. Excutez les commandes SQL suivantes sur votre base de
donnes :
CREATE TABLE users (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL UNIQUE,
password CHAR(40) NOT NULL,
group_id INT(11) NOT NULL,
created DATETIME,
modified DATETIME
);
CREATE TABLE groups (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
created DATETIME,
modified DATETIME
);
CREATE TABLE posts (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
user_id INT(11) NOT NULL,
title VARCHAR(255) NOT NULL,
body TEXT,
created DATETIME,
modified DATETIME
);
CREATE TABLE widgets (
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
part_no VARCHAR(12),
quantity INT(11)
);
Ce sont les tables que nous utiliserons pour construire le reste de notre application. Une fois que nous avons
la structure des tables dans notre base de donnes, nous pouvons commencer cuisiner. Utilisez Gnration
de code avec Bake pour crer rapidement vos models, controllers et vues.
Pour utiliser cake bake, appelez cake bake all et cela listera les 4 tables que vous avez inser dans
MySQL. Slctionnez 1. Group, et suivez ce qui est crit sur lcran. Rptez pour les 3 autres tables, et
cela gnrera les 4 controllers, models et vues pour vous.
Evitez dutiliser le Scaffold ici. La gnration des ACOs en sera srieusement affecte si vous cuisinez les
controllers avec la fonctionnalit Scaffold.
Pendant la cuisson des Models, cake dtectera auto-magiquement les associations entre vos Models (ou
relations entre vos tables). Laissez CakePHP remplir les bonnes associations hasMany et belongsTo. Si vous
946
tes invit choisir hasOne ou hasMany, dune manire gnrale, vous aurez besoin dune relation hasMany
(seulement) pour ce tutoriel.
Laissez de ct les routing admin pour le moment, cest dj un assez compliqu sujet comme cela sans eux.
Assurez-vous aussi de ne pas ajouter les Components Acl et Auth aucun de vos controllers quand vous les
cuisinez. Nous le ferons bien assez tt. Vous devriez maintenant avoir des models, controllers, et des vues
cuisins pour vos users, groups, posts et widgets.
Ensuite nous devrons mettre jour notre model User pour hasher les passwords avant quils aillent dans
la base de donnes. Stocker les passwords en brut est extrmement non scuris et AuthComponent va
sattendre ce que vos passwords soient hashs. Dans app/Model/User.php ajoutez ce qui suit :
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
// autre code.
947
}
}
Ensuite nous devons faire quelques modifications dans AppController. Si vous navez pas
/app/Controller/AppController.php, crez le. Puisque nous voulons que notre site entier soit
contrll avec Auth et Acl, nous allons les dfinir en haut dans AppController :
class AppController extends Controller {
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
'Session'
);
public $helpers = array('Html', 'Form', 'Session');
public function beforeFilter() {
//Configure AuthComponent
$this->Auth->loginAction = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->logoutRedirect = array(
'controller' => 'users',
'action' => 'login'
);
$this->Auth->loginRedirect = array(
'controller' => 'posts',
'action' => 'add'
);
}
}
Avant de configurer ACL, nous aurons besoin dajouter quelques users et groups. Avec AuthComponent
en utilisation, nous ne serons pas capable daccder aucune de nos actions, puisque nous ne sommes pas
connects. Nous allons maintenant ajouter quelques exceptions ainsi AuthComponent va nous autoriser
crer quelques groups et users. Dans les deux, votre GroupsController et votre UsersController,
ajoutez ce qui suit :
public function beforeFilter() {
parent::beforeFilter();
// Pour CakePHP 2.0
$this->Auth->allow('*');
// Pour CakePHP 2.1 et suprieurs
$this->Auth->allow();
}
948
Ces lignes disent AuthComponent dautoriser les accs publiques toutes les actions. Cest seulement
temporaire et ce sera retir une fois que nous aurons quelques users et groups dans notre base de donnes.
Najoutez pourtant encore aucun user ou group.
Ce schma vous invite supprimer et crer les tables. Rpondez Oui (Yes) la suppression et cration des
tables.
Si vous navez pas daccs au shell, ou si vous avez des problmes pour utiliser la console, vous pouvez excuter le fichier sql se trouvant lemplacement suivant : /chemin/vers/votre/app/Config/Schema/db_acl.sql.
Avec les controllers configurs pour lentre de donnes et les tables Acl initialises, nous sommes prts
commencer, nest-ce-pas ? Pas tout fait, nous avons encore un peu de travail faire dans les models users
et groups. Concrtement, faire quils sattachent auto-magiquement lAcl.
949
Cela permet de lier les models Group et User lAcl, et de dire CakePHP que chaque fois que lon cr
un User ou un Group, nous voulons galement ajouter une entre dans la table aros. Cela fait de la gestion
des Acl un jeu denfant, puisque vos AROs se lient de faon transparente vos tables users et groups.
Ainsi, chaque fois que vous crez ou supprimez un groupe/user, la table Aro est mise jour.
Nos controllers et models sont maintenant prts recevoir des donnes initiales et nos models Group et
User sont relis la table Acl. Ajoutez donc quelques groups et users en utilisant les formulaires crs avec
Bake en allant sur http ://exemple.com/groups/add et http ://exemple.com/users/add. Jai cr les groups
suivants :
administrateurs
managers
users
Jai galement cr un user dans chaque groupe, de faon avoir un user de chaque niveau daccs pour les
tests ultrieurs. Ecrivez tout sur du papier ou utilisez des mots de passe faciles, de faon ne pas les oublier.
Si vous faites un SELECT * FROM aros ; depuis une commande MySQL, vous devriez recevoir quelque
chose comme cela :
+----+-----------+-------+-------------+-------+------+------+
| id | parent_id | model | foreign_key | alias | lft | rght |
+----+-----------+-------+-------------+-------+------+------+
| 1 |
NULL | Group |
1 | NULL |
1 |
4 |
| 2 |
NULL | Group |
2 | NULL |
5 |
8 |
| 3 |
NULL | Group |
3 | NULL |
9 |
12 |
| 4 |
1 | User |
1 | NULL |
2 |
3 |
| 5 |
2 | User |
2 | NULL |
6 |
7 |
| 6 |
3 | User |
3 | NULL |
10 |
11 |
+----+-----------+-------+-------------+-------+------+------+
6 rows in set (0.00 sec)
Cela nous montre que nous avons 3 groups et 3 users. Les users sont imbriqus dans les groups, ce qui
signifie que nous pouvons dfinir des permissions sur une base par groupe ou par user.
950
Ces deux changements vont dire ACL de ne pas vrifier les Aros des User Aros et de vrifier seulement
les Aros de Group.
Note : Chaque user devra tre assign un group_id pour que ceci fontionne correctement.
Maintenant la table aros va ressembler ceci :
+----+-----------+-------+-------------+-------+------+------+
| id | parent_id | model | foreign_key | alias | lft | rght |
+----+-----------+-------+-------------+-------+------+------+
| 1 |
NULL | Group |
1 | NULL |
1 |
2 |
| 2 |
NULL | Group |
2 | NULL |
3 |
4 |
| 3 |
NULL | Group |
3 | NULL |
5 |
6 |
+----+-----------+-------+-------------+-------+------+------+
3 rows in set (0.00 sec)
Note : Si vous avez suivi le tutoriel jusquici, vous devez effacer vos tables, y compris aros, groups et
users, et crer les tables groups et users nouveau de zro pour obtenir la table aros ci-dessus.
Ces deux exemples vont crer notre root ou ACO de plus haut niveau, qui sera appel controllers. Lobjectif
de ce nud root est dautoriser/interdire laccs lchelle globale de lapplication, et permet lutilisation
de lAcl dans des objectifs non lis aux controllers/actions, tels que la vrification des permissions dun
enregistrement dun model. Puisque nous allons utiliser un ACO root global, nous devons faire une petite
modification la configuration de AuthComponent. LAuthComponent doit tre renseign sur lexistence de ce nud root, de sorte que lors des contrles de lACL, le component puisse utiliser le bon chemin
de nud lors de la recherche controllers/actions. Dans lAppController, assurez vous que le tableau
$components contient lactionPath dfini avant :
951
Continuez Application Simple contrle par Acl - partie 2 pour continuer le tutoriel.
952
CHAPITRE 14
Vous pouvez rcuprer un guide complet pour toutes les commandes disponibles comme ceci :
./Console/cake AclExtras.AclExtras -h
./Console/cake AclExtras.AclExtras aco_sync -h
Une fois remplie, votre table acos permet de crer les permissions de votre application.
1. https ://github.com/markstory/acl_extras/
2. https ://github.com/markstory/acl_extras/zipball/master
953
Nous allons maintenant ajouter un peu dautorisations/interdictions. Ajoutez ce qui suit une fonction temporaire dans votre UsersController et visitez ladresse dans votre navigateur pour les lancer (par ex :
http ://localhost/cake/app/users/initdb). Si vous fates un SELECT * FROM aros_acos, vous devriez
voir une pile entire de 1 et -1. Une fois que vous avez confirm, vos permissions sont configures, retirez
la fonction :
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('initDB'); // Nous pouvons supprimer cette ligne aprs avoir fini
}
public function initDB() {
$group = $this->User->Group;
// Autorise l'accs tout pour les admins
$group->id = 1;
$this->Acl->allow($group, 'controllers');
// Autorise l'accs aux posts et widgets pour les managers
$group->id = 2;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Posts');
$this->Acl->allow($group, 'controllers/Widgets');
// Autorise l'accs aux actions add et edit des posts widgets pour les utilisateurs de
$group->id = 3;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Posts/add');
$this->Acl->allow($group, 'controllers/Posts/edit');
$this->Acl->allow($group, 'controllers/Widgets/add');
$this->Acl->allow($group, 'controllers/Widgets/edit');
// Permet aux utilisateurs classiques de se dconnecter
$this->Acl->allow($group, 'controllers/users/logout');
// Nous ajoutons un exit pour viter d'avoir un message d'erreur affreux "missing views
echo "tout est ok";
954
exit;
}
Nous avons maintenant configurer quelques rgles basiques. Nous avons autoris les administrateurs pour
tout. Les Manageurs peuvent accder tout dans posts et widgets. Alors que les users peuvent accder aux
add et edit des posts & widgets.
Nous devions avoir une rfrence dun model de Group et modifier son id pour tre capable de spcifier
lARO que nous voulons, cela est d la faon dont fonctionne AclBehavior. AclBehavior ne configure pas le champ alias dans la table aros donc nous devons utiliser une rfrence dobjet ou un tableau
pour rfrencer lARO que lon souhaite.
Vous avez peut-tre remarqu que jai dlibrement oubli index et view des permissions Acl. Nous allons faire des actions publiques index et view dans PostsController et WidgetsController. Cela
donne aux users non-autoriss lautorisation de voir ces pages, en rendant ces pages publiques. Cependant,
tout moment, vous pouvez retirer ces actions des AuthComponent::allowedActions et les permissions pour view et edit seront les mmes que celles dans Acl.
Maitenant, nous voulons enlever les rfrences de Auth->allowedActions dans les controllers de vos
users et groups. Ensuite ajouter ce qui suit aux controllers de vos posts et widgets :
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('index', 'view');
}
Cela enlve le basculement off que nous avions mis plus tt dans les controllers users et groups
et cela rend public laccs aux actions index et voir dans les controllers Posts et Widgets. Dans
AppController::beforeFilter() ajoutez ce qui suit :
$this->Auth->allow('display');
Ce qui rend laction display publique. Cela rendra notre action PagesController : :display() publique. Ceci
est important car le plus souvent le routage par dfaut dsigne cette action comme page daccueil de votre
application.
Connexion
Notre application est dsormais sous contrle daccs, et toute tentative daccs des pages non publiques
vous redirigera vers la page de connexion. Cependant, vous devrez crer une vue login avant que quelquun
puisse se connecter. Ajoutez ce qui suit app/View/Users/login.ctp si vous ne lavez pas dj fait :
<h2>Connexion</h2>
<?php
echo $this->Form->create('User', array('url' => array('controller' => 'users', 'action' =>
echo $this->Form->input('User.nom_user');
echo $this->Form->input('User.mot_de_passe');
echo $this->Form->end('Connexion');
?>
Connexion
955
Vous devriez tre maintenant capable de vous connecter et tout devrait fonctionner auto-maigiquement.
Quand laccs est refus, les messages de Auth seront affichs si vous ajoutez le code echo
$this->Session->flash(auth).
Dconnexion
Abordons maintenant la dconnexion. Nous avions plus tt laiss cette fonction vide, il est maintenant temps
de la remplir. Dans UsersController::logout() ajoutez ce qui suit
$this->Session->setFlash('Au-revoir');
return $this->redirect($this->Auth->logout());
Cela dfinit un message flash en Session et dconnecte lUser en utilisant la mthode logout de Auth. La
mthode logout de Auth supprime tout simplement la cl dauthentification en session et retourne une URL
qui peut tre utilise dans une redirection. Si il y a dautres donnes en sessions qui doivent tre galement
effaces, ajoutez le code ici.
Cest fini !
Vous devriez maintenant avoir une application contrle par Auth et Acl. Les permissions Users sont dfinies
au niveau du groupe, mais on peut galement les dfinir en mme temps par user. Vous pouvez galement
dfinir les permissions sur une base globale ou par controller et par action. De plus, vous avez un bloc de
code rutilisable pour tendre facilement vos tables ACO lorsque votre application grandit.
956
CHAPITRE 15
Tutoriels et exemples
Dans cette section, vous pourrez dcouvrir des applications CakePHP typiques afin de voir comment toutes
les pices sassemblent.
Sinon, vous pouvez vous rfrer au dpt de plugins non-officiels de CakePHP CakePackages 1 ainsi que la
Boulangerie 2 (Bakery) pour des applications et components existants.
957
4. Enfin, vous aurez besoin de connaissances de base propos du motif de conception MVC. Un bref
aperu de ce motif dans le chapitre Comprendre le systme M-V-C (Model-View-Controller). Ne vous
inquitez pas : il ny a quune demi-page de lecture.
Maintenant, lanons-nous !
Obtenir CakePHP
Tout dabord, rcuprons une copie rcente de CakePHP.
Pour obtenir la dernire version, allez sur le site GitHub du projet
https ://github.com/cakephp/cakephp/tags et tlchargez la dernire version de la 2.0.
Vous
pouvez
aussi
cloner
le
dpt
git://github.com/cakephp/cakephp.git
en
utilisant
git 3 .
CakePHP
git clone
Peu importe comment vous lavez tlcharg, placez le code lintrieur du DocumentRoot de votre
serveur. Une fois termin, votre rpertoire dinstallation devrait ressembler quelque chose comme cela :
/chemin_du_document_root
/app
/lib
/plugins
/vendors
.htaccess
index.php
README
A prsent, il est peut-tre temps de voir un peu comment fonctionne la structure de fichiers de CakePHP :
lisez le chapitre Structure du dossier de CakePHP.
Permissions du rpertoire Tmp
Ensuite vous devrez mettre le rpertoire app/tmp en criture pour le serveur web. La meilleur faon de
le faire est de trouver sous quel utilisateur votre serveur web tourne. Vous pouver mettre <?php echo
exec(whoami); ?> lintrieur de tout fichier PHP que votre serveur web execute. Vous devriez
voir afficher un nom dutilisateur. Changez le possesseur du rpertoire app/tmp pour cet utilisateur. La
commande finale que vous pouvez lancer (dans *nix) pourrait ressembler ceci :
$ chown -R www-data app/tmp
Si pour une raison ou une autre, CakePHP ne peut crire dans ce rpertoire, vous verrez des avertissements
et des exceptions attrapes vous disant que les donnes de cache nont pas pu tre crites.
958
juste crer une simple table pour stocker nos posts. Nous allons galement insrer quelques posts des fins
de tests. Excutez les requtes SQL suivantes dans votre base de donnes :
/* D'abord, crons la table des posts : */
CREATE TABLE posts (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
/* Puis insrons quelques posts pour les tests : */
INSERT INTO posts (title, body, created)
VALUES ('Le titre', 'Voici le contenu du post.', NOW());
INSERT INTO posts (title, body, created)
VALUES ('Encore un titre', 'Et le contenu du post qui suit.', NOW());
INSERT INTO posts (title, body, created)
VALUES ('Le retour du titre', 'C\'est trs excitant, non ?', NOW());
Le choix des noms pour les tables et les colonnes ne sont pas arbitraires. Si vous respectez les conventions
de nommage de CakePHP pour les bases de donnes et les classes (toutes deux expliques au chapitre
Conventions de CakePHP), vous tirerez profit dun grand nombre de fonctionnalits automatiques et vous
viterez des tapes de configurations. CakePHP est suffisamment souple pour implmenter les pires schmas
de bases de donnes, mais respecter les conventions vous fera gagner du temps.
Consultez le chapitre Conventions de CakePHP pour plus dinformations, mais il suffit de comprendre que
nommer notre table posts permet de la relier automatiquement notre model Post, et quavoir des champs
modified et created permet de les avoir grs automagiquement par CakePHP.
959
Une fois votre nouveau fichier database.php sauvegard, vous devriez tre en mesure douvrir votre
navigateur internet et de voir la page daccueil de CakePHP. Elle devrait galement vous indiquer que votre
fichier de connexion a t trouv, et que CakePHP peut sy connecter avec succs.
Note : Rappelez-vous que vous aurez besoin davoir PDO, et pdo_mysql activs dans votre php.ini.
Configuration facultative
Il y a quelques autres lments qui peuvent tre configurs. La plupart des dveloppeurs configurent les
lments de cette petite liste, mais ils ne sont pas obligatoires pour ce tutoriel. Le premier consiste dfinir
une chane de caractres personnalise (ou grain de sel) afin de scuriser les hashs. Le second consiste
dfinir un nombre personnalis (ou graine) utiliser pour le chiffrage.
Le grain de sel est utilis pour gnrer des hashes. Changez la valeur par dfaut de Security.salt
dans /app/Config/core.php la ligne 187. La valeur de remplacement doit tre longue, difficile
deviner et aussi alatoire que possible :
/**
* Une chane alatoire utilise dans les mthodes de hachage scurises.
*/
Configure::write('Security.salt', 'pl345e-P45s_7h3*S@l7!');
La graine cipher est utilise pour le chiffrage/dchiffrage des chanes de caractres. Changez la valeur
par dfaut de Security.cipherSeed dans /app/Config/core.php la ligne 192. La valeur de
remplacement doit tre un grand nombre entier alatoire :
/**
* Une chane alatoire de chiffre utilise pour le chiffrage/dchiffrage
* des chanes de caractres.
*/
Configure::write('Security.cipherSeed', '7485712659625147843639846751');
960
URL Rewriting
Apache et mod_rewrite (et .htaccess)
Alors que CakePHP est construit pour travailler avec mod_rewrite et habituellement il lest nous avons
remarqu que certains utilisateurs se battent pour obtenir un bon fonctionnement sur leurs systmes.
Ici il y a quelques trucs que vous pourriez essayer pour que cela fonctionne correctement. Premirement,
regardez votre fichier httpd.conf (Assurez-vous que vous avez dit le httpd.conf du systme plutt que celui
dun utilisateur- ou le httpd.conf dun site spcifique).
Ces fichiers peuvent varier selon les diffrentes distributions et les versions dApache. Vous pouvez allez
voir http ://wiki.apache.org/httpd/DistrosDefaultLayout pour plus dinformations.
1. Assurez-vous quun .htaccess est permis et que AllowOverride est dfini All pour le bon DocumentRoot. Vous devriez voir quelque chose comme :
# Chaque rpertoire auquel Apache a accs peut tre configur avec
# respect pour lesquels les services et les fonctionnalits sont
# autoriss et/ou dsactivs dans ce rpertoire (et ses sous-rpertoires).
#
# Premirement, nous configurons "par dfault" pour tre un ensemble
# trs restrictif de fonctionnalits.
#
<Directory />
Options FollowSymLinks
AllowOverride All
#
Order deny,allow
#
Deny from all
</Directory>
Pour les utilisateurs qui ont apache 2.4 et suprieur, vous devez modifier le fichier de configuration
pour votre httpd.conf ou la configuration de lhte virtuel pour ressembler ce qui suit :
<Directory /var/www/>
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
2. Assurez-vous que vous avez charg correctement mod_rewrite. Vous devriez voir quelque chose
comme :
LoadModule rewrite_module libexec/apache2/mod_rewrite.so
Dans la plupart des systmes, ceux-ci vont tre comments donc vous aurez juste besoin de retirer les
symboles # en dbut de ligne.
Aprs que vous avez fait des changements, re-dmarrez Apache pour tre sr que les paramtres soient
actifs.
Vrifiez que vos fichiers .htaccess sont effectivement dans le bon rpertoire.
Cela peut arriver pendant la copie parce que certains systmes dexploitation traitent les fichiers qui
commencent par . en cach et du coup ne les voient pas pour les copier.
961
3. Assurez-vous que votre copie de CakePHP vient de la section des tlchargements du site de notre
dpt Git, et a t dzipp correctement en vrifiant les fichiers .htaccess.
Le rpertoire root de CakePHP (a besoin dtre copi dans votre document, cela redirige tout vers
votre app CakePHP) :
<IfModule mod_rewrite.c>
RewriteEngine on
[L]
RewriteRule
^$ app/webroot/
RewriteRule
(.*) app/webroot/$1 [L]
</IfModule>
Le rpertoire app de CakePHP (sera copi dans le rpertoire suprieur de votre application avec Bake) :
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule
^$
webroot/
RewriteRule
(.*) webroot/$1
</IfModule>
[L]
[L]
Le rpertoire webroot de CakePHP (sera copi dans le webroot de votre application avec Bake) :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
</IfModule>
Si votre site CakePHP a toujours des problmes avec mod_rewrite, essayez de modifier les
paramtres pour les Htes Virtuels. Si vous tes sur Ubuntu, modifiez le fichier /etc/apache2/sitesavailable/default (lendroit dpend de la distribution). Dans ce fichier, assurez-vous que
AllowOverride None a t chang en AllowOverride All, donc vous devez avoir :
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order Allow,Deny
Allow from all
</Directory>
Si vous tes sur Mac OSX, une autre solution est dutiliser loutil virtualhostx 4 pour faire un Hte
Virtuel pour pointer vers votre dossier.
Pour beaucoup de services dhbergement (GoDaddy, 1and1), votre serveur web est en fait dj distribu partir dun rpertoire utilisateur qui utilise dj mod_rewrite. Si vous installez CakePHP dans
un rpertoire utilisateur (http ://exemple.com/~username/cakephp/), ou toute autre structure dURL
qui utilise dj mod_rewrite, vous aurez besoin dajouter les requtes (statements) RewriteBase aux
fichiers .htaccess que CakePHP utilise (/.htaccess, /app/.htaccess, /app/webroot/.htaccess).
4. http ://clickontyler.com/virtualhostx/
962
Ceci peut tre ajout dans la mme section que la directive RewriteEngine, donc par exemple, votre
fichier .htaccess dans webroot ressemblerait ceci :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php/$1 [QSA,L]
</IfModule>
Les dtails de ces changements dpendront de votre configuration, et pourront inclure des choses
supplmentaires qui ne sont pas lies CakePHP. Merci de vous renseigner sur la documentation en
ligne dApache pour plus dinformations.
4. (Optionel) Pour amliorer la configuration de production, vous devriez empcher les assets invalides
dtre parss par CakePHP. Modifiez votre webroot .htaccess pour quelque chose comme :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/cake/app
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/(app/webroot/)?(img|css|js)/(.*)$
RewriteRule ^(.*)$ index.php [QSA,L]
</IfModule>
Ce qui est au-dessus va simplement empcher les assets incorrects dtre envoys index.php et la
place dafficher la page 404 de votre serveur web.
De plus, vous pouvez crer une page HTML 404 correspondante, ou utiliser la page 404 de CakePHP
intgre en ajoutant une directive ErrorDocument :
ErrorDocument 404 /404-not-found
nginx ne fait pas usage de fichiers .htaccess comme Apache et Lighttpd, il est donc ncessaire de crer les
URLs rcrites disponibles dans la configuration du site. selon votre configuration, vous devrez modifier
cela, mais tout le moins, vous aurez besoin de PHP fonctionnant comme une instance FastCGI.
server {
listen
80;
server_name www.example.com;
rewrite ^(.*) http://example.com$1 permanent;
}
server {
listen
80;
server_name example.com;
# root directive should be global
root
/var/www/example.com/public/app/webroot/;
963
index
index.php;
access_log /var/www/example.com/log/access.log;
error_log /var/www/example.com/log/error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
try_files $uri =404;
fastcgi_pass
127.0.0.1:9000;
fastcgi_index
index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Si pour une raison exotique vous ne pouvez pas changer votre rpertoire racine et devez lancer votre projet
partir dun sous-dossier comme example.com/subfolder/, vous devrez injecter /webroot dans chaque
requte.
location ~ ^/(subfolder)/(.*)? {
index index.php;
set $new_uri /$1/webroot/$2;
try_files $new_uri $new_uri/ /$1/index.php?$args;
... php handling ...
}
Note : Les rcentes configurations de PHP-FPM sont dfinies pour couter sur le socket php-fpm au lieu
du port TCP 9000 sur ladresse 127.0.0.1. Si vous obtenez une erreur 502 de mauvaise passerelle avec la
configuration du dessus, essayez de remplacer le port TCP du fastcgi_pass par le chemin du socket (ex :
fastcgi_pass unix :/var/run/php5-fpm.sock ;).
IIS7 ne supporte pas nativement les fichiers .htaccess. Bien quil existe des add-ons qui peuvent ajouter
ce support, vous pouvez aussi importer les rgles des .htaccess dans IIS pour utiliser les rewrites natifs de
CakePHP. Pour ce faire, suivez ces tapes :
1. Utilisez linstalleur de la plateforme Web de Microsoft 5 pour installer lURL Rewrite Module 2.0 6
ou tlchargez le directement (32-bit 7 / 64-bit 8 ).
2. Crez un nouveau fichier dans votre dossier CakePHP, appel web.config.
5.
6.
7.
8.
964
http ://www.microsoft.com/web/downloads/platform.aspx
http ://www.iis.net/downloads/microsoft/url-rewrite
http ://www.microsoft.com/en-us/download/details.aspx ?id=5747
http ://www.microsoft.com/en-us/download/details.aspx ?id=7435
3. Utilisez Notepad ou tout autre diteur XML-safe, copiez le code suivant dans votre nouveau fichier
web.config...
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Rewrite requests to test.php"
stopProcessing="true">
<match url="^test.php(.*)$" ignoreCase="false" />
<action type="Rewrite" url="app/webroot/test.php{R:1}" />
</rule>
<rule name="Exclude direct access to app/webroot/*"
stopProcessing="true">
<match url="^app/webroot/(.*)$" ignoreCase="false" />
<action type="None" />
</rule>
<rule name="Rewrite routed access to assets(img, css, files, js, favicon)"
stopProcessing="true">
<match url="^(img|css|files|js|favicon.ico)(.*)$" />
<action type="Rewrite" url="app/webroot/{R:1}{R:2}"
appendQueryString="false" />
</rule>
<rule name="Rewrite requested file/folder to index.php"
stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<action type="Rewrite" url="index.php"
appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
Une fois que le fichier web.config est cr avec les bonnes rgles de rcriture des liens de IIS, les liens
CakePHP, les CSS, le JavaScript, et le reroutage devraient fonctionner correctement.
URL-Rewriting sur lighttpd
Lighttpd ne supporte pas les fonctions .htaccess, par consquent vous pouvez retirer tous les fichiers .htaccess. Dans la configuration lighttpd, assurez-vous dactiver mod_rewrite. Ajoutez une ligne :
url.rewrite-if-not-file =(
"^([^\?]*)(\?(.+))?$" => "/index.php?url=$1&$3"
)
La rgle ncessaire UrlToolkit (pour le rewriting URL) pour utiliser CakePHP avec Hiawatha est :
965
UrlToolkit {
ToolkitID = cakephp
RequestURI exists Return
Match .* Rewrite /index.php
}
Si vous ne voulez ou ne pouvez pas utiliser lURL rewriting sur votre serveur web, rfrez-vous la section
core configuration.
Maintenant continuez sur Blog Tutoriel - Ajouter la logique pour commencer construire votre premire
application CakePHP.
La convention de nommage est vraiment trs importante dans CakePHP. En nommant notre model Post,
CakePHP peut automatiquement dduire que ce model sera utilis dans le controller PostsController, et sera
li la table posts de la base de donnes.
Note : CakePHP crera dynamiquement un objet model pour vous, sil ne trouve pas le fichier correspondant
dans /app/Model. Cela veut aussi dire que si vous navez pas nomm correctement votre fichier (par ex.
post.php ou posts.php au lieu de Post.php), CakePHP ne reconnatra pas votre configuration et utilisera ses
objets model par dfaut.
Pour plus dinformations sur les models, comme les prfixes des tables, les callbacks, et la validation, consultez le chapitre Models (Modles) du manuel.
966
models et o les tches lies aux posts sexcutent. Nous placerons ce nouveau controller dans un fichier appel PostsController.php lintrieur du dossier /app/Controller. Voici quoi devrait ressembler le controller de base
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
}
Maintenant, ajoutons une action notre controller. Les actions reprsentent souvent une simple fonction ou une interface dans une application. Par exemple, quand les utilisateurs requtent
www.exemple.com/posts/index (qui est la mme chose que www.exemple.com/posts/), ils pourraient sattendre voir une liste de posts. Le code pour cette action devrait ressembler quelque chose comme a
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
public function index() {
$this->set('posts', $this->Post->find('all'));
}
}
En dfinissant la fonction index() dans notre PostsController, les utilisateurs peuvent accder cette
logique en demandant www.exemple.com/posts/index. De la mme faon, si nous devions dfinir une fonction appele foobar(), les utilisateurs pourrait y accder en demandant www.exemple.com/posts/foobar.
Avertissement : Vous pourriez tre tent de nommer vos controllers et vos actions dune certaine
manire pour obtenir une certaine URL. Rsistez cette tentation. Suivez les conventions CakePHP
(le nom des controllers au pluriel, etc.) et nommez vos actions de faon lisible et comprhensible. Vous
pouvez lier les URLs votre code en utilisant ce quon appelle des routes, on le verra plus tard.
La seule instruction que cette action utilise est set(), pour transmettre les donnes du controller la vue
(que nous crerons la prochaine tape). La ligne dfinit la variable de vue appele posts qui est gale
la valeur de retour de la mthode find(all) du model Post. Notre model Post est automatiquement
disponible via $this->Post, parce que nous avons suivi les conventions de nommage de CakePHP.
Pour en apprendre plus sur les controllers de CakePHP, consultez le chapitre Controllers (Contrleurs).
967
Vous souvenez-vous, dans la dernire section, comment nous avions assign la variable posts la vue en
utilisant la mthode set() ? Cela devrait transmettre les donnes la vue qui ressemblerait quelque chose
comme cela
// print_r($posts) affiche:
Array
(
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => Le titre
[body] => Voici le contenu du post.
[created] => 2008-02-13 18:34:55
[modified] =>
)
)
[1] => Array
(
[Post] => Array
(
[id] => 2
[title] => Encore un titre
[body] => Et le contenu du post qui suit.
[created] => 2008-02-13 18:34:56
[modified] =>
)
)
[2] => Array
(
[Post] => Array
(
[id] => 3
[title] => Le retour du titre
[body] => C'est trs excitant, non ?
[created] => 2008-02-13 18:34:57
[modified] =>
)
)
)
Les fichiers des vues de CakePHP sont stocks dans /app/View lintrieur dun dossier dont le nom
correspond celui du controller (nous aurons crer un dossier appel Posts dans ce cas). Pour mettre en
forme les donnes de ces posts dans un joli tableau, le code de notre vue devrait ressembler quelque chose
comme cela
<!-- File: /app/View/Posts/index.ctp -->
<h1>Blog posts</h1>
<table>
<tr>
968
<th>Id</th>
<th>Titre</th>
<th>Cr le</th>
</tr>
<!-- Here is where we loop through our $posts array, printing out post info -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td>
<?php echo $this->Html->link($post['Post']['title'],
array('controller' => 'posts', 'action' => 'view', $post['Post']['id'])); ?>
</td>
<td><?php echo $post['Post']['created']; ?></td>
</tr>
<?php endforeach; ?>
<?php unset($post); ?>
</table>
Vous avez sans doute remarqu lutilisation dun objet appel $this->Html. Cest une instance de la
classe CakePHP HtmlHelper. CakePHP est livr avec un ensemble de helpers (des assistants) pour les
vues, qui ralisent en un clin dil des choses comme le linking (mettre les liens dans un texte), laffichage
des formulaires, du JavaScript et de lAJAX. Vous pouvez en apprendre plus sur la manire de les utiliser
dans le chapitre Helpers (Assistants), mais ce quil est important de noter ici, cest que la mthode link()
gnrera un lien HTML partir dun titre (le premier paramtre) et dune URL (le second paramtre).
Lorsque vous indiquez des URLs dans CakePHP, il est recommand dutiliser les tableaux. Ceci est expliqu
dans le chapitre des Routes. Utiliser les tableaux dans les URLs vous permet de tirer profit des capacits de
CakePHP r-inverser les routes. Vous pouvez aussi utiliser les URLs relatives depuis la base de lapplication comme suit /controller/action/param1/param2.
A ce stade, vous devriez tre en mesure de pointer votre navigateur sur la page
http ://www.exemple.com/posts/index. Vous devriez voir votre vue, correctement formate avec le
titre et le tableau listant les posts.
Si vous avez essay de cliquer sur lun des liens que nous avons crs dans cette vue (le lien sur le titre
dun post mne lURL : /posts/view/un_id_quelconque), vous avez srement t inform par CakePHP
que laction na pas encore t dfinie. Si vous navez pas t inform, soit quelque chose sest mal pass,
soit en fait vous aviez dj dfini laction, auquel cas vous tes vraiment sournois ! Sinon, nous allons la
crer sans plus tarder dans le Controller Posts
// File: /app/Controller/PostsController.php
class PostsController extends AppController {
public $helpers = array('Html', 'Form');
public function index() {
$this->set('posts', $this->Post->find('all'));
}
public function view($id = null) {
if (!$id) {
969
Lappel de set() devrait vous tre familier. Notez que nous utilisons findById() plutt que
find(all) parce que nous voulons seulement rcuprer les informations dun seul post.
Notez que notre action view prend un paramtre : lID du post que nous aimerions voir. Ce paramtre est
transmis laction grce lURL demande. Si un utilisateur demande /posts/view/3, alors la valeur 3 est
transmise la variable $id.
Nous faisons aussi une petite vrification derreurs pour nous assurer quun utilisateur accde bien lenregsitrement. Si un utilisateur requte /posts/view, nous lancerons un NotFoundException et laisserons le Gestionnaire dErreur de CakePHP ErrorHandler prendre le dessus. Nous excutons aussi une
vrification similaire pour nous assurer que lutilisateur a accde un enregistrement qui existe.
Maintenant, crons la vue pour
/app/View/Posts/view.ctp.
notre
nouvelle
action
view
et
plaons-la
dans
Vrifiez que cela fonctionne en testant les liens de la page /posts/index ou en affichant manuellement un
post via /posts/view/1.
970
Note : $this->request->is() prend un unique argument, qui peut tre la METHOD request (get,
put, post, delete) ou toute identifier de request (ajax). Ce nest pas une faon de vrifier une data
poste spcifique. Par exemple, $this->request->is(book) ne retournera pas true si les data du
book ont t postes.
Note : Vous avez besoin dinclure le component Flash (FlashComponent) et le helper Flash (FlashHelper)
dans chaque controller que vous utiliserez. Si ncessaire, incluez-les dans le controller principal (AppController) pour quils soient accessibles tous les controllers.
Voici ce que fait laction add() : si la requte HTTP est de type POST, essayez de sauvegarder les donnes
en utilisant le model Post. Si pour une raison quelconque, la sauvegarde a choue, affichez simplement la
vue. Cela nous donne une chance de voir les erreurs de validation de lutilisateur et dautres avertissements.
Chaque requte de CakePHP contient un objet CakeRequest qui est accessible en utilisant
$this->request. Cet objet contient des informations utiles sur la requte qui vient dtre reue,
et permet de contrler les flux de votre application. Dans ce cas, nous utilisons la mthode
CakeRequest::is() pour vrifier que la requte est de type POST.
Lorsquun utilisateur utilise un formulaire pour poster des donnes dans votre application, ces informations
sont disponibles dans $this->request->data. Vous pouvez utiliser les fonctions pr() ou debug()
pour les afficher si vous voulez voir quoi cela ressemble.
Nous utilisons la mthode FlashComponent::success() du component Flash (FlashComponent)
pour dfinir un message dans une variable session et qui sera affich dans la page juste aprs la redirection.
Dans le layout, nous trouvons la fonction FlashHelper::render() qui permet dafficher et de nettoyer
la variable correspondante. La mthode Controller::redirect du controller permet de rediriger vers
971
une autre URL. Le paramtre array(action => index) sera traduit vers lURL /posts (dans
notre cas laction index du controller Posts). Vous pouvez vous rfrer la fonction Router::url()
dans lAPI 9 pour voir les diffrents formats dURL accepts dans les diffrentes fonctions de CakePHP.
Lappel de la mthode save() vrifiera les erreurs de validation et interrompra lenregistrement si une
erreur survient. Nous verrons la faon dont les erreurs sont traites dans les sections suivantes.
Nous appelons la mthode create() en premier afin de rinitialiser ltat du model pour sauvegarder
les nouvelles informations. Cela ne cre pas rellement un enregistrement dans la base de donnes mais
rinitialise Model : :$id et dfinit Model : :$data en se basant sur le champ par dfaut dans votre base de
donnes.
Nous utilisons le FormHelper pour gnrer la balise douverture dune formulaire HTML. Voici le code
HTML gnr par $this->Form->create()
.. code-block:: html
972
Vous vous demandez peut-tre : comment je fais pour indiquer CakePHP mes exigences de validation ?
Les rgles de validation sont dfinies dans le model. Retournons donc notre model Post et procdons
quelques ajustements
class Post extends AppModel {
public $validate = array(
'title' => array(
'rule' => 'notBlank'
),
'body' => array(
'rule' => 'notBlank'
)
);
}
Le tableau $validate indique CakePHP comment valider vos donnes lorsque la mthode save()
est appele. Ici, jai spcifi que les deux champs body et title ne doivent pas tre vides. Le moteur
de validation de CakePHP est puissant, il dispose dun certain nombre de rgles intgres (code de carte
bancaire, adresse emails, etc.) et dune souplesse pour ajouter vos propres rgles de validation. Pour plus
dinformations sur cette configuration, consultez le chapitre Validation des Donnes.
Maintenant que vos rgles de validation sont en place, utilisez lapplication pour essayer dajouter un post
avec un titre et un contenu vide afin de voir comment cela fonctionne. Puisque que nous avons utilis la
mthode FormHelper::input() du helper Form pour crer nos lments de formulaire, nos messages derreurs de validation seront affichs automatiquement.
973
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
if ($this->request->is(array('post', 'put'))) {
$this->Post->id = $id;
if ($this->Post->save($this->request->data)) {
$this->Flash->success(__('Your post has been updated.'));
return $this->redirect(array('action' => 'index'));
}
$this->Flash->error(__('Unable to update your post.'));
}
if (!$this->request->data) {
$this->request->data = $post;
}
}
Cette action sassure dabord que lutilisateur a essay daccder un enregistrement existant. Sil ny a pas
de paramtre $id pass, ou si le post nexiste pas, nous lanons une NotFoundException pour que le
gestionnaire dErreurs ErrorHandler de CakePHP sen occupe.
Ensuite laction vrifie si la requte est une requte POST ou PUT. Si elle lest, alors nous utilisons les
donnes POST pour mettre jour notre enregistrement Post, ou sortir et montrer les erreurs de validation
lutilisateur.
Sil ny a pas de donnes dfinies dans $this->request->data, nous le dfinissons simplement dans
le post rcupr prcdemment.
La vue ddition devrait ressembler quelque chose comme cela :
<!-- Fichier: /app/View/Posts/edit.ctp -->
<h1>Editer le post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->input('id', array('type' => 'hidden'));
echo $this->Form->end('Save Post');
?>
Cette vue affiche le formulaire ddition (avec les donnes pr-remplies) avec les messages derreur de
validation ncessaires.
Une chose noter ici : CakePHP supposera que vous ditez un model si le champ id est prsent dans le
tableau de donnes. Sil nest pas prsent (ce qui revient notre vue add), CakePHP supposera que vous
insrez un nouveau model lorsque save() sera appele.
Vous pouvez maintenant mettre jour votre vue index avec des liens pour diter des posts :
<!-- Fichier: /app/View/Posts/index.ctp
<h1>Blog posts</h1>
974
975
}
return $this->redirect(array('action' => 'index'));
}
Cette logique supprime le Post spcifi par $id, et utilise $this->Flash->success() pour afficher
lutilisateur un message de confirmation aprs lavoir redirig sur /posts. Si lutilisateur tente une suppression en utilisant une requte GET, une exception est leve. Les exceptions manques sont captures par
le gestionnaire dexceptions de CakePHP et un joli message derreur est affich. Il y a plusieurs Exceptions
intgres qui peuvent tre utilises pour indiquer les diffrentes erreurs HTTP que votre application pourrait
rencontrer.
Etant donn que nous excutons juste un peu de logique et de redirection, cette action na pas de vue. Vous
voudrez peut-tre mettre jour votre vue index avec des liens pour permettre aux utilisateurs de supprimer
des Posts, ainsi :
<!-- Fichier: /app/View/Posts/index.ctp -->
<h1>Blog posts</h1>
<p><?php echo $this->Html->link(
'Ajouter un Post',
array('action' => 'add')
); ?></p>
<table>
<tr>
<th>Id</th>
<th>Titre</th>
<th>Actions</th>
<th>Cr le</th>
</tr>
<!-- Ici, nous bouclons sur le tableau $post afin d'afficher les informations des posts -->
<?php foreach ($posts as $post): ?>
<tr>
<td><?php echo $post['Post']['id']; ?></td>
<td>
<?php echo $this->Html->link(
$post['Post']['title'],
array('action' => 'view', $post['Post']['id'])
); ?>
</td>
<td>
<?php echo $this->Form->postLink(
'Supprimer',
array('action' => 'delete', $post['Post']['id']),
array('confirm' => 'Etes-vous sr ?'));
?>
<?php echo $this->Html->link(
'Editer',
array('action' => 'edit', $post['Post']['id'])
); ?>
</td>
976
<td>
<?php echo $post['Post']['created']; ?>
</td>
</tr>
<?php endforeach; ?>
</table>
Utiliser postLink() permet de crer un lien qui utilise du Javascript pour supprimer notre post en faisant
une requte POST. Autoriser la suppression par une requte GET est dangereux cause des robots dindexation qui peuvent tous les supprimer.
Note : Ce code utilise aussi le helper Form pour demander lutilisateur une confirmation avant de
supprimer le post.
Routes
Pour certains, le routage par dfaut de CakePHP fonctionne suffisamment bien. Les dveloppeurs qui sont
sensibles la facilit dutilisation et la compatibilit avec les moteurs de recherches apprcieront la manire
dont CakePHP lie des URLs des actions spcifiques. Nous allons donc faire une rapide modification des
routes dans ce tutoriel.
Pour plus dinformations sur les techniques de routages, consultez le chapitre Configuration des Routes.
Par dfaut, CakePHP effectue une redirection dune personne visitant la racine de votre site (par ex :
http ://www.exemple.com) vers le controller Pages (PagesController) et affiche le rendu de la vue appele
home. Au lieu de cela, nous voudrions la remplacer avec notre controller Posts (PostsController).
Le routage de CakePHP se trouve dans /app/Config/routes.php. Vous devrez commenter ou supprimer la ligne qui dfinit la route par dfaut. Elle ressemble cela
Router::connect(
'/',
array('controller' => 'pages', 'action' => 'display', 'home')
);
Cette ligne connecte lURL / la page daccueil par dfaut de CakePHP. Nous voulons que cette URL soit
connecte notre propre controller, remplacez donc la ligne par celle-ci
Router::connect('/', array('controller' => 'posts', 'action' => 'index'));
Cela devrait connecter les utilisateurs demandant / laction index() de notre controller Posts
(PostsController).
Note : CakePHP peut aussi faire du reverse routing (ou routage invers). Par exemple, pour la route
dfinie plus haut, en ajoutant array(controller => posts, action => index)
la fonction retournant un tableau, lURL / sera utilise. Il est dailleurs bien avis de toujours utiliser un
tableau pour les URLs afin que vos routes dfinissent o vont les URLs, mais aussi pour sassurer quelles
aillent dans la mme direction.
977
Conclusion
Crer des applications de cette manire vous apportera, paix, honneur, amour et argent au-del mme de vos
fantasmes les plus fous. Simple nest ce pas ? Gardez lesprit que ce tutoriel tait trs basique. CakePHP
a beaucoup plus de fonctionnalits offrir et il est aussi souple dans dautres domaines que nous navons
pas souhait couvrir ici pour simplifier les choses. Utilisez le reste de ce manuel comme un guide pour
dvelopper des applications plus riches en fonctionnalits.
Maintenant que vous avez cr une application CakePHP basique, vous tes prt pour les choses srieuses.
Commencez votre propre projet et lisez le reste du Cookbook et lAPI 10 .
Si vous avez besoin daide, il y a plusieurs faons dobtenir de laide - merci de regarder la page O obtenir
de laide Bienvenue sur CakePHP !
Prochaines lectures suggres
Voici les diffrents chapitres que les gens veulent souvent lire aprs :
1. Layouts : Personnaliser les Layouts de votre application.
2. Elements : Inclure et r-utiliser les portions de vues.
3. Scaffolding : Construire une bauche dapplication sans avoir coder.
4. Gnration de code avec Bake Gnrer un code CRUD basique.
5. Authentification Simple et Autorisation de lApplication : Tutoriel sur lenregistrement et la connexion
dutilisateurs.
978
Nous avons respect les conventions de CakePHP pour le nommage des tables, mais nous profitons dune
autre convention : en utilisant les colonnes du nom duser et du mot de passe dans une table users, CakePHP
sera capable de configurer automatiquement la plupart des choses pour nous quand on ralisera la connexion
de luser.
La prochaine tape est de crer notre model User, qui a la responsablilit de trouver, sauvegarder et valider
toute donne duser :
// app/Model/User.php
App::uses('AppModel', 'Model');
class User extends AppModel {
public $name = 'User';
public $validate = array(
'username' => array(
'required' => array(
'rule' => 'notBlank',
'message' => 'Un nom d\'utilisateur est requis'
)
),
'password' => array(
'required' => array(
'rule' => 'notBlank',
'message' => 'Un mot de passe est requis'
)
),
'role' => array(
'valid' => array(
'rule' => array('inList', array('admin', 'auteur')),
'message' => 'Merci de rentrer un rle valide',
'allowEmpty' => false
)
)
);
}
Creons aussi notre UsersController, le contenu suivant correspond la classe cuisine basique UsersController en utilisant les utilitaires de gnration de code fournis avec CakePHP :
// app/Controller/UsersController.php
class UsersController extends AppController {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add', 'logout');
}
public function index() {
$this->User->recursive = 0;
$this->set('users', $this->paginate());
}
public function view($id = null) {
979
if (!$this->User->exists($id)) {
throw new NotFoundException(__('User invalide'));
}
$this->set('user', $this->User->findById($id));
}
980
votre
application,
ouvrez
app/Controller/AppController.php et ajoutez les lignes suivantes :
votre
fichier
// app/Controller/AppController.php
class AppController extends Controller {
//...
981
Il ny a pas grand chose configurer, puisque nous avons utilis les conventions pour la table des users. Nous
avons juste configur les URLs qui seront charges aprs que la connexion et la dconnexion des actions
sont effectues, dans notre cas, respectivement /posts/ et /.
Ce que nous avons fait dans la fonction beforeFilter a t de dire au AuthComponent de ne pas exiger
un login pour toutes les actions index et view, dans chaque controller. Nous voulons que nos visiteurs
soient capables de lire et lister les entres sans sinscrire dans le site.
Maintenant, nous avons besoin dtre capable dinscrire des nouveaux users, de sauvegarder leur nom duser
et mot de passe, et plus important de hasher leur mot de passe afin quil ne soit pas stock en texte plain
dans notre base de donnes. Disons AuthComponent de laisser des users non-authentifis daccder la
fonction add des users et de raliser laction connexion et deconnexion :
// app/Controller/UsersController.php
public function beforeFilter() {
parent::beforeFilter();
// Permet aux utilisateurs de s'enregistrer et de se dconnecter
$this->Auth->allow('add', 'logout');
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Flash->error(__("Nom d'user ou mot de passe invalide, ressayer"));
}
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
Le hash du mot de passe nest pas encore fait, ouvrez votre fichier de model app/Model/User.php et
ajoutez ce qui suit :
// app/Model/User.php
App::uses('AppModel', 'Model');
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
// ...
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$passwordHasher = new SimplePasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
982
}
return true;
}
// ...
Ainsi, maintenant chaque fois quun user est sauvegard, le mot de passe est hash en utilisant la classe
SimplePasswordHasher. Il nous manque juste un fichier template de vue pour la fonction de connexion :
//app/View/Users/login.ctp
<div class="users form">
<?php echo $this->Flash->render('auth'); ?>
<?php echo $this->Form->create('User'); ?>
<fieldset>
<legend>
<?php echo __('Please enter your username and password'); ?>
</legend>
<?php echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(__('Login')); ?>
</div>
Vous pouvez maintenant inscrire un nouvel user en rentrant lURL /users/add et vous connecter avec
ce profil nouvellement cr en allant sur lURL /users/login. Essayez aussi daller sur nimporte quel
URL qui na pas t explicitement autorise telle que /posts/add, vous verrez que lapplication vous
redirige automatiquement vers la page de connexion.
Et cest tout ! Cela semble trop simple pour tre vrai. Retournons en arrire un peu pour expliquer ce qui
sest pass. La fonction beforeFilter dit au component AuthComponent de ne pas exiger de connexion pour laction add en plus des actions index et view qui taient dj autorises dans la fonction
beforeFilter de lAppController.
Laction login appelle la fonction $this->Auth->login() dans AuthComponent, et cela fonctionne
sans autre config car nous suivons les conventions comme mentionnes plus tt. Cest--dire, avoir un model
User avec les colonnes username et password, et utiliser un formulaire post un controller avec les donnes
duser. Cette fonction retourne si la connexion a russi ou non, et en cas de succs, alors nous redirigeons
luser vers lURL configur de redirection que nous utilisions quand nous avons ajout AuthComponent
notre application.
La dconnexion fonctionne juste en allant lURL /users/logout et redirigera luser vers
lUrl de Dconnexion configure dcrite prcedemment. Cette URL est le rsultat de la fonction
AuthComponent::logout() en cas de succs.
983
Aussi, un petit changement dans PostsController est ncessaire pour stocker luser connect courant en
rfrence pour le post cr :
// app/Controller/PostsController.php
public function add() {
if ($this->request->is('post')) {
$this->request->data['Post']['user_id'] = $this->Auth->user('id'); //Ligne ajoute
if ($this->Post->save($this->request->data)) {
$this->Flash->success(__('Votre post a t sauvegard.'));
$this->redirect(array('action' => 'index'));
}
}
}
La fonction user() fournie par le component retourne toute colonne partir de luser connect courant.
Nous avons utilis cette mthode pour ajouter les donnes dans les infos requtes qui sont sauvegardes.
Scurisons maintenant notre app pour empcher certains auteurs de modifier ou supprimer les posts des
autres. Des rgles basiques pour notre app sont que les users admin peuvent accder tout URL, alors que
les users normaux (le role auteur) peuvent seulement accder aux actions permises. Ouvrez encore la classe
AppController et ajoutez un peu plus doptions la config de Auth :
// app/Controller/AppController.php
public $components = array(
'Flash',
'Auth' => array(
'loginRedirect' => array('controller' => 'posts', 'action' => 'index'),
'logoutRedirect' => array(
'controller' => 'pages',
'action' => 'display',
'home'
),
'authenticate' => array(
'Form' => array(
'passwordHasher' => 'Blowfish'
)
),
'authorize' => array('Controller') // Ajout de cette ligne
)
);
public function isAuthorized($user) {
// Admin peut accder toute action
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
// Refus par dfaut
return false;
}
984
Nous venons de crer un mcanisme trs simple dautorisation. Dans ce cas, les users avec le role admin
sera capable daccder tout URL dans le site quand ils sont connects, mais les autres (par ex le role
auteur) ne peut rien faire dautre par rapport aux users non connects.
Ce nest pas exactement ce que nous souhaitions, donc nous avons besoin de dterminer et fournir plus de
rgles notre mthode isAuthorized(). Mais plutt que de le faire dans AppController, dleguons
chaque controller la fourniture de ces rgles supplmentaires. Les rgles que nous allons ajouter PostsController permettront aux auteurs de crer des posts mais empcheront ldition des posts si lauteur ne correspond pas. Ouvrez le fichier PostsController.php et ajoutez le contenu suivant :
// app/Controller/PostsController.php
public function isAuthorized($user) {
// Tous les users inscrits peuvent ajouter les posts
if ($this->action === 'add') {
return true;
}
// Le propritaire du post peut l'diter et le supprimer
if (in_array($this->action, array('edit', 'delete'))) {
$postId = (int) $this->request->params['pass'][0];
if ($this->Post->isOwnedBy($postId, $user['id'])) {
return true;
}
}
return parent::isAuthorized($user);
}
Ceci conclut notre tutoriel simple sur lauthentification et les autorisations. Pour scuriser lUsersController,
vous pouvez suivre la mme technique que nous faisions pour PostsController, vous pouvez aussi tre plus
cratif et coder quelque chose de plus gnral dans AppController bas sur vos propres rgles.
Si vous avez besoin de plus de contrle, nous vous suggrons de lire le guide complet Auth dans la section Authentification o vous en trouverez plus sur la configuration du component, la cration de classes
dautorisation personnalise, et bien plus encore.
985
Une fois que vous avez votre copie toute rcente de CakePHP, changez votre branche vers la dernire version
de 2.0, configurez votre fichier database.php et changez la valeur du Security.salt (grain de scurit)
dans votre fichier app/Config/core.php. A ce stade, nous construirons un schma simple de base
de donnes sur lequel btir notre application. Excutez les commandes SQL suivantes sur votre base de
donnes :
11. http ://git-scm.com/
986
Ce sont les tables que nous utiliserons pour construire le reste de notre application. Une fois que nous avons
la structure des tables dans notre base de donnes, nous pouvons commencer cuisiner. Utilisez Gnration
de code avec Bake pour crer rapidement vos models, controllers et vues.
Pour utiliser cake bake, appelez cake bake all et cela listera les 4 tables que vous avez inser dans
MySQL. Slctionnez 1. Group, et suivez ce qui est crit sur lcran. Rptez pour les 3 autres tables, et
cela gnrera les 4 controllers, models et vues pour vous.
Evitez dutiliser le Scaffold ici. La gnration des ACOs en sera srieusement affecte si vous cuisinez les
controllers avec la fonctionnalit Scaffold.
Pendant la cuisson des Models, cake dtectera auto-magiquement les associations entre vos Models (ou
relations entre vos tables). Laissez CakePHP remplir les bonnes associations hasMany et belongsTo. Si vous
tes invit choisir hasOne ou hasMany, dune manire gnrale, vous aurez besoin dune relation hasMany
(seulement) pour ce tutoriel.
Laissez de ct les routing admin pour le moment, cest dj un assez compliqu sujet comme cela sans eux.
Assurez-vous aussi de ne pas ajouter les Components Acl et Auth aucun de vos controllers quand vous les
cuisinez. Nous le ferons bien assez tt. Vous devriez maintenant avoir des models, controllers, et des vues
cuisins pour vos users, groups, posts et widgets.
987
Ensuite nous devrons mettre jour notre model User pour hasher les passwords avant quils aillent dans
la base de donnes. Stocker les passwords en brut est extrmement non scuris et AuthComponent va
sattendre ce que vos passwords soient hashs. Dans app/Model/User.php ajoutez ce qui suit :
App::uses('AuthComponent', 'Controller/Component');
class User extends AppModel {
// autre code.
Ensuite nous devons faire quelques modifications dans AppController. Si vous navez pas
/app/Controller/AppController.php, crez le. Puisque nous voulons que notre site entier soit
contrll avec Auth et Acl, nous allons les dfinir en haut dans AppController :
class AppController extends Controller {
public $components = array(
'Acl',
'Auth' => array(
988
Avant de configurer ACL, nous aurons besoin dajouter quelques users et groups. Avec AuthComponent
en utilisation, nous ne serons pas capable daccder aucune de nos actions, puisque nous ne sommes pas
connects. Nous allons maintenant ajouter quelques exceptions ainsi AuthComponent va nous autoriser
crer quelques groups et users. Dans les deux, votre GroupsController et votre UsersController,
ajoutez ce qui suit :
public function beforeFilter() {
parent::beforeFilter();
// Pour CakePHP 2.0
$this->Auth->allow('*');
// Pour CakePHP 2.1 et suprieurs
$this->Auth->allow();
}
Ces lignes disent AuthComponent dautoriser les accs publiques toutes les actions. Cest seulement
temporaire et ce sera retir une fois que nous aurons quelques users et groups dans notre base de donnes.
Najoutez pourtant encore aucun user ou group.
989
Ce schma vous invite supprimer et crer les tables. Rpondez Oui (Yes) la suppression et cration des
tables.
Si vous navez pas daccs au shell, ou si vous avez des problmes pour utiliser la console, vous pouvez excuter le fichier sql se trouvant lemplacement suivant : /chemin/vers/votre/app/Config/Schema/db_acl.sql.
Avec les controllers configurs pour lentre de donnes et les tables Acl initialises, nous sommes prts
commencer, nest-ce-pas ? Pas tout fait, nous avons encore un peu de travail faire dans les models users
et groups. Concrtement, faire quils sattachent auto-magiquement lAcl.
Cela permet de lier les models Group et User lAcl, et de dire CakePHP que chaque fois que lon cr
un User ou un Group, nous voulons galement ajouter une entre dans la table aros. Cela fait de la gestion
990
des Acl un jeu denfant, puisque vos AROs se lient de faon transparente vos tables users et groups.
Ainsi, chaque fois que vous crez ou supprimez un groupe/user, la table Aro est mise jour.
Nos controllers et models sont maintenant prts recevoir des donnes initiales et nos models Group et
User sont relis la table Acl. Ajoutez donc quelques groups et users en utilisant les formulaires crs avec
Bake en allant sur http ://exemple.com/groups/add et http ://exemple.com/users/add. Jai cr les groups
suivants :
administrateurs
managers
users
Jai galement cr un user dans chaque groupe, de faon avoir un user de chaque niveau daccs pour les
tests ultrieurs. Ecrivez tout sur du papier ou utilisez des mots de passe faciles, de faon ne pas les oublier.
Si vous faites un SELECT * FROM aros ; depuis une commande MySQL, vous devriez recevoir quelque
chose comme cela :
+----+-----------+-------+-------------+-------+------+------+
| id | parent_id | model | foreign_key | alias | lft | rght |
+----+-----------+-------+-------------+-------+------+------+
| 1 |
NULL | Group |
1 | NULL |
1 |
4 |
| 2 |
NULL | Group |
2 | NULL |
5 |
8 |
| 3 |
NULL | Group |
3 | NULL |
9 |
12 |
| 4 |
1 | User |
1 | NULL |
2 |
3 |
| 5 |
2 | User |
2 | NULL |
6 |
7 |
| 6 |
3 | User |
3 | NULL |
10 |
11 |
+----+-----------+-------+-------------+-------+------+------+
6 rows in set (0.00 sec)
Cela nous montre que nous avons 3 groups et 3 users. Les users sont imbriqus dans les groups, ce qui
signifie que nous pouvons dfinir des permissions sur une base par groupe ou par user.
ACL bas uniquement sur les groupes
Dans la cas o nous souhaiterions simplifier en utilisant les permissions par groups, nous avons besoin
dimplmenter bindNode() dans le model User :
public function bindNode($user) {
return array('model' => 'Group', 'foreign_key' => $user['User']['group_id']);
}
Ces deux changements vont dire ACL de ne pas vrifier les Aros des User Aros et de vrifier seulement
les Aros de Group.
Note : Chaque user devra tre assign un group_id pour que ceci fontionne correctement.
Maintenant la table aros va ressembler ceci :
991
+----+-----------+-------+-------------+-------+------+------+
| id | parent_id | model | foreign_key | alias | lft | rght |
+----+-----------+-------+-------------+-------+------+------+
| 1 |
NULL | Group |
1 | NULL |
1 |
2 |
| 2 |
NULL | Group |
2 | NULL |
3 |
4 |
| 3 |
NULL | Group |
3 | NULL |
5 |
6 |
+----+-----------+-------+-------------+-------+------+------+
3 rows in set (0.00 sec)
Note : Si vous avez suivi le tutoriel jusquici, vous devez effacer vos tables, y compris aros, groups et
users, et crer les tables groups et users nouveau de zro pour obtenir la table aros ci-dessus.
Ces deux exemples vont crer notre root ou ACO de plus haut niveau, qui sera appel controllers. Lobjectif
de ce nud root est dautoriser/interdire laccs lchelle globale de lapplication, et permet lutilisation
de lAcl dans des objectifs non lis aux controllers/actions, tels que la vrification des permissions dun
enregistrement dun model. Puisque nous allons utiliser un ACO root global, nous devons faire une petite
modification la configuration de AuthComponent. LAuthComponent doit tre renseign sur lexistence de ce nud root, de sorte que lors des contrles de lACL, le component puisse utiliser le bon chemin
de nud lors de la recherche controllers/actions. Dans lAppController, assurez vous que le tableau
$components contient lactionPath dfini avant :
class AppController extends Controller {
public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
'Session'
);
992
Continuez Application Simple contrle par Acl - partie 2 pour continuer le tutoriel.
Vous pouvez rcuprer un guide complet pour toutes les commandes disponibles comme ceci :
./Console/cake AclExtras.AclExtras -h
./Console/cake AclExtras.AclExtras aco_sync -h
Une fois remplie, votre table acos permet de crer les permissions de votre application.
993
$this->Acl->allow($aroAlias, $acoAlias);
Nous allons maintenant ajouter un peu dautorisations/interdictions. Ajoutez ce qui suit une fonction temporaire dans votre UsersController et visitez ladresse dans votre navigateur pour les lancer (par ex :
http ://localhost/cake/app/users/initdb). Si vous fates un SELECT * FROM aros_acos, vous devriez
voir une pile entire de 1 et -1. Une fois que vous avez confirm, vos permissions sont configures, retirez
la fonction :
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('initDB'); // Nous pouvons supprimer cette ligne aprs avoir fini
}
public function initDB() {
$group = $this->User->Group;
// Autorise l'accs tout pour les admins
$group->id = 1;
$this->Acl->allow($group, 'controllers');
// Autorise l'accs aux posts et widgets pour les managers
$group->id = 2;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Posts');
$this->Acl->allow($group, 'controllers/Widgets');
// Autorise l'accs aux actions add et edit des posts widgets pour les utilisateurs de
$group->id = 3;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Posts/add');
$this->Acl->allow($group, 'controllers/Posts/edit');
$this->Acl->allow($group, 'controllers/Widgets/add');
$this->Acl->allow($group, 'controllers/Widgets/edit');
// Permet aux utilisateurs classiques de se dconnecter
$this->Acl->allow($group, 'controllers/users/logout');
// Nous ajoutons un exit pour viter d'avoir un message d'erreur affreux "missing views
echo "tout est ok";
exit;
}
Nous avons maintenant configurer quelques rgles basiques. Nous avons autoris les administrateurs pour
tout. Les Manageurs peuvent accder tout dans posts et widgets. Alors que les users peuvent accder aux
add et edit des posts & widgets.
Nous devions avoir une rfrence dun model de Group et modifier son id pour tre capable de spcifier
lARO que nous voulons, cela est d la faon dont fonctionne AclBehavior. AclBehavior ne configure pas le champ alias dans la table aros donc nous devons utiliser une rfrence dobjet ou un tableau
pour rfrencer lARO que lon souhaite.
Vous avez peut-tre remarqu que jai dlibrement oubli index et view des permissions Acl. Nous allons faire des actions publiques index et view dans PostsController et WidgetsController. Cela
994
donne aux users non-autoriss lautorisation de voir ces pages, en rendant ces pages publiques. Cependant,
tout moment, vous pouvez retirer ces actions des AuthComponent::allowedActions et les permissions pour view et edit seront les mmes que celles dans Acl.
Maitenant, nous voulons enlever les rfrences de Auth->allowedActions dans les controllers de vos
users et groups. Ensuite ajouter ce qui suit aux controllers de vos posts et widgets :
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('index', 'view');
}
Cela enlve le basculement off que nous avions mis plus tt dans les controllers users et groups
et cela rend public laccs aux actions index et voir dans les controllers Posts et Widgets. Dans
AppController::beforeFilter() ajoutez ce qui suit :
$this->Auth->allow('display');
Ce qui rend laction display publique. Cela rendra notre action PagesController : :display() publique. Ceci
est important car le plus souvent le routage par dfaut dsigne cette action comme page daccueil de votre
application.
Connexion
Notre application est dsormais sous contrle daccs, et toute tentative daccs des pages non publiques
vous redirigera vers la page de connexion. Cependant, vous devrez crer une vue login avant que quelquun
puisse se connecter. Ajoutez ce qui suit app/View/Users/login.ctp si vous ne lavez pas dj fait :
<h2>Connexion</h2>
<?php
echo $this->Form->create('User', array('url' => array('controller' => 'users', 'action' =>
echo $this->Form->input('User.nom_user');
echo $this->Form->input('User.mot_de_passe');
echo $this->Form->end('Connexion');
?>
Vous devriez tre maintenant capable de vous connecter et tout devrait fonctionner auto-maigiquement.
Quand laccs est refus, les messages de Auth seront affichs si vous ajoutez le code echo
$this->Session->flash(auth).
995
Dconnexion
Abordons maintenant la dconnexion. Nous avions plus tt laiss cette fonction vide, il est maintenant temps
de la remplir. Dans UsersController::logout() ajoutez ce qui suit
$this->Session->setFlash('Au-revoir');
return $this->redirect($this->Auth->logout());
Cela dfinit un message flash en Session et dconnecte lUser en utilisant la mthode logout de Auth. La
mthode logout de Auth supprime tout simplement la cl dauthentification en session et retourne une URL
qui peut tre utilise dans une redirection. Si il y a dautres donnes en sessions qui doivent tre galement
effaces, ajoutez le code ici.
Cest fini !
Vous devriez maintenant avoir une application contrle par Auth et Acl. Les permissions Users sont dfinies
au niveau du groupe, mais on peut galement les dfinir en mme temps par user. Vous pouvez galement
dfinir les permissions sur une base globale ou par controller et par action. De plus, vous avez un bloc de
code rutilisable pour tendre facilement vos tables ACO lorsque votre application grandit.
996
CHAPITRE 16
Contribuer
Il y a un certain nombre de moyens pour contribuer CakePHP. Les sections suivantes couvrent les diffrentes faons avec lesquelles vous pouvez contribuer CakePHP :
Documentation
Contribuer la documentation est simple. Les fichiers sont hbergs sur https ://github.com/cakephp/docs.
Nhsitez pas forker le dpt, ajoutez vos changements/amliorations/traductions et retournez les avec un
pull request. Vous pouvez mme modifier les documents en ligne avec github, sans tlcharger les fichiers
le bouton Improve this Doc (Amliorer cette Doc) sur toutes les pages vous redirigera vers lditeur en
ligne de Github pour la page correspondante.
La documentation de CakePHP est intgre de faon continue 1 , donc vous pouvez vrifier le statut des
diffrents builds 2 sur le serveur Jenkins tout moment.
Traductions
Envoyez un Email lquipe docs (docs at cakephp dot org) ou venez discuter sur IRC (#cakephp on freenode) de tout effort de traduction auquel vous souhaitez participer.
Nouvelle Traduction dune Langue
Nous souhaitons crer des traductions aussi compltes que possible. Cependant, il peut arriver des fois o un
fichier de traduction nest pas jour. Vous devriez toujours considrer la version anglais comme la version
qui fait autorit.
Si votre langue nest pas dans les langues actuellement proposes, merci de nous contacter sur Github et nous
envisagerons de crer un squelette de dossier pour cette langue. Les sections suivantes sont les premires
par lesquelles vous devriez commencer puisque ce sont des fichiers qui ne changent pas souvent :
1. http ://en.wikipedia.org/wiki/Continuous_integration
2. http ://ci.cakephp.org
997
index.rst
cakephp-overview.rst
getting-started.rst
installation.rst
dossier /installation
dossier /getting-started
dossier /tutorials-and-examples
Astuces de traducteurs
Parcourez et modifiez le contenu traduire dans le langage voulu - sinon vous ne verrez pas ce qui a dj
t traduit.
Nhsitez pas plonger droit dans votre langue qui existe dj dans le livre.
998
Documentation
999
Le balisage interne
Un astrisque : text pour une accentuation (italiques)
*text*
Two asterisks : text pour une forte accentuation (caractres gras)
**text**
Two backquotes : text pour les exemples de code
text
Si les astrisques ou les backquotes apparaissent dans le texte et peuvent tre confondus avec les dlimiteurs
du balisage interne, ils doivent tre chapps avec un backslash.
Le balisage interne a quelques restrictions :
Il ne doit pas tre imbriqu.
Le contenu ne doit pas commencer ou finir avec un espace : * text* est mauvais.
Le contenu doit tre spar du texte environnant par des caractres qui ne sont pas des mots. Utilisez un
backslash pour chapper pour rgler le problme : unmot\ *engras*\ long.
Listes
La liste du balisage est trs similaire celle de markdown. Les listes non ordonnes commencent par
une ligne avec un unique astrisque et un espace. Les listes numrotes peuvent tre cres avec, soit les
numros, soit # pour une numrotation automatique :
* C'est une balle
* Ici aussi. Mais cette ligne
a deux lignes.
1. Premire ligne
2. Deuxime ligne
#. Numrotation automatique
#. Va vous faire conomiser du temps.
Les listes indentes peuvent aussi tre cres, en indentant les sections et en les sparant avec une ligne
vide :
* Premire ligne
* Deuxime ligne
* Allez plus profondment
* Whoah
* Retour au premier niveau.
Les listes avec dfinitions peuvent tre cres en faisant ce qui suit :
term
dfinition
CakePHP
Un framework MVC pour PHP
1000
Les termes ne peuvent pas tre sur plus dune ligne, mais les dfinitions peuvent tre multi-lignes et toutes
les lignes doivent toujours tre indentes.
Liens
Il y a plusieurs types de liens, chacun avec ses propres utilisations.
Liens externes
Les liens vers les documents externes peuvent tre les suivants :
`Lien externe <http://exemple.com>`_
:doc:
Les autres pages de la documentation peuvent tre lies en utilisant le modle :doc:. Vous pouvez
faire un lien un document spcifique en utilisant, soit un chemin de rfrence absolu ou relatif. Vous
pouvez omettre lextension .rst. Par exemple, si la rfrence :doc:form apparait dans le document core-helpers/html, alors le lien de rfrence core-helpers/form. Si la rfrence
tait :doc:/core-helpers il serait en rfrence avec /core-helpers sans soucis de o
il a t utilis.
Les liens croiss de rfrencement
:ref:
Vous pouvez recouper un titre quelconque dans nimporte quel document en utilisant le modle :ref:. Le label de la cible lie doit tre unique travers lentire documentation. Quand on
cre les labels pour les mthodes de classe, il vaut mieux utiliser class-method comme format
pour votre label de lien.
Lutilisation la plus commune des labels est au-dessus dun titre. Exemple :
.. _nom-label:
Section en-t\te
--------------Plus de contenu ici.
6. http ://example.com
Documentation
1001
Sphinx va afficher des avertissements si un fichier nest pas rfrenc dans un toc-tree. Cest un bon moyen
de sassurer que tous les fichiers ont un lien point vers eux, mais parfois vous navez pas besoin dinsrer un
lien pour un fichier, par exemple pour nos fichiers epub-contents et pdf-contents. Dans ces cas, vous pouvez
ajouter :orphan: en haut du fichier pour supprimer les avertissements disant que le fichier nest pas dans
le toc-tree.
Description des classes et de leur contenu
La documentation de CakePHP utilise phpdomain 7 pour fournir des directives sur mesure pour dcrire
les objets PHP et les constructs. Utiliser les directives et les modles est requis pour donner une bonne
indexation et des fonctionnalits de rfrencement crois.
Description des classes et constructs
Chaque directive remplit lindex, et lindex des espaces de nom.
.. php:global:: name
Cette directive dclare une nouvelle variable globale PHP.
.. php:function:: name(signature)
Dfinit une nouvelle fonction globale en-dehors de la classe.
.. php:const:: name
Cette directive dclare une nouvelle constante PHP, vous pouvez aussi lutiliser imbrique lintrieur
dune directive de classe pour crer les constantes de classe.
.. php:exception:: name
Cette directive dclare un nouvelle Exception dans lespace de noms courant. La signature peut inclure
des arguments du constructeur.
.. php:class:: name
Dcrit une classe. Mthodes, attributs, et constantes appartenant la classe doivent tre lintrieur
du corps de la directive :
.. php:class:: MyClass
Description de la Classe
.. php:method:: method($argument)
Description de la mthode
7. http ://pypi.python.org/pypi/sphinxcontrib-phpdomain
1002
Attributs, mthodes et constantes ne doivent pas tre imbriqus. Ils peuvent aussi suivre la dclaration
de classe :
.. php:class:: MyClass
Texte sur la classe
.. php:method:: methodName()
Texte sur la mthode
Voir aussi :
php:method, php:attr, php:const
.. php:method:: name(signature)
Dcrire une mthode de classe, ses arguments, les valeurs retournes et les exceptions :
.. php:method:: instanceMethod($one, $two)
:param string $un: Le premier param\tre.
:param string $deux: Le deuxime param\tre.
:returns: Un tableau de trucs.
:throws: InvalidArgumentException
C\'est un m\thode d\'instanciation.
.. php:staticmethod:: ClassName::methodName(signature)
Dcrire une mthode statique, ses arguments, les valeurs retournes et les exceptions.
see php:method pour les options.
.. php:attr:: name
Dcrit une proprit/attribut sur une classe.
Eviter lAffichage dAvertissements de Sphinx
Sphinx va afficher des avertissements si une fonction est rfrence dans plusieurs fichiers. Cest un
bon moyen de sassurer que vous navez pas ajout une fonction deux fois, mais parfois vous voulez
en fait crire une fonction dans deux ou plusieurs fichiers, par exemple debug object est rfrenc dans
/development/debugging et dans /core-libraries/global-constants-and-functions. Dans ce cas, vous pouvez
ajouter :noindex: sous la fonction debug pour supprimer les avertissements. Gardez uniquement une
rfrence sans :no-index: pour que la fonction soit rfrence :
.. php:function:: debug(mixed $var, boolean $showHtml = null, $showFrom = true)
:noindex:
Rfrencement crois
Les modles suivants se rfrent aux objets PHP et les liens sont gnrs si une directive assortie est trouve :
Documentation
1003
:php:func:
Rfrence une fonction PHP.
:php:global:
Rfrence une variable globale dont le nom a un prfixe $.
:php:const:
Rfrence soit une constante globale, soit une constante de classe. Les constantes de classe doivent
tre prcdes par la classe propritaire :
DateTime a une constante :php:const:`DateTime::ATOM`.
:php:class:
Rfrence une classe par nom :
:php:class:`ClassName`
:php:meth:
Rfrence une mthode dune classe. Ce modle supporte les deux types de mthodes :
:php:meth:`DateTime::setDate`
:php:meth:`Classname::staticMethod`
:php:attr:
Rfrence une proprit dun objet :
:php:attr:`ClassName::$propertyName`
:php:exc:
Rfrence une exception.
Code source
Les blocks de code littral sont crs en finissant un paragraphe avec ::. Le block littral doit tre indent,
et comme pour tous les paragraphes, tre spar par des lignes uniques :
C'est un paragraphe::
while ($i--) {
faireDesTrucs()
}
C'est un texte rgulier de nouveau.
Le texte littral nest pas modifi ou format, la sauvegarde du niveau dindentation est supprime.
1004
Notes et avertissements
Il y a souvent des fois o vous voulez informer le lecteur dune astuce importante, une note spciale ou
un danger potentiel. Les avertissements dans sphinx sont justement utiliss pour cela. Il y a cinq types
davertissements.
.. tip:: Les astuces sont utilises pour documenter ou ritrer des informations intressantes ou importantes. Le contenu de cette directive doit tre crit dans des phrases compltes et inclure toutes les
ponctuations appropries.
.. note:: Les notes sont utilises pour documenter une information particulirement importante. Le
contenu de cette directive doit tre crit dans des phrases compltes et inclure toutes les ponctuations
appropries.
.. warning:: Les avertissements sont utiliss pour documenter des blocks potentiellement dangereux, ou des informations relatives la scurit. Le contenu de la directive doit tre crite en phrases
compltes et inclure toute la ponctuation approprie.
.. versionadded:: X.Y.Z Les avertissements ajout en version X.Y.Z sont utiliss pour spcifier lajout de fonctionnalits dans une version spcifique, X.Y.Z tant la version laquelle lajout de la
fonctionnalit en question a eu lieu
.. deprecated:: X.Y.Z la diffrence des avertissements ajout en version, les avertissements
dprci en version servent indiquer la dprciation dune fonctionnalit une version prcise, X.Y.Z
tant la version laquelle le retrait de la fonctionnalit en question a eu lieu
Tous les avertissements sont faits de la mme faon :
.. note::
Indent, prcd et suivi par une ligne vide. Exactement comme
un paragraphe.
Ce texte n'est pas une partie de la note.
Exemples
Astuce : Cest une astuce utile que vous allez probablement oublie.
Note : Vous devriez y faire attention.
Avertissement : Cela pourrait tre dangereux.
Introduit dans la version 2.6.3 : Cette super fonctionnalit a t ajoute en version 2.6.3
Obsolte depuis la version 2.6.3 : Cette vieille fonctionnalit a t dprcie en version 2.6.3
Documentation
1005
Tickets
Avoir des retours et de laide de la communaut sous forme de tickets est une partie extrmement importante
dans le processus de dveloppement de CakePHP. Tous les tickets CakePHP sont hbrgs sur Github 8 .
Code
Les correctifs et les pull requests sont les meilleures faons de contribuer au code de CakePHP. Les pull
requests peuvent tre crs sur Github, et sont prfrs aux correctifs attachs aux tickets.
8. https ://github.com/cakephp/cakephp/issues
9. https ://github.com/cakephp/cakephp/search ?q=it+is+broken&ref=cmdform&type=Issues
10. http ://groups.google.com/group/cake-php
1006
Configuration initiale
Avant de travailler sur les correctifs pour CakePHP, cest une bonne ide de rcuprer la configuration de
votre environnement. Vous aurez besoin du logiciel suivant :
Git
PHP 5.2.8 or greater
PHPUnit 3.5.10 or greater (3.7.38 recommended)
Mettez en place vos informations dutilisateur avec votre nom / titre et adresse e-mail de travail
git config --global user.name 'Bob Barker'
git config --global user.email 'bob.barker@example.com'
Note : Si vous tes nouveau sous Git, nous vous recommandons fortement de lire l excellent livre gratuit
ProGit 11 .
Rcuprer un clone du code source de CakePHP sous github. :
Si vous navez pas de compte github 12 , crez en un.
Forkez le dpt de CakePHP 13 en cliquant sur le bouton Fork.
Aprs que le fork est fait, clonez votre fork sur votre machine local :
git clone git@github.com:YOURNAME/cakephp.git
Ajoutez le dpt CakePHP dorigine comme un dpt distant. Vous utiliserez ceci plus tard pour aller
chercher les changements du dpt CakePHP. Cela vous permettra de rester jour avec CakePHP
cd cakephp
git remote add upstream git://github.com/cakephp/cakephp.git
Maintenant que vous avez configur CakePHP, vous devriez tre en mesure de dfinir un $ test : ref :
connexion la base <database-configuration>, et : ref : excuter tous les tests de <running-tests>.
Code
1007
Astuce : Utiliser un nom descriptif pour vos branches, en rfrence au ticket ou au nom de la fonctionnalit,
est une bonne convention. Ex : ticket-1234, fonctionnalit-gniale.
Ce qui prcde va crer une branche locale base sur la branche (CakePHP) 2.3 en amont. Travaillez sur
votre correctif, et fates autant de commits que vous le souhaitez ; mais gardez lesprit ce qui suit :
Suivez ceci Normes de codes.
Ajoutez un cas de test pour montrer que le bug est rgl, ou que la nouvelle fonctionnalit marche.
Fates des commits logiques, et crivez des messages de commit bien clairs et concis.
checkout 2.3
fetch upstream
merge upstream/2.3
checkout <branch_name>
rebase 2.3
Cela rcuprera et fusionnera tous les changements qui se sont passs dans CakePHP depuis que vous
avez commenc. Cela rebasera - ou remettra vos changements au dessus du code actuel. Il y aura peut-tre
un conflit pendant le rebase. Si le rebase quitte rapidement, vous pourrez voir les fichiers qui sont en
conflit/Non fusionns avec git status. Rsolvez chaque conflit et continuer le rebase :
git add <filename> # Fates ceci pour chaque fichier en conflit.
git rebase --continue
Vrifiez que tous les tests continuent. Ensuite fates un push de votre branche votre fork :
git push origin <branch-name>
Une fois que votre branche est sur github, vous pouvez discuter de cela sur la mailing-liste cakephp-core 14
ou soumettre un pull request sur github.
Choisir lemplacement dans lequel vos changements seront fusionns
Quand vous fates vos pull requests, vous devez vous assurer de slectionner la branche de base correcte,
puisque vous ne pouvez pas lditer une fois que la pull request est cre.
Si votre changement est un bugfix et nintroduit pas de nouvelles fonctionnalits et corrige seulement un
comportement existant qui est prsent dans la version courante. Dans ce cas, choisissez master comme
votre cible de fusion.
Si votre changement est une nouvelle fonctionnalit ou un ajout au framework, alors vous devez choisir
la branche avec le nombre de la version prochaine. Par exemple si la version stable courante est 2.2.2,
la branche acceptant les nouvelles fonctionnalits sera 2.3.
14. http ://groups.google.com/group/cakephp-core
1008
Si votre changement est une dfailance dune fonctionnalit existante, ou de lAPI, alors vous devrez
choisir la prochaine version majeure. Par exemple, si la version courante est 2.2.2 alors la prochaine
fois quun comportement peut tre cass sera dans 3.0 ainsi vous devez cibler cette branche.
Note : Rappelez vous que tout le code auquel vous contribuez pour CakePHP sera sous la licence MIT
License, et la Cake Software Foundation 15 sera le propritaire de toutes les contributions de code et toutes
les contributions de code sont soumises au contrat de licence des Contributeurs 16 .
Tous les bugs rpars fusionns sur une branche de maintenance seront aussi fusionns priodiquement la
version publie par lquipe centrale (core team).
Normes de codes
Les dveloppeurs de CakePHP vont utiliser les normes de code suivantes.
Il est recommand que les autres personnes qui dveloppent des IngredientsCake suivent les mmes normes.
Vous pouvez utiliser le CakePHP Code Sniffer 17 pour vrifier que votre code suit les normes requises.
Langue
Tout code et commentaire doit tre crit en Anglais.
Indentation
Un onglet sera utilis pour lindentation.
Ainsi, lindentation devrait ressembler ceci :
// niveau de base
// niveau 1
// niveau 2
// niveau 1
// niveau de base
Ou :
15. http ://cakefoundation.org/pages/about
16. http ://cakefoundation.org/pages/cla
17. https ://github.com/cakephp/cakephp-codesniffer
Normes de codes
1009
$booleanVariable = true;
$stringVariable = "moose";
if ($booleanVariable) {
echo "Valeur bolenne si true";
if ($stringVariable === "moose") {
echo "Nous avons rencontr un moose";
}
}
Dans les cas o vous utilisez un appel de fonction multi-lignes, utilisez les instructions suivantes :
Les parenthses ouvrantes dun appel de fonction multi-lignes doivent tre le dernier contenu de la ligne.
Seul un argument est permis par ligne dans un appel de fonction multi-lignes.
Les parenthses fermantes dun appel de fonction multi-lignes doivent tre elles-mme sur une ligne.
Par exemple, plutt quutiliser le format suivant :
$matches = array_intersect_key($this->_listeners,
array_flip(preg_grep($matchPattern,
array_keys($this->_listeners), 0)));
Structures de Contrle
Les structures de contrle sont par exemple if, for, foreach, while, switch etc. Cidessous, un exemple avec if :
if ((expr_1) || (expr_2)) {
// action_1;
} elseif (!(expr_3) && (expr_4)) {
// action_2;
} else {
// default_action;
}
1010
Dans les structures de contrle, il devrait y avoir 1 (un) espace avant la premire parenthse et 1 (un)
espace entre les dernires parenthses et laccolade ouvrante.
Toujours utiliser des accolades dans les structures de contrle, mme si elles ne sont pas ncessaires. Elles
augmentent la lisibilit du code, et elles vous donnent moins derreurs logiques.
Louverture des accolades doit tre place sur la mme ligne que la structure de contrle. La fermeture
des accolades doit tre place sur de nouvelles lignes, et ils doivent avoir le mme niveau dindentation
que la structure de contrle. La dclaration incluse dans les accolades doit commencer sur une nouvelle
ligne, et le code quil contient doit gagner un nouveau niveau dindentation.
Les attributs Inline ne devraient pas tre utiliss lintrieur des structures de contrle.
// mauvais = pas d'accolades, dclaration mal place
if (expr) statement;
// mauvais = pas d'accolades
if (expr)
statement;
// bon
if (expr) {
statement;
}
// mauvais = inline assignment
if ($variable = Class::function()) {
statement;
}
// bon
$variable = Class::function();
if ($variable) {
statement;
}
Oprateurs ternaires
Les oprateurs ternaires sont permis quand lopration entire rentre sur une ligne. Les oprateurs ternaires
plus longs doivent tre spars en expression if else. Les oprateurs ternaires ne doivent pas tre imbriqus. Des parenthses optionnelles peuvent tre utilises autour de la condition vrifie de lopration
pour rendre le code plus clair :
// Bien, simple et lisible
$variable = isset($options['variable']) ? $options['variable'] : true;
Normes de codes
1011
Fichiers de Vue
Dans les fichiers de vue (fichiers .ctp) les dveloppeurs devront utiliser les structures de contrle en mot
(keyword control structures). Les structures de contrle en mot sont plus faciles lire dans des fichiers de
vue complexes. Les structures de contrle peuvent soit tre contenues dans un block PHP plus large, soit
dans des balises PHP spars :
<?php
if ($isAdmin):
echo '<p>You are the admin user.</p>';
endif;
?>
<p>The following is also acceptable:</p>
<?php if ($isAdmin): ?>
<p>You are the admin user.</p>
<?php endif; ?>
Nous autorisons les balises PHP fermantes (?>) la fin des fichiers .ctp.
Comparaison
Toujours essayer dtre aussi strict que possible. Si un test non strict est dlibr, il peut tre sage de le
commenter afin dviter de le confondre avec une erreur.
Pour tester si une variable est null, il est recommand dutiliser une vrification stricte :
if ($value === null) {
// ...
}
Comme vous pouvez le voir, il doit y avoir un espace des deux cts des signes gal (=).
1012
Les paramtres avec une valeur par dfaut, doivent tre placs en dernier dans la dfintion de la fonction.
Essayez de faire en sorte que vos fonctions retournent quelque chose, au moins true ou false, ainsi cela
peut dterminer si lappel de la fonction est un succs :
public function connection($dns, $persistent = false) {
if (is_array($dns)) {
$dnsInfo = $dns;
} else {
$dnsInfo = BD::parseDNS($dns);
}
if (!($dnsInfo) || !($dnsInfo['phpType'])) {
return $this->addError();
}
return true;
}
Ici $Model doit tre une instance de Model et $array doit tre un array.
Notez que si vous souhaitez autoriser que $array soit aussi une instance de ArrayObject, vous ne
devez pas typer puisque array accepte seulement le type primitif :
/**
* Description de la method.
*
Normes de codes
1013
DocBlocks
Tous les blocs de commentaire, lexception du premier bloc dans un fichier, doit toujours tre prcd
dune ligne vierge.
DocBlock dEntte de Fichier
Tous les fichier PHP doivent contenir un DocBlock den-tte, qui doit ressembler cela :
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @copyright
@link
http://cakephp.org CakePHP(tm) Project
*
@since
X.Y.Z
*
@license
http://www.opensource.org/licenses/mit-license.php MIT License
*
/
*
http ://phpdoc.org
http ://phpdoc.org/docs/latest/references/phpdoc/tags/copyright.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/link.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/since.html
1014
@license 22
DocBlocks de Classe
Les DocBlocks de classe doivent ressembler ceci :
/**
* Short description of the class.
*
* Long description of class.
* Can use multiple lines.
*
* @deprecated 3.0.0 Deprecated in 2.6.0. Will be removed in 3.0.0. Use Bar instead.
* @see Bar
* @link http://book.cakephp.org/2.0/en/foo.html
*/
class Foo {
}
http ://phpdoc.org/docs/latest/references/phpdoc/tags/license.html
http ://phpdoc.org
http ://phpdoc.org/docs/latest/references/phpdoc/tags/deprecated.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/internal.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/link.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/property.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/see.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/since.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/uses.html
Normes de codes
1015
*/
protected $_bar = null;
Les DocBlocks des attributs peuvent contenir les tags phpDocumentor 31 suivants :
@deprecated 32 en utilisant le format @version <vector> <description>, o version et
description sont obligatoires.
@internal 33
@link 34
@see 35
@since 36
@var 37
DocBlocks des Mthodes/Fonctions
Les DocBlocks de mthode ou de fonctions doivent ressembler ceci :
/**
* Short description of the method.
*
* Long description of method.
* Can use multiple lines.
*
* @param string $param2 first parameter.
* @param array|null $param2 Second parameter.
* @return array An array of cakes.
* @throws Exception If something goes wrong.
*
* @link http://book.cakephp.org/2.0/en/foo.html#bar
* @deprecated 3.0.0 Deprecated as of 2.5.0. Will be removed in 3.0.0. Use Bar::baz instead
* @see Bar::baz
*/
public function bar($param1, $param2 = null) {
}
Les DocBlocks des mthodes/fonctions peuvent contenir les tags phpDocumentor 38 suivants :
@deprecated 39 en utilisant le format @version <vector> <description>, o version et
description sont obligatoires.
@internal 40
@link 41
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
http ://phpdoc.org
http ://phpdoc.org/docs/latest/references/phpdoc/tags/deprecated.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/internal.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/link.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/see.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/since.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/var.html
http ://phpdoc.org
http ://phpdoc.org/docs/latest/references/phpdoc/tags/deprecated.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/internal.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/link.html
1016
@param 42
@return 43
@throws 44
@see 45
@since 46
@uses 47
Types de Variables
Les types de variables pour lutilisation dans DocBlocks :
Type Description
mixed Une variable avec un type indfini (ou multiple).
int Variable de type Integer (Tout nombre).
float Type Float (nombres virgule).
bool Type Logique (true ou false).
string Type String (toutes les valeurs en ou ).
null Type null. Habituellement utilis avec un autre type.
array Type Tableau.
object Type Objet.
resource Type Ressource (retourn par exemple par mysql_connect()). Rappelez vous que quand vous spcifiez un type en mixed, vous devez indiquer si il est inconnu, ou les types possibles.
callable Function appelable.
Vous pouvez aussi combiner les types en utilisant le caractre pipe :
int|bool
Pour plus de deux types, il est habituellement mieux dutiliser seulement mixed.
Quand vous retournez lobjet lui-mme, par ex pour chaner, vous devriez utilisez $this la place :
/**
* Foo function.
*
* @return $this
*/
public function foo() {
return $this;
}
42.
43.
44.
45.
46.
47.
http ://phpdoc.org/docs/latest/references/phpdoc/tags/param.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/return.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/throws.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/see.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/since.html
http ://phpdoc.org/docs/latest/references/phpdoc/tags/uses.html
Normes de codes
1017
Quand vous incluez les fichiers avec des classes ou librairies, utilisez seulement et toujours la fonction
require_once 48 .
Convention de Nommage
Fonctions
Ecrivez toutes les fonctions en camelBack :
function nomDeFonctionLongue() {
}
Classes
Les noms de classe doivent tre crites en CamelCase, par exemple :
class ClasseExemple {
}
Variables
Les noms de variable doivent tre aussi descriptifs que possible, mais aussi courts que possible. Tous les
noms de variables doivent dmarrer avec une lettre minuscule, et doivent tre crites en camelBack si il y a
plusieurs mots. Les variables contenant des objets doivent dune certaine manire tre associes la classe
do elles proviennent. Exemple :
$user = 'John';
$users = array('John', 'Hans', 'Arne');
$dispatcher = new Dispatcher();
48. http ://php.net/require_once
1018
Les noms de mthodes et variables prives commencent avec un underscore double (__). Exemple :
class A {
private $__iAmAPrivateVariable;
private function __iAmAPrivateMethod() {
/*...*/
}
}
Essayez cependant dviter les mthodes et variables prives et privilgiez plutt les variables protges.
Ainsi elles pourront tre accessible ou modifi par les sous-classes, alors que celles prives empchent
lextension ou leur rutilisation. La visibilit prive rend aussi le test beaucoup plus difficile.
Exemple dAdresses
Pour tous les exemples dURL et dadresse email, utilisez example.com, example.org et example.net,
par exemple :
Email : someone@example.com 49
WWW : http ://www.example.com
FTP : ftp ://ftp.example.com
Le nom de domaine example.com est rserv cela (voir RFC 2606 50 ) et est recommand pour lutilisation dans la documentation ou comme exemples.
Fichiers
Les noms de fichier qui ne contiennent pas de classes, doivent tre crits en minuscules et souligns, par
exemple :
nom_de_fichier_long.php
49. someone@example.com
50. http ://tools.ietf.org/html/rfc2606.html
Normes de codes
1019
Casting
Pour le casting, nous utilisons :
Type Description
(bool) Cast pour boolean.
(int) Cast pour integer.
(float) Cast pour float.
(string) Cast pour string.
(array) Cast pour array.
(object) Cast pour object.
Constantes
Les constantes doivent tre dfinies en majuscules :
define('CONSTANTE', 1);
Si un nom de constante a plusieurs mots, ils doivent tre spars par un caractre underscore, par exemple :
define('NOM_LONG_DE_CONSTANTE', 2);
1020
Guides de Migration
Pour chaque version majeure et mineure, lquipe de CakePHP va fournir un guide de migration. Ces guides
expliquent les nouvelles fonctionnalits et tout changement entranant des modifications de chaque version.
Ils peuvent tre trouvs dans la section Annexes du cookbook.
Utiliser CakePHP
Si vous construisez votre application avec CakePHP, les conventions suivantes expliquent la stabilit que
vous attendez.
Interfaces
Outside of major releases, interfaces provided by CakePHP will not have any existing methods changed and
new methods will not be added to any existing interfaces.
En-dehors des versions majeures, les interfaces fournies par CakePHP ne vont pas avoir de mthodes existantes changes et les nouvelles mthodes ne seront pas ajoutes aux interfaces existantes.
Classes
Les classes fournies par CakePHP peuvent tre construites et ont leurs mthodes public et les proprits
utilises par le code lapplication et en-dehors de versions majeures, la compatibilit rtroactive est assure.
Note : Certaines classes dans CakePHP sont marques avec la balise de doc @internal de lAPI. Ces
classes ne sont pas stables et ne nassurent pas forcment de compatibilit rtroactive.
Dans les versions mineures, les nouvelles mthodes peuvent tre ajoutes aux classes, et les mthodes existantes peuvent avoir de nouveaux arguments ajouts. Tout argument nouveau aura des valeurs par dfaut,
mais si vous surchargez des mthodes avec une signature diffrente, vous verrez peut-tre des erreurs fatales.
Les mthodes qui ont des nouveaux arguments ajouts seront documents dans le guide de migration pour
cette version.
La table suivante souligne plusieurs cas dutilisations et la compatibilit que vous pouvez attendre de
CakePHP :
1021
Si vous...
Typehint sur une classe
Cr une nouvelle instance
Etendre la classe
Access a public property
Appel dune mthode publique
Etendre une classe et...
Surcharger une proprit publique
Accder une proprit protge
Surcharger une proprit protge
Surcharger une mthode protge
Apple dune mthode protge
Ajouter une proprit publique
Ajouter une mthode publique
Ajouter un argument pour une
mthode qui surcharge
Ajouter un argument par dfaut
pour une mthode existante
Backwards compatibility ?
Oui
Oui
Oui
Oui
Oui
Oui
Non 52
Non 1
Non 1
Non 1
Non
Non
Non 1
Oui
1022
1023
problme avec une version sortie, le systme de ticket est le meilleur endroit pour partager vos ides.
Nous maintenons 4 versions de CakePHP.
stable : Versions tagges pour la production o la stabilit est plus importante que les fonctionnalits.
Les questions dposes pour ces versions seront rgles dans la branche connexe, et feront parties de la
prochaine version.
Branches de maintenance : Les branches de Dveloppement deviennent des branches de maintenance
une fois quun niveau stable de la version a t atteint. Les branches de maintenance sont les endroits
o toutes les corrections de bugs sont committes avant de faire leur chemin vers une version stable. Les
branches de maintenance ont le mme nom que la version principale pour lesquelles elles sont faites. Par
ex : 1.2. Si vous utilisez une version stable et avez besoin de correctifs qui nont pas fait leur chemin vers
une version stable, vrifiez ici.
Branches de dveloppement : Les branches de Dveloppement contiennent des correctifs de pointe et
des fonctionnalits. Ils sont nomms daprs le numro de version pour lesquels ils sont faits. Par ex :
1.3. Une fois que les branches de dveloppement ont atteint un niveau de version stable, elles deviennent
des branches de maintenance, et plus aucune fonctionnalit nouvelle nest introduite, moins que ce soit
absolument ncessaire.
Branches de fonctionnalit : Les branches de fonctionnalit contiennent des fonctionnalits non-finies,
possiblement instable et sont recommandes uniquement pour les utilisateurs avertis intresss dans la
fonctionnalit la plus avance et qui souhaitent contribuer la communaut. Les branches de fonctionnalit sont nommes selon la convention suivante de version-fonctionnalit. Un exemple serait 1.3-routeur
qui contiendrait de nouvelles fonctionnalits pour le Routeur dans 1.3.
Esprons que cela vous aide comprendre quelle version est bonne pour vous. Une fois que vous choisissez votre version, vous vous sentirez peut-tre contraints de contribuer un report de bug ou de faire des
commentaires gnraux sur le code.
Si vous utilisez une version stable ou une branche de maintenance, merci de soumettre des tickets ou
discuter avec nous sur IRC.
Si vous utilisez la branche de dveloppement ou la branche de fonctionnalit, le premier endroit o aller
est IRC. Si vous avez un commentaire et ne pouvez pas nous atteindre sur IRC aprs un jour ou deux,
merci de nous soumettre un ticket.
Si vous trouvez un problme, la meilleure rponse est dcrire un test. Le meilleur conseil que nous pouvons
offrir dans lcriture des tests est de regarder ceux qui sont inclus dans le cur.
Comme toujours, si vous avez nimporte quelle question ou commentaire, visitez nous sur #cakephp sur
irc.freenode.net.
1024
CHAPITRE 17
Annexes
Les annexes contiennent des informations sur les nouvelles fonctionnalits de la version 2.x ainsi quun
guide de migration de la version 1.3 vers 2.0.
1025
Cache
Cache::add() a t ajoute. Cette mthode vous permet dajouter des donnes au cache si la cl
nexiste pas dj. Cette mthode fonctionnera de faon atomique avec Memcached, Memcache, APC et
Redis. Les autres backends de cache feront des oprations non-atomiques.
CakeTime
CakeTime::listTimezones() a t change pour accepter un tableau en dernier argument. Les
valeurs valides pour largument $options sont : group, abbr, before, and after.
Shell Helpers Ajouts
Les applications de Console peuvent maintenant tre des classes de helper qui encapsulent des blocks rutilisables de logique pour laffichage. Consultez la section Shell Helpers pour plus dinformations.
I18nShell
Une nouvelle option no-locations a t ajoute. Quand elle est active, cette option va dsactiver la
gnration des rfrences de localisation dans vos fichiers POT.
Hash
Hash::sort() supporte maintenant le tri sans sensibilit la casse grce loption ignoreCase.
Model
Les finders magiques supportent maintenant des types de finder personnalis. Par exemple si votre
model implmente un finder find(published), vous pouvez maintenant utiliser les fonctions
findPublishedBy et findPublishedByAuthorId avec linterface de la mthode magique.
Les conditions du find peuvent maintenant utiliser les oprateurs IN et NOT IN. Ceci permet aux expressions du find davoir une meilleur compatibilit avec la version 3.x.
Validation
Validation::uploadedFile() est un portage de la version 3.0.
CakeSession
Loption de configuration Session.cacheLimiter a t ajoute. Cette option vous laisse
dfinir les en-ttes du cache control utilises pour le cookie de session. La valeur par dfaut est
must-revalidate.
1026
View
FormHelper
url => false est maintenant support pour FormHelper::create() pour pouvoir crer des
balises de formulaire sans lattribut HTML action. Ceci est un portage de la version 3.x.
Configure::consume() a t ajoute pour lire et supprimer dans Configure en une seule tape.
Datasource
Les sources de donnes SQL vont maintenant remplacer et null en quand les colonnes ne sont
pas nulles et que les lignes sont en train dtre cres ou mises jour.
CakeSession
CakeSession::consume() a t ajoute pour lire et supprimer dans Session en une seule tape.
Largument $renew a t ajout CakeSession::clear() pour permettre de vider la session sans
forcer un nouvel id et renouveler la session. Il est par dfaut true.
2.7 Guide de Migration
1027
Model
TreeBehavior
La nouvelle configuration level est maintenant disponible. Vous pouvez lutiliser pour spcifier un nom
de champ dans lequel la profondeur des noeuds de larbre sera stock.
La nouvelle mthode TreeBehavior::getLevel() a t ajoute qui attrape le niveau de profondeur
dun noeud.
Le formatage de TreeBehavior::generateTreeList() a t extrait dans une mthode part
entire TreeBehavior::formatTreeList().
Network
CakeEmail
CakeEmail va maintenant utiliser la config default lors de lacration des instances qui ne spcifient pas
une configuration utiliser. Par exemple $email = new CakeEmail(); va maintenant utiliser la
config default.
Utility
CakeText
La classe String a t renomme en CakeText. Ceci rsoud certains conflits de compatibilit avec
HHVM et aussi avec PHP7+. Il y a aussi une classe String fournie pour des raisons de compatibilit.
Validation
Validation::notEmpty() a t renomme en Validation::notBlank(). Ceci a pour objectif dviter la confusion autour de la fonction PHP notEmpty() et que la rgle de validation accepte 0
en input valide.
Controller
SessionComponent
1028
RequestHandlerComponent
Len-tte Accept text/plain nest plus automatiquement reli la response de type csv. Cest un
portage de la version 3.0.
View
SessionHelper
SessionHelper::consume() a t ajoute pour lire et supprimer dans Session en une seule tape.
SessionHelper::flash() a t dprcie. Vous devez utiliser FlashHelper la place.
TestSuite
ControllerTestCase
1029
Console
ConsoleOptionParser
ConsoleOptionParser::removeSubcommand() a t ajoute.
Shell
overwrite() a t ajoute pour permettre de gnrer des barres de progression ou pour viter de
gnrer de nombreuses lignes en remplaant le texte qui a dj t affich lcran.
Controller
AuthComponent
Loprateur wildcard RLIKE a t ajout pour permettre des correspondances avec les expressions
rgulires.
Les migrations de Schema avec MySQL supportent maintenant une cl after lorsque on ajoute une
colonne. Cette cl vous permet de spcifier aprs quelle colonne la colonne crer doit tre ajoute.
Model
Model
1030
CakeRequest::param() peut maintenant lire des valeurs en utilisant Syntaxe de chemin Hash
comme data().
CakeRequest:setInput() a t ajoute.
HttpSocket
HttpSocket::head() a t ajoute.
Vous pouvez maintenant utiliser loption protocol pour surcharger le protocole spcifique utiliser
lorsque vous fates une requte.
I18n
La valeur de configuration I18n.preferApp peut maintenant tre utilise pour controller lordre des
traductions. Si dfini true, les traductions de lapplication seront prfres celles des plugins.
Utility
CakeTime
Hash::get() lance maintenant une exception quand largument path est invalide.
Hash::nest() lance maintenant une exception quand les rsultats de lopration dimbrication ne
retourne aucune donne.
Validation
1031
View
JsonView
JsonView supporte maintenant la variable de vue _jsonOptions. Cela permet de configurer les
options utilises pour gnrer le JSON.
XmlView
XmlView supporte maintenant la variable de vue _xmlOptions. Cela permet de configurer les options
utilises pour gnrer le XML.
Helper
HtmlHelper
HtmlHelper::css() a une nouvelle option once. Elle fonctionne de la mme manire que loption
once de HtmlHelper::script(). La valeur par dfaut est false pour maintenir une compatibilit
rtroactive.
Largument $confirmMessage de HtmlHelper::link() a t dprci. Vous devez utiliser la cl
confirm la place dans $options pour spcifier le message.
FormHelper
Largument $confirmMessage de FormHelper::postLink() a t dprci. Vous devez maintenant utiliser la cl confirm dans $options pour spcifier le message.
Lattribut maxlength va maintenant aussi tre appliqu aux textareas, quand le champ de la base de
donnes correspondant est de type varchar, selon les specs de HTML.
PaginatorHelper
PaginatorHelper::meta() a t ajoute pour afficher les meta-links (rel prev/next) pour un ensemble de rsultats pagins.
1032
Cache
Un nouvel adaptateur a t ajout pour Memcached. Ce nouvel adaptateur utilise ext/memcached au lieu
de ext/memcache. Il permet damliorer la performance et les connexions persistentes partages.
Ladaptateur Memcache est maintenant dprci en faveur de Memcached.
Cache::remember() a t ajoute.
Cache::config() accepte maintenant la cl database lors de lutilisation avec RedisEngine
afin dutiliser un certain nombre de base de donnes pas par dfaut.
Console
SchemaShell
Les sous-commandes create et update ont maintenant une option yes. Loption yes vous permet
de passer les diffrentes questions interactives forant ainsi une rponse yes.
CompletionShell
CookieComponent peut utiliser le nouveau chiffrement AES-256 offert par Security. Vous pouvez
activer ceci en appelant CookieComponent::type() avec aes.
RequestHandlerComponent
1033
AclComponent
Les checs de vrification de noeud ACL sont maintenant directement mis dans les logs. Lappel de
trigger_error() a t retir.
Scaffold
CakePlugin::loadAll() fusionne maintenant les options par dfaut et celles spcifiques au plugin
comme on peut sy attendre intuitivement. Regardez les cas de test pour plus de dtails.
Event
EventManager
Les Events lis au gestionnaire global sont maintenant dclenchs dans lordre de priorit des events lis au
gestionnaire local. Ceci peut entraner le dclenchement des listeners dans un ordre diffrent par rapport aux
versions prcdentes. Au lieu davoir des listeners globaux attraps, et ensuite instancier les listeners tant
dclenchs plus tard, les deux ensembles de listeners sont combins en une liste de listeners bas sur leurs
priorits et ensuite dclenchs en un ensemble. Les listeners globaux dune priorit donne sont toujours
dclenchs avant linstanciation des listeners.
I18n
La classe I18n a de nombreuses nouvelles constantes. Ces constantes vous permettent de remplacer les
hardcoded integers avec des valeurs lisibles par exemple : I18n::LC_MESSAGES.
Model
Les nombres unsigned sont maintenant supports par les sources de donnes qui les fournissent (MySQL).
Vous pouvez dfinir loption unsigned true dans vos fichiers schema/fixture pour commencer utiliser
cette fonctionnalit.
Les Jointures inclues dans les requtes sont maintenant ajoutes aprs que les jointures des associations
sont ajoutes. Cela facilite la jointure des tables qui dpendent dassociations gnres.
1034
Network
CakeEmail
Les adresses Email dans CakeEmail ne sont pas valides avec filter_var par dfaut. Cela assouplit
les rgles daddresse email en autorisant les addresses demail interne comme root@localhost par
exemple.
Vous pouvez maintenant spcifier la cl layout dans la config demail sans avoir spcifier la cl
template.
CakeRequest
Sessions ne seront pas dmarres si elles sont connues pour tre vides. Si le cookie de session ne peut tre
trouv, une session ne sera pas dmarre moins quune opration dcriture ne soit faite.
Routing
Router
Router::mapResources() accepte la cl connectOptions dans largument $options. Regardez Routing REST Personnalis pour plus de dtails.
Utility
Debugger
1035
File
CakeLog ne sauto-configure plus tout seul. Au final, tous les fichiers de log ne seront plus auto-crs
si aucun flux nest cout. Assurez-vous que vous avez au moins un moteur par dfaut configur si vous
voulez couter tous les types et les niveaux.
Error
ExceptionRenderer
ExceptionRenderer remplit maintenant les tempplates derreur avec les variables code, message et url.
name a t dprci mais est toujours disponible. Cela uniformise les variables travers tous les templates
derreur.
1036
Testing
Les fichiers de fixture peuvent maintenant tre placs dans des sous-rpertoires. Vous pouvez utiliser
les fixtures dans les sous-rpertoires en incluant le nom du rpertoire aprs le .. Par exemple,
app.my_dir/article va charger App/Test/Fixture/my_dir/ArticleFixture. On notera que
le rpertoire de fixture ne sera pas inflect ou modifi dans tous les cas.
Les Fixtures peuvent maintenant dfinir $canUseMemory false pour dsactiver le moteur de stockage
de la mmoire utilise dans MySQL.
View
View
$title_for_layout
est
dprci.
Utilisez
$this->fetch(title);
$this->assign(title, your-page-title); la place.
View::get() accepte maintenant un deuxime argument pour fournir une valeur par dfaut.
et
FormHelper
FormHelper va maintenant gnrer les inputs de fichier pour les types de champ binary.
FormHelper::end() a eu un deuxime paramtre ajout. Ce paramtre vous laisse passer les proprits supplmentaires aux champs utiliss pour scuriser les formulaires avec SecurityComponent.
FormHelper::end() et FormHelper::secure() vous permettent de passer des options supplmentaires qui sont changes en attributs sur les inputs cachs gnrs. Cest utile quand vous voulez
utiliser lattribut HTML5 form.
FormHelper::postLink() vous permet maintenant de faire un tampon de la balise de formulaire
gnr au lieu de la retourner avec le lien. Ceci permet dviter les balises de formulaire imbriques.
PaginationHelper
PaginatorHelper::sort() a maintenant une option lock pour crer le tri des liens de pagination
avec seulement la direction par dfaut.
ScaffoldView
1037
Console
Les messages de log de type notice seront maintenant en couleur dans les terminaux qui supportent les
couleurs.
ConsoleShell est maintenant dprcie.
SchemaShell
cake bake model permet maintenant la commande pour baker les $behaviors. Si les champs lft,
rght et parent_id se trouvent dans votre table, cela va ajouter le behavior Tree, par exemple. Vous pouvez
aussi tendre le ModelTask pour permettre vos propres behaviors dtre reconnus.
cake bake pour les views, models, controllers, tests et fixtures supportent maintenant les paramtres
-f ou --force pour forcer lcrasement de fichiers.
Les Tasks dans le coeur peuvent tre maintenant aliass de la mme faon que vous le faites avec les
Helpers, Components et Behaviors.
FixtureTask
cake bake fixture supporte maintenant un paramtre --schema qui permet le baking de toutes
les fixtures de faon noninteractive all tout en utilisant limport du schema.
Core
Constantes
Les constantes IMAGES_URL, JS_URL, CSS_URL ont t dprcies et remplaces par les variables de
config respectivement App.imageBaseUrl, App.jsBaseUrl, App.cssBaseUrl.
Les Constantes IMAGES, JS, CSS ont t dprcies.
Object
1038
Components
AuthComponent
Les objets dAuthentification utilisent maintenant les nouveaux objets password hasher pour la gnration
et la vrification des password hashs Regardez Hachage des mots de passe pour plus dinfo.
DbAcl
DbAcl utilise maintenant les jointures INNER au lieu des jointures LEFT. Ceci amliore les performances
pour certaines bases de donnes externes.
Model
Models
Model::save(),
Model::saveField(),
Model::saveAll(),
Model::saveAssociated(), Model::saveMany() prennent une nouvelle option
counterCache. Vous pouvez la dfinir false pour viter de mettre jour les valeurs du counter cache
pour une opration de sauvegarde particulire.
Model::clear() a t ajoute.
Datasource
Mysql, Postgres, et Sqlserver supportent maintenant un tableau settings dans la dfinition de connexion.
Cette paire de cl => valeur mettra des commandes SET lorsque la connexion est cre.
MySQL driver supporte maintenant les options SSL.
View
JsonView
1039
LAPI pour HtmlHelper::css() a t simplifie. Vous pouvez maintenant fournir un tableau doptions en deuxime argument. Quand vous fates cela, lattribut rel se met par dfaut stylesheet.
Une nouvelle option escapeTitle ajoute HtmlHelper::link() pour contrler lchappement
seulement du titre du lien et pas des attributs.
TextHelper
TextHelper::autoParagraph() a t ajoute. Elle permet de convertir automatiquement les paragraphes de test en HTML.
PaginatorHelper
PaginatorHelper::param() a t ajoute.
La premire page ne contient plus /page:1 ou ?page=1 dans lURL. Cela vite les problmes de
contenu dupliqu, o vous avez besoin dutiliser canonical ou noindex de toute faon.
FormHelper
CakeRequest::param() a t ajoute.
CakeRequest::is() a t modifie pour supporte un tableau de types et va retourner true si la requte
correspond tout type.
CakeRequest::isAll() a t ajoute pour vrifier quune requte correspond tous les types donns.
1040
CakeResponse
Les messages de log demail ont maintenant loption email par dfaut. Si vous ne voyez pas de contenus
demail dans vos logs, assurez-vous dajouter loption email votre configuration de log.
CakeEmail::emailPattern() a t ajoute. Cette mthode peut tre utilise pour faciliter les
rgles de validation demail. Cest utile quand vous grez certains htes Japonais qui permettent aux
adresses non conformes dtre utilises.
CakeEmail::attachments() vous permet de fournir les contenus de fichier directement en utilisant la cl data.
Les donnes de Configuration sont maintenant correctement fusionnes avec les classes de transport.
HttpSocket
HttpSocket::patch() a t ajoute.
I18n
L10n
ell est maintenant la locale par dfaut pour le Grec comme spcifi par ISO 639-3 et gre son alias. Les
dossiers de locale ont t ajusts en consquence (de /Locale/gre/ en /Locale/ell/ ).
fas est maintenant la locale par dfaut pour le Farsi comme spcifi par ISO 639-3 et per son alias. Les
dossiers de locale ont t ajusts en consquence (de /Locale/per/ en /Locale/fas/ ).
sme est maintenant la locale par dfaut pour le Sami comme spcifi par ISO 639-3 et smi son alias. Les
dossiers de locale ont t ajusts en consquence (de /Locale/smi/ en /Locale/sme/ ).
mkd remplace mk comme locale par dfaut pour le Macedonien comme spcifi par ISO 639-3. Les
dossiers de locale ont aussi t ajusts.
Le code de Catalog in a t supprim et remplac par id (Indonesian), e a t supprim et remplac par
el (Greek), n a t supprim et remplac par nl (Dutch), p a t supprim et remplac par pl (Polish),
sz a t supprim et remplac par se (Sami).
Kazakh a t ajout kaz comme locale et kk comme code de catalog.
Kalaallisut a t ajout avec kal comme locale et kl comme code de catalog.
la constante DEFAULT_LANGUAGE a t dprcie en faveur de la valeur de Configuration
Config.language.
Logging
Les moteurs de Log nont plus besoin du suffixe Log dans leur configuration. Donc pour le moteur de
FileLog ; il suffit maintenant de dfinir engine => File. Cela unifie la faon dont les moteurs
2.4 Guide de Migration
1041
sont nomms dans la configuration (regardez les moteurs de Cache par exemple). Note : Si vous avez un
moteur de Log de type DatabaseLogger qui ne suit pas les conventions, utilisez un suffix Log pour
votre nom de classe, vous devez ajuster votre nom de classe en DatabaseLog. Vous devez aussi viter
les noms de classe comme SomeLogLog ce qui inclut le suffixe deux fois la fin.
FileLog
Deux nouvelles options de config size et rotate ont t ajoutes pour le moteur FileLog.
En mode debug, les rpertoires manquants vont tre maintenant automatiquement crs pour viter le
lancement des erreurs non ncessaires.
SyslogLog
Le nouveau moteur de log SyslogLog a t ajout pour streamer les messages au syslog.
Cache
FileEngine
En mode debug, les rpertoires manquants vont tre automatiquement crs pour viter le lancement
derreurs non ncessaires.
Utility
General
1042
CakeNumber
1043
Constantes
Une application peut maintenant facilement dfinir CACHE et LOGS, puisquils sont maintenant dfinis de
faon conditionnelle par CakePHP.
Mise en Cache
FileEngine est toujours le moteur de cache par dfaut. Dans le pass, un certain nombre de personnes a
des difficults configurant et dployant APC correctement des deux faons en cli et web. Lutilisation des
fichiers devrait rendre la configuration de CakePHP plus simple pour les nouveaux dveloppeurs.
Configure : :write(Cache.viewPrefix, YOURPREFIX) ; a t ajoute core.php pour autoriser les domaines/languages multiples par configuration.
Component
AuthComponent
Une nouvelle proprit AuthComponent::$unauthorizedRedirect a t ajoute.
Par dfaut la valeur est true et luser est redirig lURL de rfrence lors des checs dauthorisation.
Si dfini une chane ou un tableau, luser est redirig lURL.
Si dfini false, une exception ForbiddenException est lance la place de la redirection.
Un nouvel adaptateur dauthenticate a t ajout pour le support de hash blowfish/bcrypt hashed des
mots de passe. Vous pouvez maintenant utiliser Blowfish dans votre tableau $authenticate pour
permettre aux mots de passe bcrypt dtre utiliss.
AuthComponent::redirect() a t dprcie. Utilisez AuthComponent::redirectUrl()
la place.
PaginatorComponent
PaginatorComponent supporte maintenant loption findType. Ceci peut tre utilis pour spcifier quelle
mthode find vous voulez utiliser pour la pagination. Cest un peu plus facile de manager et de dfinir que
lindex 0ime.
PaginatorComponent lance maintenant NotFoundException quand vous essayez daccder une page qui
nest pas correct (par ex la page requte est suprieure au total du compte de page).
SecurityComponent
SecurityComponent supporte maintenant loption unlockedActions. Ceci peut tre utilis pour dsactiver toutes les vrifications de scurit pour toute action liste dans cette option.
1044
RequestHandlerComponent
RequestHandlerComponent::viewClassMap() a t ajout, qui est utilis pour mapper un
type vers le nom de classe de la vue. Vous pouvez ajouter $settings[viewClassMap] pour
configurer automatiquement la viewClass correcte base sur le type extension/content.
CookieComponent
CookieComponent::check() a t ajoute. Cette mthode fonctionne de la mme faon que
CakeSession::check().
Console
Le shell server a t ajout. Vous pouvez utiliser cela pour commencer le serveur web PHP5.4 pour
votre application CakePHP.
Construire un nouveau projet avec bake dfinit maintenant le prfixe de cache de lapplication avec le
nom de lapplication.
I18n
L10n
nld est maintenant la locale par dfaut pour Dutch comme spcifi par ISO 639-3 et dut pour ses alias.
Les dossiers locale ont t ajusts pour cela (from /Locale/dut/ to /Locale/nld/ ).
Albanian est maintenant sqi, le Basque est maintenant eus, le Chinese est maintentant zho, Tibetan
est maintenant bod, Czech est maintenant ces, Farsi est maitenant fas, French est maitenant fra, Icelandic est maitenant isl, Macedonian est maitenant mkd, Malaysian est maitenant msa, Romanian est
maitenant ron, Serbian est maitenant srp et le Slovak est maitenant slk. Les dossiers locale correspondant ont t aussi ajusts.
Core
CakePlugin
CakePlugin::load() peut maintenant prendre une nouvelle option ignoreMissing. Le configurer true va empcher les erreurs dinclusion du fichier quand vous essayez de charger les routes
ou le bootstrap, mais quils nexistent pas pour un plugin. Alors essentiellement, vous pouvez maintenant utiliser la dclaration suivante qui va charger tous les plugins et leurs routes et bootstrap
quelque soit le plugin trouv : : CakePlugin::loadAll(array(array(routes => true,
bootstrap => true, ignoreMissing => true)))
1045
Configure
Configure::check() a t ajoute. Cette mthode fonctionne de la manire que
CakeSession::check().
ConfigReaderInterface::dump() a t ajoute. Merci de vous assurer que tout lecteur personnalis que vous avez a maintenant une mthode dump() inplemente.
Le paramtre $key de IniReader::dump() supporte maintenant les cls comme PluginName.keyname similaire PhpReader::dump().
Error
Exceptions
CakeBaseException a t ajout, auquel toutes les Exceptions du coeur tendent. La classe dException de
base introduit aussi la mthode responseHeader() qui peut tre appele sur les instances dException
cres pour ajouter les headers la rponse, puisque les Exceptions ne rutilisent pas toute instance de
rponse.
Model
Le support pour le type biginteger a t ajout pour toutes les sources de donnes du coeur, et les fixtures.
Support pour les indices FULLTEXT a t ajout pour le driver MySQL.
Models
Model::find(list) dfinit maintenant recursive bas sur le containment depth max ou la
valeur rcursive. Quand la liste est utilise avec ContainableBehavior.
Model::find(first) va maintenant retourner un tableau vide quand aucun enregistrement nest
trouv.
Validation
Les mthodes de manque pour les validations vont toujours maintenant attraper les erreurs au lieu de le
faire seulement en mode dveloppement.
Network
SmtpTransport
Le support TLS/SSL a t ajout pour les connexions SMTP.
1046
CakeRequest
CakeRequest::onlyAllow() a t ajoute.
CakeRequest::query() a t ajoute.
CakeResponse
CakeResponse::file() a t ajoute.
Les types de contenu application/javascript, application/xml, application/rss+xml envoient maitntenant
aussi le charset de lapplication.
CakeEmail
Loption contentDisposition a t ajoute CakeEmail::attachments(). Cela vous permet de dsactiver le header Content-Disposition ajout aux fichiers joints.
HttpSocket
HttpSocket vrifie maintenant les certificats SSL par dfaut. Si vous utilisez les certificats signs-soimme ou si vous vous connectez travers des proxies, vous avez besoin dutiliser quelques unes des
options pour augmenter ce comportement. Regardez Grer les certificats SSL pour plus dinformations.
HttpResponse a t renomme en HttpSocketResponse. Ceci vite un problme commun avec
lextension HTTP PECL. Il y a une classe HttpResponse fournie ainsi que pour des raisons de compatibilit.
Routing
Router
Support pour tel:, sms: ont t ajouts Router::url().
View
MediaView est dprci, et vous pouvez maintenant utiliser les nouvelles fonctionnalits dans
CakeResponse pour atteindre les mmes rsultats.
La Serialization dans les vues Json et Xml ont t dplacs vers _serialize().
Les callbacks beforeRender et afterRender sont maintenant appels dans les vues Json et Xml quand on
utilise les templates de vue.
View::fetch() a maintenant un agument $default. Cet argument peut tre utilis pour fournir une
valeur par dfaut si un block doit tre vide.
View::prepend() a t ajout pour permettre de mettre du contenu avant le block existant.
XmlView utilise maintenant la variable de vue _rootNode pour personnaliser le noeid XML de haut
niveau.
1047
View::elementExists() a t ajoute. Vous pouvez utiliser cette mthode pour vrifier si les elements existe avant de les utiliser.
View::element() a une nouvelle option ignoreMissing. Vous pouvez utiliser ceci pour supprimer les erreurs attrapes quand il manque des elements de vue.
View::startIfEmpty() a t ajoute.
Layout
Le doctype pour les fichiers de layout dans le dossier app et les templates de bake dans le package cake a
t chang de XHTML en HTML5.
Helpers
1048
PaginatorHelper
PaginatorHelper::numbers() a maintenant une nouvelle option currentTag pour permettre
de specifier une balise supplmentaire pour entourer le nombre de page courant.
Pour les mthodes : PaginatorHelper::prev() et PaginatorHelper::next(), il est aussi
maintenant possible de dfinir loption tag false pour dsactiver le wrapper. Aussi une nouvelle
option disabledTag a t ajoute pour ces deux nouvelles mthodes.
Testing
Une fixture du coeur par dfaut pour la table cake_sessions a t ajoute. Vous pouvez lutiliser en
ajoutant core.cake_sessions votre liste de fixture.
CakeTestCase::getMockForModel() a t ajoute. Ceci simplifie lobtention des objets mock
pour les models.
Utility
CakeNumber
CakeNumber::fromReadableSize() a t ajoute.
CakeNumber::formatDelta() a t ajoute.
CakeNumber::defaultCurrency() a t ajoute.
Folder
Folder::copy() et Folder::move() supportent maintenant la possiblit de fusionner les rpertoires de cible et de source en plus de sauter le suivant/crire par dessus.
String
String::tail() a t ajout pour tronquer le texte en commenant par la fin.
ending dans String::truncate() est dprci en faveur de ellipsis.
Debugger
Debugger::exportVar() sort maintenant des proprits private et protected dans PHP >= 5.3.0.
Security
Le support pour bcrypt 1 a t ajout. Regardez la documentation de Security::hash() pour plus
dinformations sur la faon dutiliser bcrypt.
1. http ://codahale.com/how-to-safely-store-a-password/
1049
Validation
Validation::fileSize() a t ajoute.
ObjectCollection
ObjectCollection::attached() a t dprcie en faveur dune nouvelle mthode
ObjectCollection::loaded(). Ceci uniformise laccs ObjectCollection puisque
load()/unload() remplace dj attach()/detach().
1050
Une option a t ajoute pour craser les fichiers POT existant par dfaut :
./Console/cake i18n extract --overwrite
Models
Model::_findCount() va maintenant appeler les mthodes find personnalises avec $state =
before et $queryData[operation] = count. Dans certains cas, les finds personnaliss retournent toujours le bon compte pour la pagination, mais la cl operation permet plus de
flexibilit pour construire les autres requtes, ou de supprimer les joins qui sont requis pour le finder
personnnalis lui-mme. Puisque la pagination de mthodes find personnalises ne fonctionne presque
jamais, il y a besoin ce workarounds pour cela dans le niveau de model, qui ne sont plus necssaires.
Datasources
Les sources de donnes Dbo supportent maintenant les transactions relles imbriques. Si
vous avez besoin dutiliser cette fonctionnalit dans votre application, activez la en utilisant ConnectionManager::getDataSource(default)->useNestedTransactions
= true;
Testing
Le webrunner inclut maintenant des liens pour re-lancer un test avec la sortie en debug.
Les cas de test gnrs pour Controller sont maintenant des sous-classes de ControllerTestCase.
Error Handling
Quand les exceptions se rptent, ou que les exceptions sont leves quand on rend les pages derreur, le
nouveau layout error sera utilis. Il est recommand de ne pas utiliser de helpers supplmentaires dans
ce layout puisque il est l pour les erreurs de niveau dveloppeur seulement. Cela rgle les problmes des
erreurs fatales dans le rendu des pages derreur d lutilisation du helper dans le layout default.
Il est important de copier app/View/Layouts/error.ctp dans votre rpertoire. Ne pas le faire
ainsi mettra en chec le rendu des pages erreurs.
1051
NotImplementedException a t ajout.
Core
Configure
Configure::dump() a t ajoute. Elle est utilise pour rendre les donnes de configuration persistentes dans des stockages durables comme des fichiers. Les deux PhpReader et IniReader fonctionnent avec elle.
Un nouveau paramtre de config Config.timezone est disponible que vous pouvez dfinir comme une chane de timezone dutilisateur. Par ex, vous pouvez faire
Configure::write(Config.timezone, Europe/Paris). Si une mthode de la
classe CakeTime est appele avec le paramtre $timezone null et Config.timezone est dfini,
alors la valeur de Config.timezone sera utilise. Cette fonctionnalit vous permet de dfinir le timezone
dutilisateur juste une fois au lieu de le passer chaque fois dans les appels de fonction.
Controller
AuthComponent
Les options pour les adapters dfinies dans AuthComponent::$authenticate accptent maintenant une option contain. Ceci est utilis pour dfinir des options de contenance pour le cas o les
enregistrements de lutilisateur sont chargs.
CookieComponent
Vous pouvez maintenant crypter les valeurs de cookie avec le rijndael cipher. Ceci ncessite linstallation
de lextension mcrypt 2 . Utiliser rijndael donne aux valeurs du cookie le cryptage rel, et est recommand
la place de XOR cipher disponible dans les versions prcdentes. Le XOR cipher est toujours le schma
par dfaut de cipher pour maintenir la compatibilit avec les versions prcdentes. Vous pouvez en lire
plus dans la documentation Security::rijndael().
2. http ://php.net/mcrypt
1052
Pagination
Paginer les finders personnaliss va maintenant retourner des comptes corrects, vois les changements de
Model pour plus dinformations.
Network
CakeEmail
CakeRequest
va
maintenant
automatiquement
dcoder
les
corps
de
requte
application/x-www-form-urlencoded sur les requtes PUT et DELETE. Ces donnes
seront disponibles dans $this->data exactement comme les donnes POST le sont.
Utility
Set
La classe Set est maintenant dprcie, et remplace par la classe Hash. Set ne sera pas retir avant 3.0.
Set::expand() a t ajoute.
Hash
La classe Hash a t ajoute dans 2.2. Elle remplace Set en fournissant une API plus cohrente, fiable et
performante pour faire plusieurs des tches que fait Set. Regardez la page Hash pour plus de dtails.
CakeTime
Le paramtre $userOffset a t remplac par le paramtre $timezone dans toutes les fonctions
pertinentes. Donc au lieu de la sortie numrique, vous pouvez maintenant passer une chane timezone
ou un objet DateTimeZone. Passer les sorties numriques pour le paramtre $timezone est toujours
possible pour une compatibilit rtro-active.
1053
CakeTime::timeAgoInWords() a loption accuracy ajoute. Cette option vous permet de spcifier la prcision que doivent avoir les times formats.
Nouvelles mthodes ajoutes :
CakeTime::toServer()
CakeTime::timezone()
CakeTime::listTimezones()
Le paramtre $dateString dans toutes les mthodes accptent maintenant un objet DateTime.
Helpers
FormHelper
FormHelper gre maintenant mieux lajout des classes requises aux entres. Il honore maintenant la cl
on.
FormHelper::radio() supporte maintenant empty qui fonctionne de la mme faon que loption
empty de select().
Ajout de FormHelper::inputDefaults() pour dfinir les proprits habituelles pour chacune de
ses entres gnres par le Helper.
TimeHelper
Depuis 2.1, TimeHelper utilise la classe CakeTime pour toutes ses mthodes pertinentes. Le paramtre
$userOffset a t remplac par le paramtre $timezone.
TimeHelper::timeAgoInWords() a loption element ajoute. Cela vous permet de spcifier un
lment HTML pour entourer le time format.
HtmlHelper
Les couteurs dEvent peuvent maintenant tre attachs aux appels du dispatcher, ceux-ci vont avoir la
capacit de changer linformation de requte ou la rponse avant quelle soit envoye au client. Vrifiez
la documentation complte pour ces nouvelles fonctionnalits dans Filtres du Dispatcher
Avec lajout de Filtres du Dispatcher vous aurez besoin de mettre jour
app/Config/bootstrap.php. Regardez Etapes requises pour mettre jour.
1054
Router
Un nouveau moteur de cache a t ajout en utilisant phpredis extension 3 il est configur de la mme
manire que le moteur Memcache.
Cache groups
Il est maintenant possible de tagger ou de labeliser les cls de cache sous les groupes. Cela facilite pour
supprimer en masse les entres associes mise en cache avec le mme label. Les groupes sont dclars au
moment de la configuration quand on cre le moteur de cache :
Cache::config(array(
'engine' => 'Redis',
...
'groups' => array('post', 'comment', 'user')
));
Vous pouvez avoir autant de groupes que vous le souhaitez, mais gardez lesprit quils ne peuvent pas tre
modifis dynamiquement.
La mthode de la classe Cache::clearGroup() a t ajoute. Elle prende le nom du groupe et supprime
toutes les entres labelises avec la mme chane.
Log
Les changements dans CakeLog requirent maintenant une configuration supplmentaire dans votre
app/Config/bootstrap.php. Regardez Etapes requises pour mettre jour, et Journalisation (logging).
La classe CakeLog accpte maintenant les mmes niveaux de log que dfini dans RFC 5424 4 . Plusieurs
mthodes pratiques ont t aussi ajoutes :
CakeLog::emergency($message, $scope = array())
CakeLog::alert($message, $scope = array())
CakeLog::critical($message, $scope = array())
CakeLog::error($message, $scope = array())
CakeLog::warning($message, $scope = array())
CakeLog::notice($message, $scope = array())
CakeLog::info($message, $scope = array())
3. https ://github.com/nicolasff/phpredis
4. http ://tools.ietf.org/html/rfc5424
1055
1056
Si votre application a ces fichiers/classes, vous navez rien besoin de faire. De plus, si vous utilisiez le
PagesController du coeur, vous aurez aussi besoin de le copier dans votre rpertoire app/Controller.
Fichiers .htaccess
Les fichiers .htaccess par dfaut ont chang, vous devrez vous rappeler de les mettre jour ou de mettre
jour les schmas URL de re-writing de vos serveurs web pour correspondre aux changements faits dans
.htaccess
Models
Le callback beforeDelete sera vid avant les callbacks beforeDelete des behaviors. Cela donne plus
de cohrence avec le reste des vnements dclenchs dans la couche Model.
Model::find(threaded) accepte maintenant $options[parent] si vous utilisez un
autre champ, alors parent_id. Aussi, si le model a TreeBehavior attach et configur avec un autre
champ parent, le find threaded lutilisera par dfaut.
Les paramtres pour les requtes utilisant les requtes prpares vont maintenant faire partie de linstruction SQL.
Les tableaux de validation peuvent maintenant tre plus prcis quand un champ est obligatoire. La cl
required accepte create et update. Ces valeurs rendront un champ obligatoire lors de la cration
ou la mise jour.
Model now has a schemaName property. If your application switches datasources by
modifying Model::$useDbConfig you should also modify schemaName or use
Model::setDataSource() method which handles this for you. Le Model a maintenant
une proprit schemaName. Si votre application change de sources de donnes en modifiant
Model::$useDbConfig, vous devriez aussi modifier schemaName ou utiliser la mthode
Model::setDataSource() qui gre cela pour vous.
CakeSession
Modifi dans la version 2.1.1 : CakeSession ne fixe plus len-tte P3P, puisque cela relve de la responsabilit
de votre application.
Behaviors
TranslateBehavior
1057
Exceptions
Lexception par dfaut de rendu inclut maintenant des traces de pile plus dtailles y compris des extraits de
fichiers et les dcharges darguments pour toutes les fonctions dans la pile.
Utilitaire
Debugger
Debugger::getType() a t ajoute. Elle peut tre utilise pour rcuprer le type de variables.
Debugger::exportVar() a t modifie pour crer une sortie plus lisible et plus utile.
debug()
debug() utilise maintenant Debugger en interne. Cela la rend plus cohrente avec avec Debugger, et profite
des amliorations fates ici.
Set
Set::nest() a t ajoute. Elle prend en argument un tableau plat et retourne un tableau imbriqu.
File
App::build() a maintenant la possibilit denregistrer de nouveaux paquets laide deApp : :REGISTER. Voir Ajoutez de nouveaux packages vers une application pour plus dinformations.
Les classes qui ne peuvent pas tre trouves sur les chemins configurs vont tre cherches dans APP
comme un chemin de secours. Cela facilite le chargement automatique des rpertoires imbriqus dans
app/Vendor.
1058
Console
Shell de Test
Un nouveau TestShell a t ajout. Il rduit le typage requis pour excuter les tests unitaires, et offre un
chemin de fichier en fonction dinterface utilisateur
# Execute les tests du model post
Console/cake test app/Model/Post.php
Console/cake test app/Controller/PostsController.php
Les fichiers gnrs ne contiennent plus les timestamps avec la gnration des datetime.
Routing
Router
Les routes peuvent maintenant utiliser une syntaxe spciale /** pour inclure tous les arguments de fin en
un argument unique pass . Voir la section sur Connecter les Routes pour plus dinformations.
Router::resourceMap() a t ajoute.
Router::defaultRouteClass() a t ajoute. Cette mthode vous autorise dfinir la classe
route par dfaut utilise pour toutes les routes venir qui sont connects.
Rseau
CakeRequest
Controller::$uses a t modifi, la valeur par dfaut est maintenant true la place de false. De
plus, les diffrentes valeurs sont traites de faon lgrement diffrente, mais se comportera comme cela
2.1 Guide de Migration
1059
AuthComponent::allow() naccepte plus allow(*) en joker pour toutes les actions. Utilisez
juste allow(). Cela unifie lAPI entre allow() et deny().
Loption recursive a t ajoute toutes les cartes dauthentification. Vous permet de contrler plus
facilement les associations stockes dans la session.
AclComponent
AclComponent ne met plus en minuscules et ninflchit plus le nom de classe utilis pour
Acl.classname. A la place, il utilise la valeur fournie comme telle.
Les
implmentations
Backend
Acl
devraient
maintenant
tre
mis
dans
Controller/Component/Acl.
Les implmentations Acl doivent tre dplaces dans le dossier Component/Acl partir de
Component. Par exemple si votre classe Acl a t appele CustomAclComponent, et
tait dans Controller/Component/CustomAclComponent.php. Il doit tre dplac dans
Controller/Component/Acl/CustomAcl.php, et tre nomm CustomAcl.
DbAcl a t dplace dans un fichier spar.
IniAcl a t dplace dans un fichier spar.
AclInterface a t dplace dans un fichier spar.
Helpers
TextHelper
TextHelper::autoLink(),
TextHelper::autoLinkUrls(),
TextHelper::autoLinkEmails() echappe les inputs HTMS par dfaut. Vous pouvez contrler loption escape.
HtmlHelper
1060
$scripts_for_layout est toujours disponible, mais lAPI view blocks donne un remplacement plus
extensible et flexible.
La syntaxe Plugin.view est maintenant disponible partout. Vous pouvez utiliser cette syntaxe nimporte o, vous rferencez le nom de la vue, du layout ou de lelment.
Loption $options[plugin] pour element() est dprci. Vous devez utiliser
Plugin.nom_element la place.
Vues de type contenu
Deux nouvelles classes de vues ont t ajoutes CakePHP. Une nouvelle classe JsonView et XmlView
vous permettent de facilement gnrer des vues XML et JSON. Vous en apprendrez plus sur ces classes dans
la section Vues JSON et XML.
Vues tendues
View a une nouvelle mthode vous permettant denrouler ou tendre une vue/lment/layout avec un autre
fichier. Voir la section sur Vues tendues pour plus dinformations sur cette fonctionnalit.
Thmes
La classe ThemeView est dprecie en faveur de la classe View. En mettant simplement $this->theme
= MonTheme activera le support theme et toutes les classes de vue qui tendaient ThemeView devront
tendre View.
1061
Blocks de Vue
Les blocks de Vue sont une faon flexible de crer des slots ou blocks dans vos vues. Les blocks remplacent
$scripts_for_layout avec une API robuste et flexible. Voir la section sur Utiliser les Blocs de Vues
pour plus dinformations.
Helpers
Nouveaux callbacks
FormHelper omet dsormais des champs dsactivs partir des champs hash scuriss. Cela permet le
fonctionnement avec SecurityComponent et dsactive les inputs plus facilement.
Loption between quand elle est utilise dans le cas dinputs radio, se comporte maintenant diffremment. La valeur between est maintenant place entre le lgende et les premiers lments inputs.
Loption hiddenField avec les inputs checkbox peuvent maintenant tre mis une valeur spcifique
comme N plutt que seulement 0.
Lattribut for pour les inputs date et time refltent maintenant le premier input gnr. Cela peut impliquer que lattribut for peut changer les inputs datetime gnrs.
Lattribut type pour FormHelper::button() peut maintenant tre retir. Il met toujours submit
par dfaut.
FormHelper::radio() vous permet maintenant de dsactiver toutes les options. Vous pouvez le
faire en mettant soit disabled => true soit disabled => disabled dans le tableau
$attributes.
PaginatorHelper
1062
Les Models chargs utilisant la ClassRegistry et utilisant une autre source de donnes aura son nom de
source donne prfix par test_ (ex : source de donnes master essaiera dutiliser test_master dans la
testsuite)
Les cas de Test sont gnrs avec des mthodes de configuration de la classe spcifique.
Evnements
Un nouveau systme gnrique des vnements a t construit et a remplac la faon dont les callbacks
ont t dispatchs. Cela ne devrait reprsenter aucun changement dans votre code.
Vous pouvez envoyer vos propres vnements et leur attacher des callbacks selon vos souhaits, utile pour
la communication inter-plugin et facilite le dcouplage de vos classes.
Model::saveAll() et ses amis supportent maintenant le passement de fieldList pour de multiples modles. Exemple :
$this->SomeModel->saveAll($data, array(
'fieldList' => array(
'SomeModel' => array('field_1'),
'AssociatedModel' => array('field_2', 'field_3')
)
));
Model::saveAll() et ses amis peuvent maintenant sauvegarder sur des niveaux de profondeur illimits.
Exemple :
$data = array(
'Article' => array('title' => 'My first article'),
'Comment' => array(
array('body' => 'Comment 1', 'user_id' => 1),
array('body' => 'Save a new user as well', 'User' => array('first' => 'mad', 'last'
),
);
$this->SomeModel->saveAll($data, array('deep' => true));
View
View Blocks (Blocks de Vue)
View Blocks sont un mcanisme permettant linclusion de slots de contenu, en autorisant les classes enfants
de vue ou les lments fournir le contenu personnalis pour ce block.
1063
Les blocks sont sortis en appelant la mthode fetch sur View. Par exemple, ce qui suit peut tre plac
dans votre fichier View/Layouts/default.ctp :
<?php echo $this->fetch('my_block'); ?>
Cela affichera le contenu du block si disponible, ou ue chane de caractre vide si elle nest pas dfinie.
Dfinir le contenu dun block peut tre fait de plusieurs faons. Une simple attribution de donne peut tre
faite en utilisant assign :
<?php $this->assign('my_block', 'Hello Block'); ?>
Ou vous pouvez lutiliser pour capturer une section de contenu plus complexe :
<?php $this->start('my_block'); ?>
<h1>Hello Block!</h1>
<p>Ceci est block de contenu</p>
<p>Page title: <?php echo $title_for_layout; ?></p>
<?php $this->end(); ?>
ThemeView
Dans 2.1, lutilisation de ThemeView est dprcie en faveur de lutilisation de la classe View elle-mme.
ThemeView est maintenant une classe stub.
All custom pathing code has been moved into the View class, meaning that it is now possible for classes
extending the View class to automatically support themes. Whereas before we might set the $viewClass
Controller property to Theme, it is now possible to enable themes by simply setting the $theme property.
Example :
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $theme = 'Exemple';
}
Toutes les classe View qui tendent ThemeView dans 2.0 doivent maintenant simplement tendre View.
1064
JsonView
Une fois que vous avez configur le controller, vous avez besoin didentifier quel contenu devrait tre srialis en JSON, en paramtrant la variable vue _serialize. Exemple :
$this->set(compact('users', 'posts', 'tags'));
$this->set('_serialize', array('users', 'posts'));
Lexemple ci-dessus rsulterait seulement dans les variables users et posts, tant srialis pour la sortie
JSON, comme ceci :
{"users": [...], "posts": [...]}
Il ny a plus aucun besoin de crer des fichiers de vue ctp afin dafficher le contenu Json.
La personnalisation future de la sortie peut tre atteinte en tendant la classe JsonView avec votre propre
classe de vue personnalise si requise.
Les exemples suivants entourent le rsultat avec {results: ... } :
App::uses('JsonView', 'View');
class ResultsJsonView extends JsonView {
public function render($view = null, $layout = null) {
$result = parent::render($view, $layout);
if (isset($this->viewVars['_serialize'])) {
return json_encode(array('results' => json_decode($result)));
}
return $result;
}
}
XmlView
Un peu comme JsonView, XmlView requirt que vous configuriez la variable de vue _serialize afin
dindiquer quelle information serait srialise en XML pour la sortie.
$this->set(compact(users, posts, tags)) ; $this->set(_serialize, array(users, posts)) ;
Lexemple ci-dessus rsulterait dans seulement les variables users et posts tant srialises pour la sortie
XML, comme ceci :
2.1 Guide de Migration
1065
<response><users>...</users><posts>...</posts></response>
Notez que XmlView ajoute un noeud de response pour entourer tout contenu srialis.
Rendu de Vue conditionnel
Plusieurs nouvelles mthodes ont t ajoutes CakeRequest pour faciliter la tche de paramtrer les
headers HTTP corrects en mettant le HTTP en cache. Vous pouvez maintenant dfinir notre stratgie de
mise en cache en utilisant lexpiration ou la validation HTTP du cache du model, ou de combiner les deux.
Maintenant, il y a des mthodes spcifiques dans CakeRequest to fine-tune Cache-Control directives, set
the entity tag (Etag), set the Last-Modified time and much more.
Quand ces mthodes sont combins avec le RequestHandlerComponent activ dans votre controller,
le component dcidera automatiquement si la rponse est dj mise en cache dans le client et enverra un
code de statut 304 Not Modified avant le rendu de la vue. Sauter le processus de rendu de vue sauvegarde
les cycles CPU et la mmoire.
class ArticlesController extends AppController {
public $components = array('RequestHandler');
public function view($id) {
$article = $this->Article->findById($id);
$this->response->modified($article['Article']['modified']);
$this->set(compact('article'));
}
}
Dans lexemple ci-dessus, la vue ne sera pas rendu si le client envoie le header If-Modified-Since, et la
rponse aura un statut 304.
Helpers
Pour faciliter lutilisation en dehors de la couche View, les mthodes des helpers TimeHelper,
TextHelper, et NumberHelper ont t extraites respectivement des classes CakeTime, String,
et CakeNumber.
Pour utiliser les nouvelles classes utilitaires :
class AppController extends Controller {
public function log($msg) {
$msg .= String::truncate($msg, 100);
parent::log($msg);
}
}
Vous pouvez craser la classe par dfaut utiliser en crant une nouvelle classe dans votre dossier
APP/Utility, par exemple : Utility/MyAwesomeStringClass.php, et le spcifier dans la cl
engine :
1066
// Utility/MyAwesomeStringClass.php
class MyAwesomeStringClass extends String {
// mon truchement est meilleur que les votres
public static function truncate($text, $length = 100, $options = array()) {
return null;
}
}
// Controller/AppController.php
class AppController extends Controller {
public $helpers = array(
'Text' => array(
'engine' => 'MyAwesomeStringClass',
),
);
}
HtmlHelper
Une nouvelle fonction HtmlHelper::media() a t ajoute pour la gnration dlments HTML audio/video.
1067
Tous les fichiers contenant les classes doivent tre nomms selon la classe quil contiennent. Aucun fichier
ne doit contenir plus dune classe. Donc, plus de minuscules ou de soulignements dans les noms de fichier.
Voici quelques exemples :
mes_trucs_controller.php devient MesTrucsController.php
form.php (un Helper) devient FormHelper.php
session.php (un Component) devient SessionComponent.php
Cela rend le nommage des fichiers beaucoup plus clair et cohrent travers les applications, et aussi vite
quelques cas o le chargement des fichiers aurait pu t gn dans le pass et aurait pu entrain un chargement non souhait de fichiers.
Les Noms des Dossiers
La plupart des dossiers devront tre en CamelCase, spcialement ceux contenant des classes. En songeant
aux espaces de noms, chaque dossier reprsente un niveau dans la hirachie des espaces de noms, les dossiers
qui ne contiennent pas de classes, ou ne constituent pas un espace de noms sur eux-mmes, devraient tre
en LowerCase.
Dossiers en CamelCase :
Config
Console
Controller
Controller/Component
Lib
Locale
Model
1068
Model/Behavior
Plugin
Test
Vendor
View
View/Helper
Dossiers en LowerCase :
tmp
webroot
htaccess (URL Rewriting)
Dans votre fichier app/webroot/.htaccess remplacez le RewriteRule ^(.*)$
index.php?url=$1 [QSA,L] avec RewriteRule ^(.*)$ index.php?/$1 [QSA,L]
AppController / AppModel / AppHelper / AppShell
Les fichiers app/app_controller.php, app/app_model.php, app/app_helper.php
sont situs et nomms respectivement comme ceci app/Controller/AppController.php,
app/Model/AppModel.php et app/View/Helper/AppHelper.php.
Aussi, les shell/task sont tendus (extend) Appshell. Vous pouvez avoir votre propre AppShell.php dans
app/Console/Command/AppShell.php.
Internationalization / Localization
__() (La fonction raccourci de Double underscore) retourne toujours la traduction (plus de echo).
Si vous voulez changer les rsultats de la traduction, utilisez :
echo __('Mon Message');
A ct de cela, si vous passez des paramtres supplmentaires, la traduction appelera sprintf 5 avec ces
paramtres retourns prcdemment avant de retourner. Par exemple :
// Retournera quelque chose comme "Appel: MaClasse:maMethode"
echo __('Appel: %s:%s', $nomdelaclasse, $nomdelamethode);
5. http ://php.net/manual/en/function.sprintf.php
1069
Constantes Retires
Un nombre de constantes ont t retires, puisquelles nataient plus exactes ou bien taient dupliques.
APP_PATH
BEHAVIORS
COMPONENTS
CONFIGS
CONSOLE_LIBS
CONTROLLERS
CONTROLLER_TESTS
ELEMENTS
HELPERS
HELPER_TESTS
LAYOUTS
LIB_TESTS
LIBS
MODELS
MODEL_TESTS
6. http ://php.net/manual/en/function.sprintf.php
1070
SCRIPTS
VIEWS
CakeRequest
Cette nouvelle classe encapsule les paramtres et fonctions lies aux requtes entrantes. Elle remplace
plusieurs fonctionnalits de Dispatcher, RequestHandlerComponent et Controller. Elle remplace
aussi le tableau $this->params tout endroit. CakeRequest implmente ArrayAccess donc la
plupart des interactions avec les anciens tableaux params nont pas besoin de changement. Voir les nouvelles fonctionnalits de CakeRequest pour plus dinformations.
Gestion des Requtes, $_GET[url] et fichiers .htaccess
CakePHP nutilise plus $_GET[url] pour la gestion des chemins des requtes de lapplication. A la
place il utilise $_SERVER[PATH_INFO]. Cela fournit une faon plus uniforme de gestion des requtes
entre les serveurs avec URL rewriting et ceux sans. Du fait de ces changements, vous aurez besoin de mettre
jour vos fichiers .htaccess et app/webroot/index.php, puisque ces fichiers ont t changs pour
accueillir les changements. De plus, $this->params[url][url] nexiste plus. A la place, vous
devrez utiliser $this->request->url pour accder la mme valeur. Cet attribut contient maintenant lurl sans
slash / au dbut.
Note : Pour la page daccueil elle-mme (http://domain/) $this->request->url retourne maintenant le
bolen false au lieu de /. Assurez-vous de vrifier cela de cette faon :
if (!$this->request->url) {} // au lieu de $this->request->url === '/'
Components (Composants)
Component est maintenant la classe de base requise pour tous les components (components). Vous devrez
mettre jour vos components et leurs constructeurs, puisque tous deux ont chang :
class PrgComponent extends Component {
public function __construct(ComponentCollection $collection, $settings = array()) {
parent::__construct($collection, $settings);
}
}
Tout comme les helpers il est important dappeler parent::__construct() dans les components avec
les constructeurs surchargs. Les paramtres pour un component sont aussi maintenant passs travers le
constructeur, et non plus via le callback initialize(). Cela aide avoir de bons objets construits, et
autorise la classe de base grer les proprits suprieures.
Depuis que les paramtres ont t dplacs au constructeur du component, le callback initialize()
ne reoit plus $settings en 2me paramtre. Vous devrez mettre jour vos components pour utiliser la
signature mthode suivante :
public function initialize($controller) { }
1071
De plus, la mthode initialize() est seulement appele sur les components qui sont permis. Cela signifie en
gnral que les components qui sont directement attachs lobjet controller.
Callbacks dprcis supprims
Tous les callbacks dprcis dans Component ont t transfrs ComponentCollection. A la place, vous
devriez utiliser la mthode trigger() pour intragir avec les callbacks. Si vous avez besoin de dclencher un
callback, vous pouvez le faire en appelant :
$this->Components->trigger('someCallback', array(&$this));
Dans le pass, vous tiez capable de dsactiver les components via $this->Auth->enabled = false ; par
exemple. Dans CakePHP 2.0 vous devriez utiliser la mthode de dsactivation des ComponentCollections,
$this->Components->disable(Auth) ;. Utiliser les proprits actives ne va pas fonctionner.
AclComponent
Beaucoup de mthodes de RequestHandlerComponent sont justes des proxies pour les mthodes de
CakeRequest. Le mthodes suivantes ont t dprcies et seront retires dans les versions futures :
isSsl()
isAjax()
isPost()
isPut()
isFlash()
isDelete()
getReferer()
getClientIp()
accepts(), prefers(), requestedWith() Tous sont maintenant grs dans
les
types de contenu. Ils ne fonctionnent plus avec les mime-types. Vous pouvez utiliser
RequestHandler::setContent() pour crer des nouveaux types de contenu.
RequestHandler::setContent() naccepte plus de tableau en tant quargument unique, vous
devez fournir les deux arguments.
1072
SecurityComponent
SecurityComponent ne gre plus lAuthentification Basic et Sommaire (Digest). Elles sont toutes deux
gres par le nouveau AuthComponent. Les mthodes suivantes ont t retires de SecurityComponent :
requireLogin()
generateDigestResponseHash()
loginCredentials()
loginRequest()
parseDigestAuthData()
De plus les proprits suivantes ont t retires :
$loginUsers
$requireLogin
Le dplacement des fonctionalits verss Authcomponent a t faite pour fournir un endroit unique pour tous
les types dauthentification et pour rationaliser les rles de chaque component.
AuthComponent
AuthComponent a t entirement refait dans 2.0, a a t fait pour rduire les confusions et frustrations des
dveloppeurs. De plus, AuthComponent a t construit plus flexible et extensible. Vous pouvez trouver plus
dinformations dans le guide Authentification.
EmailComponent
EmailComponent a t dpreci et a t cre une nouvelle classe de librairie pour envoyer les emails. Voir
les changements pour Email CakeEmail pour plus de dtails.
SessionComponent
1073
Classes Lib
App
LAPI pour App::build() a chang pour App::build($paths, $mode). Elle vous autorise maintenant soit ajouter, soit faire prcder ou bien rinitialiser / remplacer les chemins existants. Le paramtre
$mode peut prendre nimporte lesquelles des 3 valeurs suivantes : App : :APPEND, App : :PREPEND,
App::RESET. Le behavior par dfaut de la fonction reste le mme (ex. Faire prcder des nouveaux
chemins par une liste existante).
App : :path()
Supporte maintenant les plugins, App : :path(Controller, Users) va retourner la localisation du dossier
des controllers dans le plugin des users.
Ne fusionnera plus les chemins du coeur, il retournera seulement les chemins dfinies dans App : :build()
et ceux par dfaut dans app (ou correspondant au plugin).
App : :build()
Ne fusionnera plus le chemin de app avec les chemins du coeur.
App : :objects()
Supporte maintenant les plugins, App : :objects(Users.Model) va retourner les models dans le plugin
Users.
Retourne array() au lieu de false pour les rsultats vides ou les types invalides.
Ne retourne plus les objets du coeur, App : :objects(core) retournera array().
Retourne le nom complet de la classe.
La classe App perd les proprits suivantes, utilisez la mthode App : :path() pour accder leur valeur
App : :$models
App : :$behaviors
App : :$controllers
App : :$components
App : :$datasources
App : :$libs
App : :$views
App : :$helpers
App : :$plugins
App : :$vendors
App : :$locales
App : :$shells
App : :import()
Ne recherche plus les classes de faon rcursive, il utilise strictement les valeurs pour les chemins dfinis
dans App : :build().
Ne sera plus capable de charger App : :import(Component, Component), utilisez
App : :uses(Component, Controller) ;
Utiliser App : :import(Lib, CoreClass) pour charger les classes du coeur nest plus possible.
1074
Importer un fichier non-existant, fournir un mauvais type ou un mauvais nom de package, ou des valeurs
nulles pour les paramtres $name et $file va donner une fausse valeur de retour.
App : :import(Core, CoreClass) nest plus support, utilisez App : :uses() la place et laisser la classe
autoloading faire le reste.
Charger des fichiers Vendor ne recherchera pas de faon rcursive dans les dossiers Vendors, cela ne
convertira plus le fichier en underscore comme cela se faisant dans le pass.
App : :core()
Le premier paramtres nest plus optionnel, il retournera toujours un chemin.
Il ne peut plus tre utilis pour obtenir les chemins des vendors.
Il acceptera seulement le nouveau style des noms de package.
Chargement des Classes avec App : :uses() Bien quil y ait eu une re-construction norme dans la faon
de charger les classes, pour quelques occasions, vous aurez besoin de changer le code de votre application
pour respecter la faon que vous aviez lhabitude de faire. Le plus grand changement est lintroduction dune
nouvelle mthode :
App::uses('AuthComponent', 'Controller/Component');
Nous avons dcid que le nom de la fonction devait imiter le mot-cl use de PHP 5.3, juste pour la faon de
dclarer o un nom de classe devait se trouver. Le premier paramtre de App::uses() est le nom complet
de la classe que vous avez lintention de charger, et le second paramtre, le nom du package (ou espace de
noms) auquel il appartient. La principale diffrence avec le App::import() de CakePHP 1.3 est que
lactuelle nimportera pas la classe, elle configurera juste le systme pour qu la premire utilisation de la
classe, elle soit localise.
Quelques exemples de lutilisation de App::uses() quand on migre de App::import() :
App::import('Controller', 'Pages');
// devient
App::uses('PagesController', 'Controller');
App::import('Component', 'Auth');
// devient
App::uses('AuthComponent', 'Controller/Component');
App::import('View', 'Media');
// devient
App::uses('MediaView', 'View');
App::import('Core', 'Xml');
// devient
App::uses('Xml', 'Utility');
App::import('Datasource', 'MongoDb.MongoDbSource')
// devient
App::uses('MongoDbSource', 'MongoDb.Model/Datasource')
1075
Toutes les classes qui ont t charges dans le pass utilisant App::import(Core, $class); auront besoin dtre charges en utlisant App::uses() en rfrence au bon package. Voir lAPI pour localiser les classes dans leurs nouveaux dossiers. Quelques exemples :
App::import('Core', 'CakeRoute');
// devient
App::uses('CakeRoute', 'Routing/Route');
App::import('Core', 'Sanitize');
// devient
App::uses('Sanitize', 'Utility');
App::import('Core', 'HttpSocket');
// devient
App::uses('HttpSocket', 'Network/Http');
CakeLog
La connexion aux flux a maintenant besoin de mettre en uvre : php : class : CakeLogInterface. Des
exceptions seront souleves si un enregistreur nest pas configur.
Cache
Cache est maintenant une classe statique, elle na plus de mthode getInstance().
CacheEngine est maintenant une classe abstraite. Vous ne pouvez plus directement crer dinstances de
celle-ci.
Les implmentations de CacheEngine doivent tendre CacheEngine, des exceptions seront souleves si
une classe de configuration ne lest pas.
1076
FileCache ncessite maintenant lajout de barres obliques au chemin de configuration lorsque vous modifiez une configuration du cache.
Cache ne retient plus le nom du dernier moteur de cache configur. Cela signifie que les oprations que
vous souhaitez produire sur un moteur spcifique doivent avoir le paramtre $config gale au nom de
config que vous souhaitez.
Cache::config('quelquechose');
Cache::write('key', $valeur);
// deviendrait
Cache::write('key', $valeur, 'quelquechose');
Router
Pour votre fichier de routes pour chaque plugin, vous avez besoin de routes courtes actives.
Votre fichier app/Config/routes.php doit tre mis jour en ajoutant cette ligne en bas du fichier :
require CAKE . 'Config' . DS . 'routes.php';
Cela est ncessaire afin de gnrer les routes par dfaut pour votre application. Si vous ne souhaitez pas
avoir de telles routes, ou si vous voulez implmenter votre propre standard, vous pouvez inclure votre propre
fichier avec vos propres rgles de routeur.
1077
Dispatcher
Le Dispatcher a t dplac dans cake/libs, vous devrez mettre jour votre fichier
app/webroot/index.php.
Le Dispatcher::dispatch() prend maintenant deux paramtres. Les objets request et response.
Ceux-ci devraient tre des instances de CakeRequest & CakeResponse ou une sous-classe de ceuxci.
Dispatcher::parseParams() naccepte que lobjet CakeRequest.
Dispatcher::baseUrl() a t retir.
Dispatcher::getUrl() a t retir.
Dispatcher::uri() a t retir.
Dispatcher::$here a t retir.
Configure
Configure::read() avec aucun paramtre ne retourne plus la valeur de debug, la place elle
retourne toutes les valeurs dans Configure. Utilisez Configure::read(debug); si vous voulez
la valeur de debug.
Configure::load() requiert maintenant un ConfigReader pour tre configur. Lisez Chargement
des fichiers de configuration pour plus dinformations.
Configure::store() crit maintenant les valeurs une configuration du Cache donne. Lisez
Chargement des fichiers de configuration pour plus dinformations.
Scaffold
Les vues Scaffold edit devront tre renommes par form. Cela a t fait pour rendre les templates
scaffold et bake cohrents.
views/scaffolds/edit.ctp -> View/Scaffolds/form.ctp
views/posts/scaffold.edit.ctp -> View/Posts/scaffold.form.ctp
Xml
La classe Xml a t compltement reconstruite. Maintenant cette classe ne manipule plus de donnes, et
elle est un enrouleur (wrapper) pour les SimpleXMLElement. Vous pouvez utiliser les mthodes suivantes :
Xml::build() : Mthode statique dans laquelle vous pouvez passer une chane de caractre xml,
un tableau, un chemin vers un fichier ou une url. Le rsultat va tre une instance SimpleXMLElement
ou une exception va tre envoye en cas derreurs.
Xml::fromArray(): Mthode statique qui retourne un SimpleXMLElement partir dun tableau.
Xml::toArray() : Mthode statique qui retourne un tableau partir de SimpleXMLElement.
Vous devez utiliser la documentation Xml pour plus dinformations sur les changements faits sur la classe
Xml.
1078
Inflector
CakeSession est maintenant une classe compltement statique, les deux SessionHelper et
SessionComponent sont des wrappers et du sucre pour celui-ci. Il peut facilement tre utilis dans
les models ou dans dautres contextes. Toutes ses mthodes sont appeles de faon statique.
La configuration de Session a aussi chang Voir la section session pour plus dinformations
HttpSocket
HttpSocket ne change pas les cls den-tte. Suivant les autres endroits dans le coeur, le HttpSocket ne
change pas les headers. RFC 2616 7 dit que les en-ttes sont insensibles la casse, et HttpSocket prserve
les valeurs envois de lhte distant.
HttpSocket retourne maintenant les rponses en objets. Au lieu des tableaux, HttpSocket retourne les
instances de HttpResponse. Voir la documentation de HttpSocket pour plus dinformations.
Les cookies sont stocks en interne par lhte, pas par instance. Cela signifie que, si vous fates deux
requtes diffrents serveurs, les cookies du domaine1 ne seront pas envoys au domaine2. Cela a t fait
pour viter dventuels problmes de scurit.
Helpers
Changement du constructeur
Quand vous crasez le constructeur, vous devez toujours aussi appeler parent : :__construct.
Helper : :__construct stocke linstance de vue dans $this->_View pour une rfrence future. Les configurations ne sont pas gres par le constructeur parent.
HelperCollection ajout
Aprs un examen des responsabilits de chaque classe implique dans la couche Vue, il nous est clairement
apparu que la Vue grait bien plus quune unique tche. La responsabilit de crer les helpers nest pas
7. http ://tools.ietf.org/html/rfc2616.html
1079
centrale dans ce que la Vue fait, et a t dplace dans le HelperCollection. HelperCollection est responsable
du chargement et de la construction des helpers, ainsi que de dclencher les callbacks sur les helpers. Par
dfaut, la Vue cre un HelperCollection dans son constructeur, et lutilise pour des oprations ultrieures.
LHelperCollection pour une vue peut tre trouv dans $this->Helpers.
Les motivations pour la reconstruction de cette fonctionnalit vient de quelques soucis.
La Vue qui tait enregistre dans ClassRegistry pouvait causer des problmes empoisonns denregistrement quand requestAction ou lEmailComponent taient utiliss.
La Vue accessible comme un symbole global entranait des abus.
Les Helpers ntaient pas contenus eux-mmes. Aprs avoir construit un helper, vous deviez construire
manuellement plusieurs autres objets afin dobtenir un objet fonctionnant.
Vous pouvez en lire plus sur HelperCollection dans la documentation Collections.
Proprits dprcies
Les proprits suivantes sur les helpers sont deprcies, vous devez utiliser les proprits de lobjet request
ou les mthodes de lHelper plutt que accder directement ces proprits puisquelles seront supprimes
dans une version future.
Helper::$webroot est deprcie, utilisez la proprit webroot de lobjet request.
Helper::$base est deprcie, utilisez la proprit base de lobjet request.
Helper::$here est deprcie, utilisez la proprit here de lobjet request.
Helper::$data est deprcie, utilisez la proprit data de lobjet request.
Helper::$params est deprcie, utilisez $this->request la place.
XmlHelper, AjaxHelper et JavascriptHelper retirs
Les Helpers AjaxHelper et JavascriptHelper ont t retirs puisquils taient dprcis dans la version 1.3.
Le Helper XmlHelper a t retir, puisquil tait obsolte et superflu avec les amliorations de Xml. La
classe Xml doit tre utilise pour remplacer les utilisations anciennes de XmlHelper.
Les Helpers AjaxHelper et JavascriptHelper sont remplacs par les Helpers JsHelper et HtmlHelper.
JsHelper
JsBaseEngineHelper est maintenant abstrait, vous devrez implmenter toutes les mthodes qui
gnraient avant des erreurs.
PaginatorHelper
PaginatorHelper::sort() prend maintenant les arguments title et key dans lordre invers.
$key sera maintenant toujours le premier. Cela a t fait pour prvenir les besoins dchange des
arguments lors de lajout dun second argument.
PaginatorHelper avait un nombre de changements pour les paramtres de pagination utilis en interne. Le
key par dfaut a t retir.
1080
PaginatorHelper supporte maintenant la gnration des liens avec les paramtres de pagination dans
querystring.
Il y a eu quelques amliorations dans pagination en gnral. Pour plus dinformations sur cela, vous devriez
lire la page des nouvelles fonctionnalits de pagination.
FormHelper
Le CacheHelper a t compltement dcoupl de la Vue, et des utilisations des callbacks du Helper pour
gnrer des caches. Vous devez retenir de placer CacheHelper aprs les autres helpers qui modifient le contenu dans les callbacks afterRender et afterLayout. Si vous ne le fates pas, certains changements
ne feront pas parti du contenu rcupr.
CacheHelper nutilise galement plus <cake:nocache> pour indiquer les rgions non mises en cache. A
la place, il utilise les commentaires spciaux HTML/XML. <!--nocache--> et <!--/nocache-->.
Cela aide CacheHelper gnrer des balises valides et continue effectuer les mmes fonctions quavant.
Vous pouvez en lire plus sur CacheHelper et les changements de Vue.
Les formats des attributs dHelper plus flexibles
1081
Une autre aptitude est que les attributs minimums peuvent tre passs en item et pas en cl. Par exemple :
$this->Form->checkbox('field', array('checked', 'value' => 'une_valeur'));
La Pagination tait traditionnellement une unique mthode dans le Controller, cela crait pourtant un nombre
de problmes. La Pagination tait difficile tendre, remplacer et modifier. Dans 2.0, la pagination a t
extraite dans un component. Controller::paginate() existe toujours, et sert en tant que mthode
commode pour le chargement et en utilisant le PaginatorComponent.
1082
Pour plus dinformations sur les nouvelles fonctionnalits offertes par la pagination dans 2.0, voir la documentation Pagination.
Vue
La Vue nest plus enregistre dans ClassRegistry
La vue enregistre dans ClassRegistry entranait des abus et crait effectivement un symbole global. Dans
2.0 chaque Helper reoit linstance Vue courante dans son constructeur. Cela autorise laccs aux vues pour
les helpers de la mme faon que dans le pass, sans crer de symboles globaux. Vous pouvez accder
linstance de vue dans $this->_View dans nimporte quel helper.
Proprits dprcies
Les proprits deprcies de Vue seront accessibles travers une mthode __get(). Cette mthode va tre
retire dans les versions futures, ainsi il est recommand que vous mettiez jour votre application.
Mthodes retires
1083
View->Helpers
Pour utiliser les thmes dans vos Controllers, vous navez plus mettre var $view = Theme;.
Utilisez public $viewClass = Theme; la place.
Changements de positionnement des callbacks
Les callbacks de Helper rcuprent maintenant toujours un argument pass lintrieur. Pour BeforeRender
et afterRender, cest le fichier vue qui est rendu. Pour beforeLayout et afterLayout, cest le fichier layout qui
est rendu. Vos signatures de fonction des helpers doivent ressembler cela :
public function beforeRender($viewFile) {
}
public function afterRender($viewFile) {
}
public function beforeLayout($layoutFile) {
}
public function afterLayout($layoutFile) {
}
Llment attrap, et les callbacks de vue ont t changs dans 2.0 pour vous aider vous fournir plus de
flexibilit et de cohrence. Lire plus sur les changements.
1084
CacheHelper decoupl
Dans les versions precdentes, il y avait un couplage troit entre CacheHelper et View. Dans 2.0 ce
couplage a t retir et CacheHelper utilise juste les callbacks comme les autres helpers pour gnrer la
page complte mise en cache.
CacheHelper <cake:nocache> tags changs
Dans les versions prcdentes, CacheHelper utilise un tag spcial <cake:nocache> comme marqueur
pour la sortie qui ne devrait pas faire partie de la page entirement mise en cache. Ces tags ne faisaient parti
daucun schma XML, et il ntait pas possible de valider dans les documents HTML et XML. Dans 2.0,
ces tags ont t remplacs avec des commentaires HTML/XML :
<cake:nocache> devient <!--nocache-->
</cake:nocache> devient <!--/nocache-->
Le code interne pour la page vue complte mise en cache a aussi t chang, alors assurez vous de nettoyer
le cache de la vue quand vous mettez jour.
Changements de MediaView
PHPUnit ne fait pas la diffrence entre les cas de tests groups et les cas de tests uniques. A cause de cela, les
options des tests groups, et le support pour les tests groups lancienne ont t retirs. Il est recommand
que les TestGroups soient ports vers les sous-classes de PHPUnit_Framework_Testsuite. Vous
pouvez trouver plusieurs exemples de ceci dans la suite de test de CakePHP. Les mthodes lies aux tests
groups dans TestManager ont aussi t retires.
1085
Shell Testsuite
Le shell Testsuite a eu ses invocations simplifies et tendues. Vous navez plus besoin de faire la diffrenciation entre case et group. On suppose que tous les tests sont des cas. Dans le pass, vous
vous auriez fait cake testsuite app case models/post, vous pouvez maintenant faire cake
testsuite app Model/Post.
Le shell Testsuite a t reconstruit pour utiliser loutils cli de PHPUnit. Cela supporte maintenant toutes
les options de ligne de commande supportes par PHPUnit. cake testsuite help vous montrera une
liste de toutes les modifications possibles.
Models
Les relations des Models sont maintenant facilement charges. Vous pouvez tre dans une situation o
lassignation dune valeur une proprit non-existante dun model vous enverra les erreurs :
$Post->inexistentProperty[] = 'value';
enverra traver lerreur Notice : Indirect modification of overloaded property $inexistentProperty has no
effect(Notice : La modification indirecte dune proprit $propritInexistente na aucun effet). Assigner
une valeur initiale la proprit rsoud le problme :
$Post->nonexistentProperty = array();
$Post->nonexistentProperty[] = 'value';
CakePHP 2.0 introduit quelques changements dans les objets Database qui ne devraient pas affecter grandement la compatibilit rtro-active. Le plus grand changement est ladoption de PDO pour la gestion des
connexions aux bases de donnes. Si vous utilisez une installation vanilla de PHP 5, vous aurez dj les
extensions ncessaires installes, mais il se peut que vous dussiez activer les extensions individuelles pour
chaque driver que vous souhaitez utiliser.
Utiliser PDO travers toutes les BDD nous permet dhomogniser le code pour chacune et fournit un
comportement plus fiable et prvisible pour tous les drivers. Il nous a galement permis dcrire des tests
plus prcis et portables pour le code de la base de donnes lie.
1086
La premire chose qui va probablement manquer aux users, est les statistiques lignes affectes et total de
lignes, comme elles ne sont pas reportes cause dun design de PDO plus performant et paresseux, il y a
des faons de rgler ce problme, mais qui sont trs spcifiques chaque base de donnes. Ces statistiques
ne sont pas parties cependant, mais pourraient manquer ou mme tre inexactes pour certains drivers.
Une fonctionnalit sympa ajoute aprs ladoption de PDO est la possibilit dutiliser des requtes prpares
avec des placeholders de requtes utilisant le driver natif si il est disponible.
Liste des changements
DboMysqli a t retire, nous ferons seulement le support de DboMysql.
API pour DboSource : :execute a chang, elle prendra maintenant un tableau de valeurs requtes en
second paramtre :
public function execute($sql, $params = array(), $options = array())
devient :
public function execute($sql, $options = array(), $params = array())
le troisime paramtre est suppos recevoir les options pour se connecter, en ce moment, il ne comprend
que loption log.
DboSource : :value() perd son troisime paramtre, il ntait pas utilis de toute faon.
DboSource : :fetchAll() accepte maintenant un tableau en second paramtre, pour passer les valeurs devant
tre lies la requte, le troisime paramtre a t abandonne. Exemple :
1087
MySQL, toutes les valeurs retournes dun find auraient t numriques dans le pass, maintenant elles
sont strictement des valeurs bolennes.
Behaviors
BehaviorCollection
devient :
public $actsAs = array(
'Acl' => array('type' => 'Controlled'),
'Tree' => array('type' => 'nested')
);
Plugins
Les plugins najoutent plus de faon magique leur prefix plugin aux components, helpers et models utiliss
travers eux. Vous devez tre explicites avec les components, models et helpers que vous souhaitez utiliser.
Dans le pass :
var $components = array('Session', 'Comments');
Aurait regard dans le plugin du controller avant de vrifier les components app/core. Il va maintenant
seulement regarder dans les components app/core. Si vous souhaitez utiliser les objets partir dun plugin,
vous devez mettre le nom du plugin :
public $components = array('Session', 'Comment.Commentaires');
Cela a t fait pour rduire la difficult des problmes de debug causs par les rats de la magie. Cela
amliore aussi la cohrence dans votre application, puisque les objets ont une faon autoritaire de les
rfrencer.
1088
Les plugins AppController et AppModel ne sont plus directement localiss dans le dossier plugin. Ils sont
maintenant placs dans les dossiers des plugins des Controllers et des Models comme ceci :
/app
/Plugin
/Comment
/Controller
CommentAppController.php
/Model
CommentAppModel.php
Console
La plupart de la console du framework a t reconstruite pour 2.0 pour traiter un grand nombre de questions
suivantes :
Etroitement coupl.
Il tait difficile de faire un texte daide pour les shells.
Les paramtres pour les shells taient fastidieux valider.
Les tches des Plugins ntaient pas joignables.
Objets avec trop de responsabilits.
Changements Rtro-incompatibles de lAPI du Shell
Shell na plus dinstance AppModel. Cette instance AppModel ntait pas correctement construite et
tait problmatique.
Shell::_loadDbConfig() a t retir. Il ntait pas assez gnrique pour rester dans le Shell. Vous
pouvez utiliser DbConfigTask si vous avez besoin de demander lutilisateur de crer une config db.
Shells nutilise plus $this->Dispatcher pour accder stdin, stdout, et stderr. Ils ont maintenant
les objets ConsoleOutput et ConsoleInput pour grer cela.
Shells chargent les tches facilement, et utilisent TaskCollection pour fournir une interface similaire
celle utilise pour les Helpers, Components, et Behaviors pour le chargement la vole des tches.
Shell::$shell a t retir.
Shell::_checkArgs() a t retir. Configurer un ConsoleOptionParser
Shells nont plus daccs direct ShellDispatcher. Vous devez utiliser les objets ConsoleInput
et ConsoleOutput la place. Si vous avez besoin de dispatcher dautres shells, regardez la section sur
invoquer dautres shells partir de votre shell.
Changements Rtro-incompatibles de lAPI du ShellDispatcher
1089
Bakes ControllerTask ne prend plus public et admin comme arguments passs. Ce sont maintenant
des options, indiques par --admin et --public.
Il est recommand que vous utilisiez le help sur les shells que vous utilisiez pour voir si tous les paramtres
ont chang. il est aussi recommand que vous lisiez les nouvelles fonctionnalits de la console, pour plus
dinformations sur les nouvelles APIs qui sont disponibles.
Debugger
La fonction debug() va sortir par dfaut les chanes sans danger de HTML. Cest dsactiv si cest utilis
dans la console. Loption $showHtml pour debug() peut tre mis sur false pour dsactiver la sortie sans
danger de HTML du debug.
ConnectionManager
ConnectionManager::enumConnectionObjects() va maintenant retourner la configuration
courante pour chaque connexion cre, au lieu dun tableau avec un nom de fichier, dun nom de classe
et dun plugin, qui ntait pas rellement utiles.
Quand vous dfinirez les connexions la base de donnes, vous aurez besoin de faire quelques changements
dans la faon dont les configs ont t dfinies dans le pass. Basiquement dans classe de configuration de la
base de donnes, la cl driver nest plus accepte, seulement datasource, afin de la rendre plus cohrente.
Aussi, comme les sources de donnes ont t dplaces vers les packages, vous aurez besoin de passer le
package dans lequel ils sont localiss. Exemple :
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'root',
'password' => 'root',
'database' => 'cake',
);
Les modles ne requirent maintenant plus de connexion la base de donnes dans le processus de construction. La base de donnes ne sera accde pour la premire fois seulement quand une opration de recherche
est dlivre ou une information pour une des colonnes est requise.
View
View : :$output
View naura pas toujours le dernier rendu de contenu (view ou layout) accessible avec $this->output.
Dans les helpers, vous pouvez utiliser $this->_View->output. Modifier cette proprit changera le
contenu qui sort de la vue rendue.
Helpers
HtmlHelper
FormHelper
FormHelper supporte maintenant tout type dentre HTML5 et tout type dentre personnalis. Utilisez
simplement le type dentre que vous souhaitez en mthode sur le helper. Par exemple range() crera
une entre avec type = range.
postLink() et postButton() Cre un lien/bouton permettant daccder certaine pasge utilisant
la mthode HTTP POST. Avec ceci dans votre controller vous pouvez empcher certaines actions, comme
delete, dtre accdes par la mthode GET.
2.0 Guide de Migration
1091
select() avec multiple = checkbox, traite maintenant lattribut id en prfixe pour toutes les options
gnres.
Libs
CakeRequest
CakeRequest est une nouvelle classe introduite dans 2.0. Elle encapsule les mthodes dintrospection
de requtes utilises couramment et remplace le tableau params avec un objet plus utile. Lisez en plus sur
CakeRequest.
CakeResponse
CakeResponse est une nouvelle classe introduite dans 2.0. Elle encapsule les mthodes et proprits
utilises couramment dans la rponse HTTP que votre application gnre. Elle consolide plusieurs caractristiques dans CakePHP. Lisez en plus sur CakeResponse.
CakeSession, SessionComponent
Routes peuvent retourner des URLs compltes Les Objets Route peuvent maintenant retourner des
URLs compltes, et Router ne les modifiera plus au-del de lajout de la chane de requte et des lments
de fragments. Par exemple, ceci pouvait tre utilis pour crer des routes pour la gestion de sous-domaines,
ou pour lactivation de flags https/http. Un exemple de classe de route qui supporte les sous-domaines serait :
class SubdomainRoute extends CakeRoute {
public function match ($params) {
$subdomain = isset($params['subdomain']) ? $params['subdomain'] : null;
unset($params['subdomain']);
$path = parent::match($params);
if ($subdomain) {
$path = 'http://' . $subdomain . '.localhost' . $path;
}
return $path;
}
}
Quand vous crez des liens, vous pouvez faire ce qui suit pour faire pointer les liens vers dautres sousdomaines.
1092
echo $this->Html->link(
'Autre domaine',
array('subdomain' => 'test', 'controller' => 'posts', 'action' => 'add')
);
Xml a connu un certain nombre de changements. Lisez en plus sur la classe Xml.
Nouvelles caractristiques de Lib
Configure readers
Configure peut maintenant tre configur pour le chargement de fichiers partir dune varit de sources
et de formats. La section Configuration contient plus dinformations sur les changements faits configure.
Configure::read() sans autre argument vous permet de lire toutes les valeurs de configure, plutt que
uniquement la valeur du debug.
Error et gestion des exceptions
CakePHP 2.0 a reconstruit la gestion des Exceptions et des Gestion des Erreurs, pour tre plus flexible et
donner plus de puissance aux dveloppeurs.
String : :wrap()
String::wrap() a t ajout pour faciliter les formatages de largeur fixe des textes. Il est utilis dans
les Shells quand vous utilisez Shell::wrapText().
debug()
debug() ne sort plus de HTML dans la console. A la place, elle donne des sorties comme ce qui suit :
########## DEBUG ##########
Array
(
[0] => test
)
###########################
1093
Components
Components reoit un traitement identique aux helpers et aux behaviors, Component est maintenant la
classe de base pour les components. Lisez en plus sur les changements sur les components.
RequestHandler
RequestHandler a t fortement remanie du fait de lintroduction de CakeRequest. Ces changements permettent certaines nouvelles fonctionnalits dtre aussi introduites.
Parsing automatique dAcceptation des headers Si un client envoie un unique mime type Accept qui
correspond lune des extensions actives dans :php :classRouter, RequestHandler le traitera de la
mme faon quune extension. Cela tendra le support de CakePHP pour les terminaux de type REST. Pour
utiliser cette fonctionnalit, commencez par activer les extensions dans app/Config/routes.php
Router::parseExtensions('json', 'xml');
Une fois que vous avez cr les layouts et les vues pour vos extensions, vous pourrez visiter une url comme
posts/view/1 et envoyer Accept : application/json dans les headers pour recevoir la version JSON de
cette URL.
CookieComponent
CookieComponent supporte maintenant seulement les cookies HTTP. Vous pouvez les activer en utilisant
$this->Cookie->httpOnly = true;. Avoir seulement les cookies HTTP les rendra inaccessible
partir du navigateur.
Security Component CSRF separation
CakePHP a une protection CSRF depuis 1.2. Pour 2.0, le CSRF existant a un nouveau mode plus paranoaque, et est sa caractristique propre autonome. Dans le pass, les fonctionnalits CSRF taient couples
avec des gardes-fous de tampering de formulaires. Les dveloppeurs dsactivent souvent validatePost pour
faire des formulaires dynamiques, en dsactivant la protection CSRF en mme temps. Pour 2.0, la vrification CSRF a t spare du tampering des formulaires vous donnant plus de contrle.
Pour plus dinformations, regardez protection CSRF
Controller
Les Controllers ont maintenant accs aux objets request et response. Vous pouvez en lire plus sur ces objets
sur leurs pages spcifiques.
1094
Console
La console pour CakePHP 2.0 a t preque entirement reconstruite. De nombreuses nouvelles caractristiques ainsi que quelques changements incompatibles avec antrieurement. Lisez en plus sur les changements sur la console.
Pagination
Pagination fournit maintenant un maxLimit par dfaut 100 pour la pagination.
Cette limite peut maintenant tre dpasse avec la variable paginate dans le Controller.
$this->paginate = array('maxLimit' => 1000);
Cette valeur par dfaut est fournie pour empcher lutilisateur de manipuler les URL provoquant une pression excessive sur la base de donnes pour les requtes suivantes, o un utilisateur modifierait le paramtre
limit pour une nombre trs important.
Mettre un Alias
Vous pouvez maintenant mettre un alias les helpers, les components et les behaviors pour utiliser votre
classe plutt quune autre. Cela signifie que vous pouvez trs facilement faire un helper MyHtml et navez
pas besoin de remplacer chaque instance de $this->Html dans vos vues. Pour le faire, passez la cl
className tout au long de votre classe, comme vous feriez avec les modles.
public $helpers = array(
'Html' => array(
'className' => 'MyHtml'
)
);
De mme, vous pouvez mettre en alias les components pour lutilisation dans vos controllers.
public $components = array(
'Email' => array(
'className' => 'QueueEmailer'
)
);
Appeller le component Email appelle le component QueueEmailer la place. Finalement, vous pouvez aussi
mettre en alias les behaviors.
public $actsAs = array(
'Containable' => array(
'className' => 'SuperContainable'
)
);
1095
Du fait de la faon dont 2.0 utilise les collections et les partage dans toute lapplication, toute classe que
vous mettez en alias sera utilise dans toute votre application. Quelque soit le moment o votre application
essaie daccder lalias, elle aura accs votre classe. Par exemple, quand vous mettez en alias le helper
Html dans lexemple ci-dessus, tous les helpers qui utilisent le helper Html ou les lments qui chargent le
helper Html, utiliseront MyHtml la place.
ConnectionManager
Une nouvelle mthode ConnectionManager::drop() a t ajoute pour permettre de retirer les connexions lors de lxecution.
Ces mthodes ne sont plus supportes. Utilisez les mthodes static que PHPUnit fournit :
setupBeforeClass et tearDownAfterClass.
start(), end(), before() et after()
Ces mthodes faisaient parti de linitialisation des cas de test de SimpleTest. start() et end() ne sont
pas remplacs. Vous pouvez utiliser setUp() et tearDown() pour remplacer before() et after().
setUp() et tearDown()
Dans le pass, les mthodes setUp, tearDown, startTest et endTest taient supportes, et entrainaient une confusion puisquelles taient quasi identiques mais dans certains cas, vous deviez utiliser
lune ou lautre.
Dans le nouveau test suite de CakePHP, il est recommand dutiliser uniquement setUp et tearDown.
Ces mthodes startTest et endTest sont toujours supportes mais sont dprcies.
8. http ://www.phpunit.de/manual/current/en/
9. http ://www.simpletest.org/
1096
getTests
La mthode getTests nest plus supporte. Vous pouvez utiliser les filtres la place. le runner web de test
prend maintenant un paramtre de query string supplmentaire qui vous permet de spcifier une expression
rgulire basique. Cette expression rgulire est utilise pour restreindre les mthodes qui sont lances :
e.g. filter=myMethod
Seuls les tests contenant la chane myMethod seront lancs au prochain rafraichissement. Le shell testsuite
de cake supporte aussi une option -filter pour filtrer les mthodes.
Mthodes dassertion
Plusieurs des mthodes dassertion ont des noms lgrement diffrents entre PHPUnit et SimpleTest. La o
le possible CakeTestCase fournit un wrapper pour les noms de mthode de SimpleTest. Ces wrappers de
compatibilit seront retirs dans 2.1.0. Les mthodes suivantes seront affectes.
assertEqual -> assertEquals
assertNotEqual -> assertNotEquals
assertPattern -> assertRegExp
assertIdentical -> assertSame
assertNotIdentical -> assertNotSame
assertNoPattern -> assertNotRegExp
assertNoErrors -> no replacement
expectError -> setExpectedException
expectException -> setExpectedException
assertReference -> assertSame
assertIsA -> assertType
Certaines mthodes prennent leurs arguments dans diffrents ordres, assurez-vous de vrifier les mthodes
que vous utilisez lors de la mise jour.
Mock expectations
Mock objects sont trs diffrents entre PHPUnit et SimpleTest. Il ny a pas de compatibilit de wrapper entre
eux. Mettre jour lutilisation de mock object peut tre un processus douloureux mais nous esprons que
les astuces suivantes vous aideront dans votre migration. Il est hautement recommand de vous familiariser
vous-mme avec la documentation de PHPUnit Mock object 10 .
Remplacez les appels de mthode Les expressions rgulires devraient vous aider mettre jour certaines de vos expectations mock object plus simplement.
Remplacez expectOnce() sans params
expectOnce\(([^\)]+)\);
expects(\$this->once())->method($1);
10. http ://www.phpunit.de/manual/current/en/test-doubles.html#test-doubles.mock-objects
1097
Remplacez expectAt()
expectAt\((\d+), (.+), array\((.+)\)\);
expects(\$this->at($1))->method($2)->with($3);
Remplacez expectNever
expectNever\(([^\)]+)\);
expects(\$this->never())->method($1);
Remplacez setReturnValue
setReturnValue\(([^,]+), (.+)\);
expects(\$this->once())->method($1)->will($this->returnValue($2));
Remplacez setReturnValueAt
setReturnValueAt((\d+), ([^,]+), (.+));
expects(\$this->at($1))->method($2)->will($this->returnValue($3));
Group tests
Group tests ont t retirs puisque PHPUnit traite les cas de test individuels et les suites test comme des
entits composables dans le runner. Vous pouvez placer les group tests lintrieur du rpertoire des cas
et utiliser PHPUnit_Framework_TestSuite en classe de base. Un exemple Testsuite ressemblerait
ceci :
class AllJavascriptHelpersTest extends PHPUnit_Framework_TestSuite {
/**
* Suite define the tests for this suite
*
* @return void
*/
public static function suite() {
$suite = new PHPUnit_Framework_TestSuite('JsHelper and all Engine Helpers');
$helperTestPath = CORE_TEST_CASES .
$suite->addTestFile($helperTestPath
$suite->addTestFile($helperTestPath
$suite->addTestFile($helperTestPath
$suite->addTestFile($helperTestPath
return $suite;
1098
}
}
TestManger na plus les mthodes pour ajouter les tests ni pour les group tests. Il est recommand que
vous utilisiez les mthodes offertes par PHPUnit.
App::build(array(
'plugins' => array('/chemin/complet/vers/plugins/', '/prochain/chemin/complet/vers/plug
'models' => array('/chemin/complet/vers/models/', '/prochain/chemin/complet/vers/model
'views' => array('/chemin/complet/vers/vues/', '/prochain/chemin/complet/vers/vues/'),
'controllers' => array('/chemin/complet/vers/controllers/', '/prochain/chemin/complet/v
1099
Ce qui a aussi chang est lordre dans lequel apparait le bootstrapping. Dans le pass,
app/config/core.php tait charg aprs app/config/bootstrap.php. Cela entranait que
nimporte quel App::import() dans le bootstrap dune application ntait plus en cache et ralentissait considrablement par rapport une inclusion en cache. Dans 1.3, le fichier core.php est charg et les
configurations du coeur mises en cache sont cres avant que bootstrap.php soit charg.
Chargement des inflections
inflections.php a t retir, ctait un fichier non ncessaire et les fonctionnalits lies ont
t reconstruites dans une mthode pour augmenter leur flexibilit. Vous pouvez maintenant utiliser
Inflector::rules() pour charger les diffrentes inflections.
Inflector::rules('singular', array(
'rules' => array('/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta'),
'uninflected' => array('singulars'),
'irregular' => array('spins' => 'spinor')
));
Fusionnera les rgles fournies dans un ensemble dinflections, avec les rgles ajoutes prenant le pas sur les
rgles de base.
Renommages de fichier et changements internes
Renommage des Librairies
Les librairies du coeur de libs/session.php, libs/socket.php, libs/model/schema.php et
libs/model/behavior.php ont t renommes afin quil y ait une meilleure correspondance entre les
noms de fichiers et les principales classes contenues (ainsi que la gestion avec les problmes despaces de
noms) :
session.php -> cake_session.php
App : :import(Core, Session) -> App : :import(Core, CakeSession)
socket.php -> cake_socket.php
App : :import(Core, Socket) -> App : :import(Core, CakeSocket)
schema.php -> cake_schema.php
App : :import(Model, Schema) -> App : :import(Model, CakeSchema)
behavior.php -> model_behavior.php
App : :import(Core, Behavior) -> App : :import(Core, ModelBehavior)
Dans la plupart des cas, le renommage ci-dessus, naffectera pas les codes existants.
Hritage de Object
1100
Le chemin ROOT/Users correspondrait au dernier noeud Users au lieu du premier. Dans 1.3, si vous vous
attenidez obtenir le dernier noeud, vous deviez utiliser le chemin ROOT/Users/Users
RequestHandlerComponent
getReferrer est dpreci, utilisez getReferer
SessionComponent & SessionHelper
del est dpreci, utilisez delete
SessionComponent::setFlash() Le second paramtre utilis habituellement pour configurer le
layout et par consquence le rendu du fichier layout. Cela a t modifi pour utiliser un lment. Si vous
spcifiez des flash de session dans vos applications vous aurez besoin de faire les changements suivants.
1. Dplacer les fichiers de layout requis dans app/views/elements
1101
Ces changements ont t faits pour rendre CakePHP plus explicites et dclaratifs dans quelles classes, vous
le dveloppeur dapplications, veut lutiliser. Dans le pass, il ny avait aucun moyen dviter le chargement
des classes de Session sans modifier les fichiers du coeur. Ce qui est quelque chose que nous souhaitions que
vous soyez capable dviter. De plus, les classes de Session taient le seul component ou helper magique.
Ce changement aide unifier et normaliser le behavior pour toutes les classes.
Classes de Librairie
CakeSession
del est dpreci, utilisez delete
SessionComponent
SessionComponent::setFlash() utilise maintenant un lment au lieu dun layout en second
paramtre. Assurez vous de dplacer tout flash layout de app/views/layouts vers app/views/elements et de
changer les instances de $content_for_layout en $message.
Folder
mkdir est dpreci, utilisez create
mv est dpreci, utilisez move
ls est dpreci, utilisez read
cp est dpreci, utilisez copy
rm est dpreci, utilisez delete
Set
isEqual est dpreci, utilisez == ou ===.
String
getInstance est dpreci, appelez les mthodes String statiquement.
Router
Routing.admin est dpreci. Il fournit un behavior incompatible avec les autres styles de prefix de routes
puisquil tait trait diffremment. A la place, vous devez utiliser Routing.prefixes. Les prfixes de
routes dans 1.3 ne ncessitent pas la dclaration manuelle de routes supplmentaires. Tous les prfixes de
routes seront gnrs automatiquement. Pour mettre jour, changez simplement votre core.php.
//Forme ancienne:
Configure::write('Routing.admin', 'admin');
// changer en:
Configure::write('Routing.prefixes', array('admin'));
1102
Voir le guide des nouvelles fonctionnalits pour plus dinformations sur lutilisation des prfixes de routes.
Un petit changement a aussi t fait pour router les paramtres. Les paramtres routs doivent maintenant
seulement tre des caractres alphanumriques, - et _ ou /[A-Z0-9-_+]+/.
Router::connect('/:$%@#param/:action/*', array(...)); // BAD
Router::connect('/:can/:anybody/:see/:m-3/*', array(...)); //Acceptable
Dans 1.3, les entrailles du Router taient hautement reconstruites pour amliorer la performance et rduire le
fouillis du code. Leffet secondaire de cela est que deux fonctions rarement utilises ont t supprimes, car
ils taient problmatique et entranait des bugs mme avec le code de base existant. Les premiers segments
de chemin utilisant les expressions rgulires ont t retirs. Vous ne pouvez plus crer des routes comme :
Ces routes compliquent la compilation des routes et rendent impossibles les routes inverses. Si vous avez
besoin de routes comme cela, il est recommand que vous utilisiez les paramtres de route avec des patrons
de capture. Le support de la next mid-route greedy star a t retire. Il a t prcedemment possible dutiliser
une greedy star dans le milieu de la route :
Router::connect(
'/pages/*/:event',
array('controller' => 'pages', 'action' => 'display'),
array('event' => '[a-z0-9_-]+')
);
This is no longer supported as mid-route greedy stars behaved erratically, and complicated route compiling.
Outside of these two edge-case features and the above changes the router behaves exactly as it did in 1.2.
Aussi, les personnes utilisant la cl id dans les URLs en forme de tableau remarqueront que Router : :url()
traite maintenant ceci en paramtre nomm. Si vous utilisiez prcedemment cette approche pour passer le
paramtre ID aux actions, vous aurez besoin de rcrire tous vos appels $html->link() et $this->redirect()
pour reflter ce changement :
// format ancien:
$url = array('controller' => 'posts', 'action' => 'view', 'id' => $id);
// utilisations des cases:
Router::url($url);
$html->link($url);
$this->redirect($url);
// 1.2 result:
/posts/view/123
// 1.3 result:
/posts/view/id:123
// correct format:
$url = array('controller' => 'posts', 'action' => 'view', $id);
Dispatcher
Dispatcher nest plus capable de dfinir un layout/viewPath de controller avec les paramtres de requte.
Le Contrle de ces proprits devrait tre gr par le Controller, pas le Dispatcher. Cette fonctionnalit
ntait aussi pas document, et pas test.
Debugger
Migration de la version 1.2 vers la 1.3
1103
Debugger::checkSessionKey()
a
t
renomm
au
profit
de
Debugger::checkSecurityKeys()
Calling
Debugger::output("text")
ne
fonctionne
plus.
Utilisez
Debugger::output("txt").
Object
Object::$_log a t retir. CakeLog::write est maintenant appel statiquement. Regardez Journalisation (logging) pour plus dinformations sur les changements faits pour se connecter.
Sanitize
Sanitize::html() retourne en gnral toujours des chanes de caractre echappes. Dans le pass,
utiliser le paramtre $remove would skip entity encoding, en retournant possiblement le contenu dangereux.
Sanitize::clean() a maintenant une option remove_html. Cela dclenchera la fonctionnalit
strip_tags de Sanitize::html(), et doit tre utilis en conjonction avec le paramtre encode.
Configure et App
Configure : :listObjects() remplac par App : :objects()
Configure : :corePaths() remplac par App : :core()
Configure : :buildPaths() remplac par App : :build()
Configure ne gre plus les chemins.
Configure : :write(modelPaths, array...) remplac par App : :build(array(models => array...))
Configure : :read(modelPaths) remplac par App : :path(models)
Il ny a plus de debug = 3. Le controller dumps generated by this setting often caused memory consumption issues making it an impractical and unusable setting. The $cakeDebug variable has also been
removed from View::renderLayout You should remove this variable reference to avoid errors.
Configure::load()
can
now
load
configuration
files
from
plugins.
Use
Configure::load(plugin.file); to load configuration files from plugins. Any configuration files in your application that use . in the name should be updated to use _
Cache
In addition to being able to load CacheEngines from app/libs or plugins, Cache underwent some refactoring
for CakePHP1.3. These refactorings focused around reducing the number and frequency of method calls.
The end result was a significant performance improvement with only a few minor API changes which are
detailed below.
The changes in Cache removed the singletons used for each Engine type, and instead an engine instance
is made for each unique key created with Cache::config(). Since engines are not singletons anymore, Cache::engine() was not needed and was removed. In addition Cache::isInitialized()
now checks cache configuration names, not cache engine names. You can still use Cache::set() or
Cache::engine() to modify cache configurations. Also checkout the Nouvelles caractristiques dans
CakePHP 1.3 for more information on the additional methods added to Cache.
It should be noted that using an app/libs or plugin cache engine for the default cache config can cause
performance issues as the import that loads these classes will always be uncached. It is recommended that
you either use one of the core cache engines for your default configuration, or manually include the
cache engine class before configuring it. Furthermore any non-core cache engine configurations should be
done in app/config/bootstrap.php for the same reasons detailed above.
1104
You can place this element anywhere in your layout or view. The sql_dump element will only generate
output when Configure::read(debug) is equal to 2. You can of course customize or override this
element in your app by creating app/views/elements/sql_dump.ctp.
View et Helpers
View
View::renderElement removed. Use View::element() instead.
Migration de la version 1.2 vers la 1.3
1105
Automagic support for .thtml view file extension has been removed either declare $this->ext =
thtml; in your controllers, or rename your views to use .ctp
View::set(title, $var) no longer sets $title_for_layout when rendering the layout. $title_for_layout is still populated by default. But if you want to customize it, use
$this->set(title_for_layout, $var).
View::$pageTitle has been removed. Use $this->set(title_for_layout, $var);
instead.
The $cakeDebug layout variable associated with debug = 3 has been removed. Remove it from your
layouts as it will cause errors. Also see the notes related to SQL log dumping and Configure for more
information.
All core helpers no longer use Helper::output(). The method was inconsistently used and caused
output issues with many of FormHelpers methods. If you previously overrode AppHelper::output()
to force helpers to auto-echo you will need to update your view files to manually echo helper output.
TextHelper
TextHelper::trim() is deprecated, used truncate() instead.
TextHelper::highlight() no longer has :
an $highlighter parameter. Use $options[format] instead.
an $considerHtmlparameter. Use $options[html] instead.
TextHelper::truncate() no longer has :
an $ending parameter. Use $options[ending] instead.
an $exact parameter. Use $options[exact] instead.
an $considerHtmlparameter. Use $options[html] instead.
PaginatorHelper
PaginatorHelper has had a number of enhancements applied to make styling easier. prev(), next(),
first() and last()
The disabled state of these methods now defaults to <span> tags instead of <div> tags.
passedArgs are now auto merged with URL options in paginator.
sort(), prev(), next() now add additional class names to the generated html. prev() adds a class
of prev. next() adds a class of next. sort() will add the direction currently being sorted, either asc or
desc.
FormHelper
FormHelper::dateTime()
no
longer
has
a
$showEmpty
parameter.
Use
$attributes[empty] instead.
FormHelper::year() no longer has a $showEmpty parameter. Use $attributes[empty]
instead.
FormHelper::month()
no
longer
has
a
$showEmpty
parameter.
Use
$attributes[empty] instead.
FormHelper::day() no longer has a $showEmpty parameter. Use $attributes[empty]
instead.
FormHelper::minute()
no
longer
has
a
$showEmpty
parameter.
Use
$attributes[empty] instead.
FormHelper::meridian()
no
longer
has
a
$showEmpty
parameter.
Use
$attributes[empty] instead.
FormHelper::select()
no
longer
has
a
$showEmpty
parameter.
Use
$attributes[empty] instead.
1106
Default URLs generated by form helper no longer contain id parameter. This makes default URLs more
consistent with documented userland routes. Also enables reverse routing to work in a more intuitive
fashion with default FormHelper URLs.
FormHelper::submit() Can now create other types of inputs other than type=submit. Use the type
option to control the type of input generated.
FormHelper::button() Now creates <button> elements instead of reset or clear inputs. If you
want to generate those types of inputs use FormHelper::submit() with a type => reset
option for example.
FormHelper::secure() and FormHelper::create() no longer create hidden fieldset elements. Instead they create hidden div elements. This improves validation with HTML4.
Also be sure to check the Mises jour 2.0 for additional changes and new features in the FormHelper.
HtmlHelper
HtmlHelper::meta() no longer has an $inline parameter. It has been merged with the
$options array.
HtmlHelper::link()
no
longer
has
an
$escapeTitle
parameter.
Use
$options[escape] instead.
HtmlHelper::para() no longer has an $escape parameter. Use $options[escape] instead.
HtmlHelper::div() no longer has an $escape parameter. Use $options[escape] instead.
HtmlHelper::tag() no longer has an $escape parameter. Use $options[escape] instead.
HtmlHelper::css() no longer has an $inline parameter. Use $options[inline] instead.
SessionHelper
flash() no longer auto echos. You must add an echo $session->flash(); to your session>flash() calls. flash() was the only helper method that auto outputted, and was changed to create consistency in helper methods.
CacheHelper
CacheHelpers interactions with Controller::$cacheAction has changed slightly. In the past if you
used an array for $cacheAction you were required to use the routed URL as the keys, this caused
caching to break whenever routes were changed. You also could set different cache durations for different passed argument values, but not different named parameters or query string parameters. Both of these
limitations/inconsistencies have been removed. You now use the controllers action names as the keys for
$cacheAction. This makes configuring $cacheAction easier as its no longer coupled to the routing,
and allows cacheAction to work with all custom routing. If you need to have custom cache durations for
specific argument sets you will need to detect and update cacheAction in your controller.
TimeHelper
TimeHelper has been refactored to make it more i18n friendly. Internally almost all calls to date() have
been replaced by strftime(). The new method TimeHelper : :i18nFormat() has been added and will take
localization data from a LC_TIME locale definition file in app/locale following the POSIX standard. These
are the changes made in the TimeHelper API :
TimeHelper : :format() can now take a time string as first parameter and a format string as the second one,
the format must be using the strftime() style. When called with this parameter order it will try to automatically convert the date format into the preferred one for the current locale. It will also take parameters
as in 1.2.x version to be backwards compatible, but in this case format string must be compatible with
date().
TimeHelper : :i18nFormat() has been added
1107
Deprecated Helpers
Both the JavascriptHelper and the AjaxHelper are deprecated, and the JsHelper + HtmlHelper should be
used in their place.
You should replace
$javascript->link() with $html->script()
$javascript->codeBlock() with $html->scriptBlock() or $html->scriptStart()
and $html->scriptEnd() depending on your usage.
Console and shells
Shell
Shell::getAdmin() has been moved up to ProjectTask::getAdmin()
Schema shell
cake schema run create has been renamed to cake schema create
cake schema run update has been renamed to cake schema update
Console Error Handling
The shell dispatcher has been modified to exit with a 1 status code if the method called on the shell explicitly
returns false. Returning anything else results in a 0 status code. Before the value returned from the method
was used directly as the status code for exiting the shell.
Shell methods which are returning 1 to indicate an error should be updated to return false instead.
Shell::error() has been modified to exit with status code 1 after printing the error message which
now uses a slightly different formatting.
$this->error('Invalid Foo', 'Please provide bar.');
// outputs:
Error: Invalid Foo
Please provide bar.
// exits with status code 1
ShellDispatcher::stderr() has been modified to not prepend Error : to the message anymore. Its
signature is now similar to Shell::stdout().
ShellDispatcher : :shiftArgs()
The method has been modified to return the shifted argument. Before if no arguments were available the
method was returning false, it now returns null. Before if arguments were available the method was returning
true, it now returns the shifted argument instead.
Vendors, Test Suite & schema
vendors/css, vendors/js, and vendors/img
Support for these three directories, both in app/vendors as well as plugin/vendors has been removed. They have been replaced with plugin and theme webroot directories.
Test Suite and Unit Tests
1108
Group tests should now extend TestSuite instead of the deprecated GroupTest class. If your Group tests do
not run, you will need to update the base class.
Vendor, plugin and theme assets
Vendor asset serving has been removed in 1.3 in favour of plugin and theme webroot directories.
Schema files used with the SchemaShell have been moved to app/config/schema instead of
app/config/sql Although config/sql will continue to work in 1.3, it will not in future versions, it
is recommend that the new path is used.
Paramtres du Component
Les paramtres du Component pour tous les components du coeur peuvent maintenant tre dfinis partir
du tableau $components. Un peu comme les behaviors, vous pouvez dclarer les paramtres pour les
components quand vous dclarer le component.
var $components = array(
'Cookie' => array(
'name' => 'MyCookie'
),
'Auth' => array(
'userModel' => 'MyUser',
'loginAction' => array('controller' => 'users', 'action' => 'login')
)
);
1109
EmailComponent::$messageId has been added, it allows control over the Message-ID header for
email messages.
View & Helpers
Les Helpers peuvent maintenant tre traits par $this->Helper->func() en plus de
$helper->func(). Cela permet aux variables de vue et aux helpers de partager les noms et de
ne pas crer de collisions.
Le nouveau JsHelper et les nouvelles fonctionnalits dans HtmlHelper
Regardez la documentation de JsHelper pour plus dinformations.
Pagination Helper
Le helper Pagination fournit des classes CSS supplmentaires pour le style et vous pouvez configurer
la direction de sort() par dfaut. PaginatorHelper::next() et PaginatorHelper::prev()
gnrent maintenant des tags span par dfaut, au lieu de divs.
Helper
Helper::assetTimestamp() a t ajoute. Elle ajoutera des timestamps tout asset sous
WWW_ROOT. Elle fonctionne avec Configure::read(Asset.timestamp); comme avant,
mais la fonctionnalit utilise dans les helpers Html et Javascript a t rendu disponible pour tous les
helpers. En supposant que Asset.timestamp == force
$path = 'css/cake.generic.css'
$stamped = $this->Html->assetTimestamp($path);
//$stamped contient 'css/cake.generic.css?5632934892'
Le timestamp ajout contient la dernire modification de temps du fichier. Depuis que cette mthode est
dfinie dans Helper, elle est disponible toutes les sous-classes.
TextHelper
highlight() accepte maintenant un tableau de mots surligner.
NumberHelper
Une nouvelle mthode addFormat() a t ajoute. Cette mthode vous permet de configurer des ensembles de paramtres de monnaie, pour que vous nayez pas les retaper.
$this->Number->addFormat('NOK', array('before' => 'Kr. '));
$formatted = $this->Number->currency(1000, 'NOK');
FormHelper
Le helper form a eu un certain nombre damliorations et de modifications de lAPI, regardez les amliorations du Hemper Form 11 pour plus dinformations.
11. http ://book.cakephp.org/1.3/en/The-Manual/Core-Helpers/Form.html#improvements
1110
Logging
La connexion et CakeLog ont t amliors considrablement, les deux dans les fonctionnalits et la flexibilit. Regardez New Logging features 12 pour plus dinformations.
Caching
Les moteurs de Cache ont t fabriqus plus flexibles dans 1.3. Vous pouvez maintenant fournir des adapters
de Cache personnaliss dans app/libs ainsi que dans les plugins en utilisant $plugin/libs. Les
moteurs de cache App/plugin peuvent aussi surcharger les moteurs du coeur. Les adapters de Cache doivent
tre dans un rpertoire de cache. Si vous aviez un moteur de cache nomm MyCustomCacheEngine,
cela serait plac soit dans app/libs/cache/my_custom_cache.php, soit dans app/libs. Ou dans
$plugin/libs/cache/my_custom_cache.php appartenant un plugin. Les configs de Cache
partir des plugins ont besoin dutiliser la syntaxe avec des points des plugins.
Cache::config('custom', array(
'engine' => 'CachePack.MyCustomCache',
...
));
Les moteurs de cahce de App et Plugin doivent tre configurs dans app/bootstrap.php. Si vous
essayez de les configurer dans core.php, ils ne fonctionneront pas correctement.
Nouvelles mthodes de Cache
Cache a quelques nouvelles mthodes pour 1.3 ce qui rend lintrospection et le test bien plus facile.
Cache::configured() retourne un tableau des cls de moteur de Cache configurs.
Cache::drop($config) retire un moteur de Cache configur. Une fois supprim, les moteurs de
cache ne sont plus lisible, et lcriture nest plus disponible.
Cache::increment() Perform an atomic increment on a numeric value. This is not implemented in
FileEngine.
Cache::decrement() Perform an atomic decrement on a numeric value. This is not implemented in
FileEngine.
Models, Behaviors and Datasource
App : :import(), datasources & datasources from plugins
Les sources de donnes peuvent maintenant tre inclues charges avec App::import() et tre
inclues dans les plugins ! Pour inclure un source de donnes dans votre plugin, vous pouvez la mettre dans my_plugin/models/datasources/your_datasource.php. Pour importer une Source de donnes partir dun plugin, utilisez App::import(Datasource,
MyPlugin.YourDatasource);
Utiliser les sources de donnes dans votre database.php
12. http ://book.cakephp.org/1.3/en/The-Manual/Common-Tasks-With-CakePHP/Logging.html/
1111
Vous pouvez utiliser les sources de donnes de plugin en configurant la cl de la source de donnes avec le
nom du plugin. Par exemple, si vous avez un plugin WebservicePack avec une source de donnes LastFm
(plugin/webservice_pack/models/datasources/last_fm.php), vous pouvez faire :
var $lastFm = array(
'datasource' => 'WebservicePack.LastFm'
...
Model
Missing Validation methods now trigger errors, making debugging why validation isnt working easier.
Models now support virtual fields.
Behaviors
Using behaviors that do not exist, now triggers a cakeError making missing behaviors easier to find and
fix.
CakeSchema
CakeSchema can now locate, read and write schema files to plugins. The SchemaShell also exposes this
functionality, see below for changes to SchemaShell. CakeSchema also supports tableParameters.
Table Parameters are non column specific table information such as collation, charset, comments, and table
engine type. Each Dbo implements the tableParameters they support.
tableParameters in MySQL
MySQL supports the greatest number of tableParameters ; You can use tableParameters to set a variety of
MySQL specific settings.
engine Control the storage engine used for your tables.
charset Control the character set used for tables.
encoding Control the encoding used for tables.
In addition to tableParameters MySQL dbos implement fieldParameters. fieldParameters allow you
to control MySQL specific settings per column.
charset Set the character set used for a column
encoding Set the encoding used for a column
See below for examples on how to use table and field parameters in your schema files.
tableParameters in Postgres
tableParameters in SQLite
1112
),
'tableParameters' => array(
'engine' => 'InnoDB',
'charset' => 'latin1',
'collate' => 'latin1_general_ci'
)
);
is an example of a table using tableParameters to set some database specific settings. If you use a
schema file that contains options and features your database does not implement, those options will be
ignored. For example if you imported the above schema to a PostgreSQL server, all of the tableParameters
would be ignore as PostgreSQL does not support any of the included options.
Console
Bake
Bake has had a number of significant changes made to it. Those changes are detailed in the bake updates
section 13
Subclassing
The ShellDispatcher has been modified to not require shells and tasks to have Shell as their immediate parent
anymore.
Output
Shell::nl() has been added. It returns a single or multiple linefeed sequences. Shell::out(),
err() and hr() now accept a $newlines parameter which is passed to nl() and allows for controlling
how newlines are appended to the output.
Shell::out() and Shell::err() have been modified, allowing a parameterless usage. This is especially useful if youre often using $this->out() for outputting just a single newline.
Acl Shell
All AclShell commands now take node parameters. node parameters can be either an alias path like
controllers/Posts/view or Model.foreign_key ie. User.1. You no longer need to know or use
the aco/aro id for commands.
The Acl shell dataSource switch has been removed. Use the Configure settings instead.
SchemaShell
The Schema shell can now read and write Schema files and SQL dumps to plugins. It expects and will create
schema files in $plugin/config/schema
13. http
://book.cakephp.org/1.3/en/The-Manual/Core-Console-Applications/Code-Generation-with-Bake.html#bakeimprovements-in-1-3
1113
$this->Html->link('Go', array('controller' => 'posts', 'action' => 'index', 'member' => tru
$this->Html->link('Go', array('controller' => 'posts', 'action' => 'index', 'admin' => true
Likewise, if you are in a prefixed URL and want to go to a non-prefixed URL, do the following :
$this->Html->link('Go', array('controller' => 'posts', 'action' => 'index', 'member' => fal
$this->Html->link('Go', array('controller' => 'posts', 'action' => 'index', 'admin' => fals
Route classes
For 1.3 the router has been internally rebuilt, and a new class CakeRoute has been created. This class
handles the parsing and reverse matching of an individual connected route. Also new in 1.3 is the ability to
create and use your own Route classes. You can implement any special routing features that may be needed
in application routing classes. Developer route classes must extend CakeRoute, if they do not an error will
be triggered. Commonly a custom route class will override the parse() and/or match() methods found
in CakeRoute to provide custom handling.
Dispatcher
Accessing filtered asset paths, while having no defined asset filter will create 404 status code responses.
Library classes
Inflector
You can now globally customize the default transliteration map used in Inflector : :slug using
Inflector : :rules. eg. Inflector::rules(transliteration, array(// => aa,
// => oe))
The Inflector now also internally caches all data passed to it for inflection (except slug method).
Set
Set has a new method Set::apply(), which allows you to apply callbacks 14 to the results of
Set::extract and do so in either a map or reduce fashion.
Set::apply('/Movie/rating', $data, 'array_sum');
1114
File
File now has a copy() method. It copies the file represented by the file instance, to a new location.
Configure
Configure::load()
can
now
load
configuration
files
from
plugins.
Use
Configure::load(plugin.file); to load configuration files from plugins. Any configuration files in your application that use . in the name should be updated to used _
App/libs
In addition to app/vendors a new app/libs directory has been added. This directory can also be part
of plugins, located at $plugin/libs. Libs directories are intended to contain 1st party libraries that do
not come from 3rd parties or external vendors. This allows you to separate your organizations internal
libraries from vendor libraries. App::import() has also been updated to import from libs directories.
App::import('Lib', 'ImageManipulation'); //imports app/libs/image_manipulation.php
The remainder of lib importing syntax is identical to vendor files. So if you know how to import vendor files
with unique names, you know how to import libs files with unique names.
Configuration
The default Security.level in 1.3 is medium instead of high
There is a new configuration value Security.cipherSeed this value should be customized to ensure
more secure encrypted cookies, and a warning will be generated in development mode when the value
matches its default value.
i18n
Now you can use locale definition files for the LC_TIME category to retrieve date and time preferences for
a specific language. Just use any POSIX compliant locale definition file and store it at app/locale/language/
(do not create a folder for the category LC_TIME, just put the file in there).
For example, if you have access to a machine running debian or ubuntu you can find a french locale file at :
/usr/share/i18n/locales/fr_FR. Copy the part corresponding to LC_TIME into app/locale/fr_fr/LC_TIME
file. You can then access the time preferences for French language this way :
Configure::write('Config.language','fr-fr'); // set the current language
$monthNames = __c('mon',LC_TIME,true); // returns an array with the month names in French
$dateFormat = __c('d_fmt',LC_TIME,true); // return the preferred dates format for France
You can read a complete guide of possible values in LC_TIME definition file in this page 15
Miscellaneous
Error Handling
Subclasses of ErrorHandler can more easily implement additional error methods. In the past you would
need to override __construct() and work around ErrorHandlers desire to convert all error methods
15. http ://sunsson.iptime.org/susv3/basedefs/xbd_chap07.html
1115
into error404 when debug = 0. In 1.3, error methods that are declared in subclasses are not converted to
error404. If you want your error methods converted into error404, then you will need to do it manually.
Scaffolding
With the addition of Routing.prefixes scaffolding has been updated to allow the scaffolding of any
one prefix.
Configure::write('Routing.prefixes', array('admin', 'member'));
class PostsController extends AppController {
var $scaffold = 'member';
}
This file could be placed anywhere in your application, but must be imported before attempting to use it. In
your model validation you could use your NlValidation class by doing the following.
public $validate = array(
'phone_no' => array('rule' => array('phone', null, 'nl')),
'postal_code' => array('rule' => array('postal', null, 'nl'))
);
When your model data is validated, Validation will see that it cannot handle the nl locale and will attempt to
delegate out to NlValidation::postal() and the return of that method will be used as the pass/fail for
the validation. This approach allows you to create classes that handle a subset or group of locales, something
that a large switch would not have. The usage of the individual validation methods has not changed, the
ability to pass off to another validator has been added.
IP Address Validation
La validation des adresses IP a t tendu pour autoriser une stricte validation dune Version dIP spcifique.
Cela utilisera aussi les mchanismes de validation natifs de PHP si ils sont disponibles.
1116
Validation::ip($someAddress);
// Valide les deux IPv4 et IPv6
Validation::ip($someAddress, 'IPv4'); // Valide les adresses IPv4 seulement
Validation::ip($someAddress, 'IPv6'); // Valide les adresses IPv6 seulement
Validation : :uuid()
Un pattern de validation uuid() a t ajout la classe Validation. Elle vrifiera quune chane donne
correspondra un UUID par pattern uniquement. Cela ne garantit pas lunicit du UUID donn.
Informations gnrales
Glossaire
tableau de routing Un tableau des attributs qui sont passs au Router::url(). Typiquement, il
ressemble cela :
array('controller' => 'posts', 'action' => 'view', 5)
attributs HTML Un tableau de cl => valeurs qui sont composes dans les attributs HTML. Par exemple :
// Par exemple
array('class' => 'ma-classe', '_target' => 'blank')
// gnrerait
class="ma-classe" _target="blank"
Si une option peut tre minimise ou a le mme nom que sa valeur, alors true peut tre utilise :
// Par exemple
array('checked' => true)
// Gnrerait
checked="checked"
syntaxe de plugin La syntaxe de Plugin fait rfrence au nom de la classe avec un point en sparation
indiquant que les classes sont une partie dun plugin. Par ex : DebugKit.Toolbar, le plugin est
DebugKit, et le nom de classe est Toolbar.
notation avec points La notation avec points dfinit un chemin de tableau, en sparant les niveaux imbriqus avec . Par exemple :
Asset.filtre.css
Informations gnrales
1117
CSRF Les Requtes de site croises de Contrefaon. Empche les attaques de replay, les soumissions
doubles et les requtes contrefates provenant dautres domaines.
routes.php Un fichier dans APP/Config qui contient la configuration de routing. Ce fichier est inclus avant
que chaque requte soit traite. Il devrait connecter toutes les routes dont votre application a besoin
afin que les requtes puissent tre routes aux contrleurs + actions correctes.
DRY Ne vous rptez pas vous-mme. Est un principe de dveloppement de logiciel qui a pour objectif de
rduire les rptitions dinformation de tout type. Dans CakePHP, DRY est utilis pout vous permettre
de coder des choses et de les r-utiliser travers votre application.
1118
CHAPITRE 18
Indices et tables
genindex
1119
1120
Index
Symbols
:action, 864
:controller, 864
:plugin, 864
$this->request, 64
$this->response, 70
__() (global function), 345
__c() (global function), 346
__construct() (mthode Component), 85, 404
__d() (global function), 346
__dc() (global function), 346
__dcn() (global function), 346
__dn() (global function), 347
__n() (global function), 347
A
acceptLanguage() (mthode CakeRequest), 70
accepts() (mthode CakeRequest), 69
accepts() (mthode RequestHandlerComponent),
567
AclBehavior (class), 291, 367, 504
AclComponent (class), 574
action (RssHelper property), 185, 483, 667
add() (mthode Cache), 690
add() (mthode CacheEngine), 686
addArgument() (mthode ConsoleOptionParser),
818
addArguments() (mthode ConsoleOptionParser),
818
addCrumb() (mthode HtmlHelper), 152, 451, 634
addDetector() (mthode CakeRequest), 69
addFormat() (mthode CakeNumber), 743
addFormat() (mthode NumberHelper), 167, 466,
650
addInputType() (mthode RequestHandlerComponent), 568
addOption() (mthode ConsoleOptionParser), 819
addOptions() (mthode ConsoleOptionParser), 819
addPathElement() (mthode Folder), 699
addScript() (mthode View), 98
addSubcommand() (mthode ConsoleOptionParser),
820
admin routing, 869
afterDelete() (mthode ModelBehavior), 326, 400
afterFilter() (mthode Controller), 54
afterFind() (mthode ModelBehavior), 325, 399
afterLayout() (mthode Helper), 204, 502
afterRender() (mthode Helper), 204, 502
afterRenderFile() (mthode Helper), 204, 501
afterSave() (mthode ModelBehavior), 325, 400
afterScaffoldSave() (mthode Controller), 58
afterScaffoldSaveError() (mthode Controller), 58
afterValidate() (mthode ModelBehavior), 325, 400
ajaxLogin (AuthComponent property), 558
alert() (mthode CakeLog), 741
alert() (mthode JsHelper), 162, 460, 644
allow() (mthode AuthComponent), 559
allowedActions (SecurityComponent property), 562
allowedControllers (SecurityComponent property),
562
allowMethod() (mthode CakeRequest), 68
alphaNumeric() (mthode Validation), 275
am() (global function), 347
App (class), 350
APP (global constant), 348
APP_DIR (global constant), 348
1121
Index
Index
D
data (CakeRequest property), 70
data (RssHelper property), 185, 483, 667
data() (mthode CakeRequest), 69
database.php, 849
database.php.default, 849
date() (mthode Validation), 277
dateTime() (mthode FormHelper), 132, 431, 615
datetime() (mthode Validation), 278
DAY (global constant), 349
day() (mthode FormHelper), 133, 432, 616
dayAsSql() (mthode CakeTime), 786
dayAsSql() (mthode TimeHelper), 193, 491, 676
daysAsSql() (mthode CakeTime), 786
daysAsSql() (mthode TimeHelper), 194, 492, 676
debug() (global function), 347
debug() (mthode CakeLog), 741
Debugger (class), 898
decimal() (mthode Validation), 279
decrement() (mthode Cache), 689
1123
1124
E
each() (mthode JsHelper), 161, 460, 644
effect() (mthode JsHelper), 160, 459, 643
elem() (mthode RssHelper), 185, 483, 668
element() (mthode View), 98
elementCache (View property), 99
email() (mthode Validation), 279
emailPattern() (mthode CakeEmail), 697
emergency() (mthode CakeLog), 741
enable() (mthode CakeLog), 741
enabled() (mthode CakeLog), 740
encrypt() (mthode Security), 749
end() (mthode FormHelper), 112, 411, 594
end() (mthode View), 98
enum() (mthode Set), 763
env() (global function), 347
epilog() (mthode ConsoleOptionParser), 817
equalTo() (mthode Validation), 279
err() (mthode Shell), 824
error() (mthode CakeLog), 741
error() (mthode FormHelper), 134, 433, 616
error() (mthode SessionHelper), 186, 484, 669
error() (mthode Shell), 825
errors() (mthode Folder), 701
etag() (mthode CakeResponse), 77
event() (mthode JsHelper), 161, 459, 643
ExceptionRenderer (class), 890
excerpt() (mthode CakeText), 784
excerpt() (mthode Debugger), 899
excerpt() (mthode TextHelper), 191, 489, 674
executable() (mthode File), 705
exists() (mthode File), 705
expand() (mthode Hash), 715
expires() (mthode CakeResponse), 77
exportVar() (mthode Debugger), 899
ext() (mthode File), 705
extend() (mthode View), 99
extension() (mthode Validation), 279
extract() (mthode Hash), 708
extract() (mthode Set), 763
F
fetch() (mthode View), 99
field (RssHelper property), 185, 483, 667
File (class), 704
file extensions, 870
file() (mthode CakeResponse), 78
file() (mthode FormHelper), 129, 428, 612
Index
Index
1125
I
i18nFormat() (mthode CakeTime), 788
i18nFormat() (mthode TimeHelper), 196, 493, 678
identify() (mthode AuthComponent), 559
image() (mthode HtmlHelper), 140, 439, 622
IMAGES (global constant), 349
IMAGES_URL (global constant), 349
import() (mthode App), 354
in() (mthode Shell), 825
inCakePath() (mthode Folder), 702
increment() (mthode Cache), 689
increment() (mthode CacheEngine), 685
Inflector (class), 729
info (File property), 704
info() (mthode CakeLog), 741
info() (mthode File), 705
IniReader (class), 861
init() (mthode App), 356
initialize() (mthode AuthComponent), 559
initialize() (mthode Component), 85, 404
initialize() (mthode Shell), 825
inList() (mthode Validation), 280
inPath() (mthode Folder), 702
input() (mthode CakeRequest), 69
input() (mthode FormHelper), 113, 412, 595
inputs() (mthode FormHelper), 114, 414, 597
insert() (mthode CakeText), 781
insert() (mthode Hash), 708
insert() (mthode Set), 766
InternalErrorException, 888
invoke() (mthode Debugger), 899
ip() (mthode Validation), 280
is() (mthode CakeRequest), 69
isAbsolute() (mthode Folder), 702
isAtom() (mthode RequestHandlerComponent),
567
isAuthorized() (mthode AuthComponent), 559
isFieldError() (mthode FormHelper), 134, 433, 616
isFuture() (mthode CakeTime), 792
isFuture() (mthode TimeHelper), 199, 497, 682
isMobile() (mthode RequestHandlerComponent),
567
isPast() (mthode CakeTime), 792
isPast() (mthode TimeHelper), 199, 497, 682
isRss() (mthode RequestHandlerComponent), 567
isSlashTerm() (mthode Folder), 702
isThisMonth() (mthode CakeTime), 792
1126
J
JS (global constant), 349
JS_URL (global constant), 349
JsHelper (class), 152, 451, 635
JsonView (class), 104
L
label() (mthode FormHelper), 123, 423, 606
last() (mthode PaginatorHelper), 176, 474, 658
lastAccess() (mthode File), 705
lastChange() (mthode File), 705
layout (View property), 99
levels() (mthode CakeLog), 740
link() (mthode HtmlHelper), 141, 440, 623
link() (mthode JsHelper), 163, 461, 645
link() (mthode PaginatorHelper), 180, 478, 662
listTimezones() (mthode CakeTime), 791
listTimezones() (mthode TimeHelper), 199, 496,
681
load() (mthode App), 356
load() (mthode Configure), 858
loadConfig() (mthode HtmlHelper), 151, 450, 634
loadModel() (mthode Controller), 62
loadTasks() (mthode Shell), 825
location() (mthode App), 352
location() (mthode CakeResponse), 76
lock (File property), 704
log() (mthode Debugger), 898
LOG_ERROR (global constant), 855
LogError() (global function), 347
loggedIn() (mthode AuthComponent), 559
login() (mthode AuthComponent), 559
loginAction (AuthComponent property), 558
Index
M
map() (mthode Hash), 717
map() (mthode Set), 768
mapActions() (mthode AuthComponent), 560
mapResources() (mthode Router), 880
match() (mthode CakeRoute), 880
matches() (mthode Set), 769
maxDimensions() (mthode Hash), 717
maxLength() (mthode Validation), 281
md5() (mthode File), 705
media() (mthode HtmlHelper), 143, 442, 625
MediaView (class), 101
merge() (mthode Hash), 715
merge() (mthode Set), 770
mergeDiff() (mthode Hash), 719
meridian() (mthode FormHelper), 134, 433, 616
messages() (mthode Folder), 702
meta() (mthode HtmlHelper), 137, 437, 620
meta() (mthode PaginatorHelper), 181, 479, 663
method() (mthode CakeRequest), 68
MethodNotAllowedException, 888
mime() (mthode File), 707
mimeType() (mthode Validation), 281
minLength() (mthode Validation), 281
MINUTE (global constant), 349
minute() (mthode FormHelper), 133, 433, 616
MissingActionException, 889
MissingBehaviorException, 889
MissingComponentException, 889
MissingConnectionException, 889
MissingControllerException, 889
MissingDatabaseException, 889
MissingHelperException, 889
MissingLayoutException, 889
MissingShellException, 889
MissingShellMethodException, 889
MissingTableException, 889
MissingTaskException, 889
MissingViewException, 889
mode (Folder property), 699
model (RssHelper property), 185, 483, 667
ModelBehavior (class), 325, 399
Index
N
name (Controller property), 62
name (File property), 704
name() (mthode File), 705
named parameters, 872
naturalNumber() (mthode Validation), 283
nest() (mthode Hash), 721
nest() (mthode Set), 779
nestedList() (mthode HtmlHelper), 147, 446, 629
next() (mthode PaginatorHelper), 175, 474, 658
nice() (mthode CakeTime), 788
nice() (mthode TimeHelper), 196, 493, 678
niceShort() (mthode CakeTime), 789
niceShort() (mthode TimeHelper), 196, 494, 679
nl() (mthode Shell), 825
normalize() (mthode Hash), 720
normalize() (mthode Set), 771
normalizePath() (mthode Folder), 702
notation avec points, 1117
notBlank() (mthode Validation), 282
notEmpty() (mthode Validation), 282
NotFoundException, 888
notice() (mthode CakeLog), 741
NotImplementedException, 888
NumberHelper (class), 165, 464, 648
numbers() (mthode PaginatorHelper), 173, 472, 656
numeric() (mthode Hash), 716
numeric() (mthode Set), 773
numeric() (mthode Validation), 283
O
object() (mthode JsHelper), 156, 455, 639
objects() (mthode App), 353
offset() (mthode File), 705
onlyAllow() (mthode CakeRequest), 68
open() (mthode File), 706
options() (mthode PaginatorHelper), 177, 475, 660
out() (mthode Shell), 826
1127
P
paginate() (mthode Controller), 60
PaginatorComponent (class), 533
PaginatorHelper (class), 172, 470, 654
para() (mthode HtmlHelper), 145, 444, 627
param() (mthode CakeRequest), 70
param() (mthode PaginatorHelper), 181, 479, 663
param() (mthode Shell), 824
params (CakeRequest property), 70
params (RssHelper property), 185, 483, 667
params() (mthode PaginatorHelper), 180, 478, 663
parse() (mthode CakeRoute), 880
parseExtensions() (mthode Router), 880
passed arguments, 871
password() (mthode AuthComponent), 560
password() (mthode FormHelper), 124, 424, 607
patch() (mthode HttpSocket), 723
path (File property), 704
path (Folder property), 699
path() (mthode App), 351
paths() (mthode App), 351
perms() (mthode File), 706
phone() (mthode Validation), 283
php :attr (directive), 1003
php :attr (role), 1004
php :class (directive), 1002
php :class (role), 1004
php :const (directive), 1002
php :const (role), 1004
php :exc (role), 1004
php :exception (directive), 1002
php :func (role), 1003
php :function (directive), 1002
php :global (directive), 1002
php :global (role), 1004
php :meth (role), 1004
php :method (directive), 1003
php :staticmethod (directive), 1003
PhpReader (class), 861
plugin routing, 870
pluginPath() (mthode App), 353
pluginSplit() (global function), 347
pluralize() (mthode Inflector), 729
post() (mthode HttpSocket), 723
1128
Q
query (CakeRequest property), 70
query() (mthode CakeRequest), 69
R
radio() (mthode FormHelper), 126, 425, 609
range() (mthode Validation), 284
read() (mthode Cache), 688
read() (mthode CacheEngine), 685
read() (mthode CakeSession), 887
read() (mthode ConfigReaderInterface), 860
read() (mthode Configure), 856
read() (mthode CookieComponent), 573
read() (mthode File), 706
read() (mthode Folder), 703
read() (mthode SessionComponent), 542
read() (mthode SessionHelper), 186, 484, 669
readable() (mthode File), 706
realpath() (mthode Folder), 703
recover() (mthode TreeBehavior), 318, 393, 531
redirect() (mthode AuthComponent), 560
redirect() (mthode Controller), 56
redirect() (mthode JsHelper), 163, 462, 646
redirect() (mthode Router), 879
redirectUrl() (mthode AuthComponent), 560
reduce() (mthode Hash), 718
ref (role), 1001
referer() (mthode CakeRequest), 69
Index
S
safe() (mthode File), 706
Index
1130
Index
W
warning() (mthode CakeLog), 741
wasWithinLast() (mthode CakeTime), 792
wasWithinLast() (mthode TimeHelper), 199, 497,
682
wasYesterday() (mthode CakeTime), 792
wasYesterday() (mthode TimeHelper), 199, 497,
682
webroot (CakeRequest property), 70
webroot() (mthode Helper), 203, 501
WEBROOT_DIR (global constant), 349
WEEK (global constant), 350
wrap() (mthode CakeText), 782
wrapText() (mthode Shell), 827
writable() (mthode File), 706
write() (mthode Cache), 689
write() (mthode CacheEngine), 685
write() (mthode CakeLog), 739
write() (mthode CakeSession), 887
write() (mthode Configure), 855
write() (mthode CookieComponent), 573
write() (mthode File), 706
write() (mthode SessionComponent), 542
writeBuffer() (mthode JsHelper), 155, 454, 638
WWW_ROOT (global constant), 349
X
Xml (class), 792
XmlView (class), 104
Index
1131