Vous êtes sur la page 1sur 1137

CakePHP Cookbook Documentation

Version 2.x

Cake Software Foundation

01 April 2016

Table des matires

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

Dbuter avec CakePHP


45
Quest ce que CakePHP ? Pourquoi lUtiliser ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Comprendre le systme M-V-C (Model-View-Controller) . . . . . . . . . . . . . . . . . . . . . . 46
O obtenir de laide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

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

Shells, Tasks & Outils de Console


La console de CakePHP . . . . . . . . . . . .
Crer un Shell . . . . . . . . . . . . . . . . .
Les tches Shell . . . . . . . . . . . . . . . .
Invoquer dautres shells partir de votre shell
Niveaux de sortie de la Console . . . . . . . .
Style de sortie . . . . . . . . . . . . . . . . .
Configurer les options et gnrer de laide . .
Routing dans shells / CLI . . . . . . . . . . .
API de Shell . . . . . . . . . . . . . . . . . .
Plus de sujets . . . . . . . . . . . . . . . . .

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

Dfinir le document root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935


Mise jour de core.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
Amliorer les performances de votre application . . . . . . . . . . . . . . . . . . . . . . . . . . . 936
12 Authentification Simple et Autorisation de lApplication
Crer le code li de tous les users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Authentification (Connexion et Deconnexion) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Autorisation (Qui est autoris accder quoi) . . . . . . . . . . . . . . . . . . . . . . . . . . .

937
937
940
942

13 Application Simple contrle par Acl


Prparer notre Application . . . . . . . .
Prparer lajout dAuth . . . . . . . . . .
Initialiser les tables Acl dans la BdD . . .
Agir comme un requteur . . . . . . . . .
Crer les ACOs (Access Control Objects)

.
.
.
.
.

945
945
947
949
949
951

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

14 Application Simple contrle par Acl - partie 2


Un outil automatique pour la cration des ACOs .
Configurer les permissions . . . . . . . . . . . .
Connexion . . . . . . . . . . . . . . . . . . . . .
Dconnexion . . . . . . . . . . . . . . . . . . .
Cest fini ! . . . . . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

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

Informations gnrales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1117


18 Indices et tables

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.

Tutoriel dun Blog


Bienvenue sur CakePHP. Vous consultez probablement ce tutoriel parce que vous voulez en apprendre plus
propos du fonctionnement de CakePHP. Cest notre but damliorer la productivit et de rendre le dveloppement plus agrable : nous esprons que vous le dcouvrirez au fur et mesure que vous plongerez dans le
code.
Ce tutoriel vous accompagnera travers la cration dune simple application de blog. Nous rcuprerons et
installerons CakePHP, crerons et configurerons une base de donnes et ajouterons suffisamment de logique
applicative pour lister, ajouter, diter et supprimer des posts.
Voici ce dont vous aurez besoin :
1. Un serveur web fonctionnel. Nous supposerons que vous utilisez Apache, bien que les instructions
pour utiliser dautres serveurs doivent tre assez semblables. Nous aurons peut-tre besoin de jouer un
peu sur la configuration du serveur, mais la plupart des personnes peuvent faire fonctionner CakePHP
sans aucune configuration pralable.
2. Un serveur de base de donnes. Dans ce tutoriel, nous utiliserons MySQL. Vous aurez besoin dun
minimum de connaissance en SQL afin de crer une base de donnes : CakePHP prendra les rnes
partir de l.
1

CakePHP Cookbook Documentation, Version 2.x

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/

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

Crer la base de donnes du blog


Maintenant, mettons en place la base de donnes pour notre blog. Si vous ne lavez pas dj fait, crez une
base de donnes vide avec le nom de votre choix pour lutiliser dans ce tutoriel. Pour le moment, nous allons
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.

Configurer la base de donnes CakePHP


En avant : indiquons CakePHP o se trouve notre base de donnes et comment sy connecter. Pour la
plupart dentre vous, cest la premire et dernire fois que vous configurerez quelque chose.
Une copie du fichier de configuration CakePHP pour la base de donnes se trouve dans
/app/Config/database.php.default. Faites une copie de ce fichier dans le mme rpertoire mais
nommez le database.php.
Le fichier de configuration devrait tre assez simple : remplacez simplement les valeurs du tableau
$default par celles qui correspondent votre installation. Un exemple de tableau de configuration complet pourrait ressembler ce qui suit :
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',

Tutoriel dun Blog

CakePHP Cookbook Documentation, Version 2.x

'port' => '',


'login' => 'cakeBlog',
'password' => 'c4k3-rUl3Z',
'database' => 'cake_blog_tutorial',
'schema' => '',
'prefix' => '',
'encoding' => 'utf8'
);

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');

Une note sur mod_rewrite


Occasionnellement, les nouveaux utilisateurs peuvent avoir des problmes de mod_rewrite. Par exemple si
la page daccueil de CakePHP a lair bizarre (pas dimages ou de styles CSS), cela signifie probablement
que mod_rewrite ne fonctionne pas sur votre systme. Merci de vous rfrer la section suivante sur lURL
rewriting pour que votre serveur web fonctionne :

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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.

Tutoriel dun Blog

CakePHP Cookbook Documentation, Version 2.x

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/

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

De belles URLs sur nginx

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/;

Tutoriel dun Blog

CakePHP Cookbook Documentation, Version 2.x

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 ;).

Rewrites dURL sur IIS7 (serveurs Windows)

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

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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"
)

Rgles de rewrite URL pour Hiawatha

La rgle ncessaire UrlToolkit (pour le rewriting URL) pour utiliser CakePHP avec Hiawatha est :

Tutoriel dun Blog

CakePHP Cookbook Documentation, Version 2.x

UrlToolkit {
ToolkitID = cakephp
RequestURI exists Return
Match .* Rewrite /index.php
}

Je ne veux / ne peux utiliser lURL rewriting

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.

Blog Tutoriel - Ajouter la logique


Crer un model Post
La classe Model est le pain quotidien des applications CakePHP. En crant un model CakePHP qui interagira
avec notre base de donnes, nous aurons mis en place les fondations ncessaires pour faire plus tard nos
oprations de lecture, dinsertion, ddition et de suppression.
Les fichiers des classes Model de CakePHP se trouvent dans /app/Model, et le fichier que nous allons
crer maintenant sera enregistr dans /app/Model/Post.php. Le fichier complet devrait ressembler
ceci
class Post extends AppModel {
}

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.

Crer un controller Posts


Nous allons maintenant crer un controller pour nos posts. Le controller est lendroit o sexcutera toute la
logique mtier pour lintraction du processus de post. En un mot, cest lendroit o vous jouerez avec les

10

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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).

Crer les Vues des Posts


Maintenant que nous avons nos donnes en provenance du model, ainsi que la logique applicative et les flux
dfinis par notre controller, nous allons crer une vue pour laction index que nous avons cr ci-dessus.
Les vues de CakePHP sont juste des fragments de prsentation assaisonne, qui sintgrent au sein dun
layout applicatif. Pour la plupart des applications, elles sont un mlange de HTML et PHP, mais les vues
peuvent aussi tre constitues de XML, CSV ou mme de donnes binaires.
Un Layout est un code de prsentation, encapsul autour dune vue. Ils peuvent tre dfinis et interchangs,
mais pour le moment, utilisons juste celui par dfaut.

Blog Tutoriel - Ajouter la logique

11

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

<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) {

Blog Tutoriel - Ajouter la logique

13

CakePHP Cookbook Documentation, Version 2.x

throw new NotFoundException(__('Invalid post'));


}
$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this->set('post', $post);
}
}

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

<!-- Fichier : /app/View/Posts/view.ctp -->


<h1><?php echo h($post['Post']['title']); ?></h1>
<p><small>Cr le : <?php echo $post['Post']['created']; ?></small></p>
<p><?php echo h($post['Post']['body']); ?></p>

Vrifiez que cela fonctionne en testant les liens de la page /posts/index ou en affichant manuellement un
post via /posts/view/1.

Ajouter des Posts


Lire depuis la base de donnes et nous afficher les posts est un bon dbut, mais lanons-nous dans lajout de
nouveaux posts.
Premirement, commenons par crer une action add() dans le PostsController
class PostsController extends AppController {
public $helpers = array('Html', 'Form', 'Flash');
public $components = array('Flash');
public function index() {
$this->set('posts', $this->Post->find('all'));
}

14

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

public function view($id) {


if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this->set('post', $post);
}
public function add() {
if ($this->request->is('post')) {
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->Flash->success(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
$this->Flash->error(__('Unable to add your post.'));
}
}
}

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

Blog Tutoriel - Ajouter la logique

15

CakePHP Cookbook Documentation, Version 2.x

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.

Valider les donnes


Cake place la barre trs haute pour briser la monotonie de la validation des champs de formulaires. Tout le
monde dteste le dvelopement de formulaires interminables et leurs routines de validations. Cake rend tout
cela plus facile et plus rapide.
Pour tirer profit des fonctionnalits de validation, vous devez utiliser le helper Form (FormHelper) dans
vos vues. FormHelper est disponible par dfaut dans toutes les vues avec la variables $this->Form.
Voici le code de notre vue add (ajout)
<!-- Fichier : /app/View/Posts/add.ctp -->
<h1>Ajouter un post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->end('Sauvegarder le post');
?>

Nous utilisons le FormHelper pour gnrer la balise douverture dune formulaire HTML. Voici le code
HTML gnr par $this->Form->create()
.. code-block:: html

<form id=PostAddForm method=post action=/posts/add>


Si create() est appele sans aucun paramtre, CakePHP suppose que vous construisez un formulaire qui
envoie les donnes en POST laction add() (ou edit() quand id est dans les donnes du formulaire)
du controller actuel.
La mthode $this->Form->input() est utilise pour crer des lments de formulaire du mme nom.
Le premier paramtre dit CakePHP quels champs ils correspondent et le second paramtre vous permet
de spcifier un large ventail doptions - dans ce cas, le nombre de lignes du textarea. Il y a un peu dintrospection et dautomagie ici : input() affichera diffrents lments de formulaire selon le champ spcifi
du model.
7. http ://api.cakephp.org

16

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

Lappel de la mthode $this->Form->end() gnre un bouton de soumission et ajoute la balise de


fermeture du formulaire. Si une chane de caractres est passe comme premier paramtre de la mthode
end(), le helper Form affichera un bouton de soumission dont le nom correspond celle-ci. Encore une
fois, rfrez-vous au chapitre Helpers (Assistants) pour en savoir plus sur les helpers.
A prsent, revenons en arrire et modifions notre vue /app/View/Posts/index.ctp pour ajouter un
lien Ajouter un post. Ajoutez la ligne suivante avant <table>
<?php echo $this->Html->link(
'Ajouter un Post',
array('controller' => 'posts', 'action' => 'add')
); ?>

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.

Editer des Posts


Ldition de posts : nous y voil. Vous tes un pro de CakePHP maintenant, vous devriez donc avoir adopt
le principe. Crez dabord laction puis la vue. Voici quoi laction edit() du controller Posts (PostsController) devrait ressembler
public function edit($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findById($id);

Blog Tutoriel - Ajouter la logique

17

CakePHP Cookbook Documentation, Version 2.x

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

(lien d\'dition ajout) -->

<h1>Blog posts</h1>

18

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

<p><?php echo $this->Html->link("Ajouter un Post", array('action' => 'add')); ?></p>


<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Action</th>
<th>Created</th>
</tr>
<!-- Ici se trouve la boucle de notre tableau $posts, impression de l\'info du post -->
<?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->Html->link(
'Editer',
array('action' => 'edit', $post['Post']['id'])
); ?>
</td>
<td>
<?php echo $post['Post']['created']; ?>
</td>
</tr>
<?php endforeach; ?>
</table>

Supprimer des Posts


A prsent, mettons en place un moyen de supprimer les posts pour les utilisateurs. Dmarrons avec une
action delete() dans le controller Posts (PostsController)
public function delete($id) {
if ($this->request->is('get')) {
throw new MethodNotAllowedException();
}
if ($this->Post->delete($id)) {
$this->Flash->success(
__('Le post avec id : %s a t supprim.', h($id))
);
} else {
$this->Flash->error(
__('Le post avec l\'id: %s n\'a pas pu tre supprim.', h($id))
);

Blog Tutoriel - Ajouter la logique

19

CakePHP Cookbook Documentation, Version 2.x

}
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

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

<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.

Blog Tutoriel - Ajouter la logique

21

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

F IGURE 1.1 Diagramme reprsentant une requte CakePHP typique.

Blog Tutoriel - Ajouter la logique

23

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

class NewsController extends AppController {


public function latest() {
$this->_findNewArticles();
}
protected function _findNewArticles() {
// Logique pour trouver les derniers articles de nouvelles
}
}

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

CakePHP Cookbook Documentation, Version 2.x

La classe Helper (Assistant) LeMeilleurQuiSoitHelper devra se trouver dans un fichier nomm


LeMeilleurQuiSoitHelper.php.
Chaque fichier sera situ dans le rpertoire appropri dans votre dossier app.
Conventions pour les Models et les Sources de donnes

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

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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.

Blog Tutoriel - Ajouter la logique

27

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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 1. Pour Commencer

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

CakePHP Cookbook Documentation, Version 2.x

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 :

HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | h


setfacl -R -m u:${HTTPDUSER}:rwx app/tmp
setfacl -R -d -m u:${HTTPDUSER}:rwx app/tmp

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

CakePHP Cookbook Documentation, Version 2.x

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/.

Utiliser un CakePHP pour de multiples applications


Si vous dveloppez un certain nombre dapplications il peut sembler tre sens de partager le mme coeur
de CakePHP. Il y a peu de faon daccomplir cela. Souvent, le plus facile est dutiliser le include_path
de PHP. Pour commencer, copiez CakePHP dans un rpertoire. Pour cet exemple, nous utiliserons
/home/mark/projects :
git clone git://github.com/cakephp/cakephp.git /home/mark/projects/cakephp

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

CakePHP Cookbook Documentation, Version 2.x

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.

Installation avance et URL Rewriting


Installation avance
Installer CakePHP avec linstalleur PEAR
CakePHP publie un package PEAR que vous pouvez installer en utilisant linstallateur PEAR. Linstallation
avec linstallateur PEAR peut simplifier le partage des librairies de CakePHP dans plusieurs applications.
Pour installer CakePHP avec PEAR, vous devrez faire comme suit :

34

Chapitre 2. Installation

CakePHP Cookbook Documentation, Version 2.x

pear channel-discover pear.cakephp.org


pear install cakephp/CakePHP

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

Installation avance et URL Rewriting

35

CakePHP Cookbook Documentation, Version 2.x

Vous tes maintenant prt gnrer le reste du squelette de votre application :


$ Vendor/bin/cake bake project <path to project>

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

CakePHP Cookbook Documentation, Version 2.x

/app/webroot/test.php (si vous utilisez la fonctionnalit de Testing.)


Il y a trois constantes que vous devrez modifier : ROOT, APP_DIR, et CAKE_CORE_INCLUDE_PATH.
ROOT doit tre dfinie vers le chemin du rpertoire qui contient le dossier app.
APP_DIR doit tre dfinie comme le nom (de base) de votre dossier app.
CAKE_CORE_INCLUDE_PATH doit tre dfinie comme le chemin du dossier des librairies de CakePHP.
Testons cela avec un exemple pour que vous puissiez voir quoi peut ressembler une installation avance
en pratique. Imaginez que je souhaite configurer CakePHP pour travailler comme ce qui suit :
Les librairies du coeur de CakePHP seront places dans /usr/lib/cake.
Le rpertoire webroot de lapplication sera /var/www/monsite/.
Le rpertoire app de mon application sera /home/me/monapp.
Etant donn ce type de configuration, jaurai besoin de modifier mon fichier webroot/index.php (qui finira
dans /var/www/mysite/index.php, dans cet exemple) pour ressembler ce qui suit :
// /app/webroot/index.php (partiel, commentaires retirs)
if (!defined('ROOT')) {
define('ROOT', DS . 'home' . DS . 'me');
}
if (!defined('APP_DIR')) {
define ('APP_DIR', 'myapp');
}
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
define('CAKE_CORE_INCLUDE_PATH', DS . 'usr' . DS . 'lib');
}

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.

Installation avance et URL Rewriting

37

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

<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/

Installation avance et URL Rewriting

39

CakePHP Cookbook Documentation, Version 2.x

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

De belles URLs sur nginx


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;

40

Chapitre 2. Installation

CakePHP Cookbook Documentation, Version 2.x

}
}

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 ;).

Rewrites dURL sur IIS7 (serveurs Windows)


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 7 pour installer lURL Rewrite Module 2.0 8
ou tlchargez le directement (32-bit 9 / 64-bit 10 ).
2. Crez un nouveau fichier dans votre dossier CakePHP, appel web.config.
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">
7.
8.
9.
10.

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

Installation avance et URL Rewriting

41

CakePHP Cookbook Documentation, Version 2.x

<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"
)

Rgles de rewrite URL pour Hiawatha


La rgle ncessaire UrlToolkit (pour le rewriting URL) pour utiliser CakePHP avec Hiawatha est :
UrlToolkit {
ToolkitID = cakephp
RequestURI exists Return
Match .* Rewrite /index.php
}

Je ne veux / ne peux utiliser lURL rewriting


Si vous ne voulez ou ne pouvez pas utiliser lURL rewriting sur votre serveur web, rfrez-vous la section
core configuration.

42

Chapitre 2. Installation

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

44

Chapitre 2. Installation

CHAPITRE 3

Dbuter avec CakePHP

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.

Quest ce que CakePHP ? Pourquoi lUtiliser ?


CakePHP 1 est un framework 2 pour PHP 3 gratuit 4 , open-source 5 , de dveloppement rapide 6 . Cest une
structure fondamentale pour les programmeurs pour crer des applications web. Notre principal objectif est
de vous permettre de travailler dune manire structure et rapide sans perte de flexibilit.
CakePHP rompt la monotonie du dveloppement web. Il vous offre tous les outils ncessaires pour ne coder
que ce dont vous avez rellement besoin : la logique spcifique de votre application.
Au lieu de rinventer la roue chaque fois que vous dmarrez un nouveau projet, rcuprez une copie de
CakePHP et concentrez-vous sur la logique de votre application.
CakePHP dispose dune quipe de dveloppement 7 et dune communaut actives, qui donnent au projet une
forte valeur ajoute. En plus de vous viter de r-inventer la roue, lutilisation de CakePHP implique que le
coeur de votre application est bien test et quil peut tre constamment amlior.
Voici un aperu rapide des caractristiques que vous apprcierez en utilisant CakePHP :
Communaut active et sympathique :ref :cakephp-official-communities.
1.
2.
3.
4.
5.
6.
7.

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

CakePHP Cookbook Documentation, Version 2.x

Systme de licence souple 8 .


Compatible avec les versions PHP 5.2.8 et suprieures.
Fonctions CRUD 9 . (create, read, update, delete) intgres pour les interactions avec la base de donnes.
Scaffolding 10 (maquettage rapide) dapplication.
Gnration de code.
Architecture MVC 11 .
Dispatcheur de requtes avec des URLs propres et personnalisables grce un systme de routes.
Validation intgre des donnes 12 .
Systme de template 13 rapide et souple (syntaxe PHP avec des Helpers).
Helpers (assistants) de vue pour AJAX, JavaScript, formulaires HTML...
Components (composants) intgrs : Email, Cookie, Security, Session et Request Handling.
Systme de contrle daccs ACL 14 flexible.
Nettoyage des donnes.
Systme de cache 15 souple.
Localisation et internationalisation.
Fonctionne sur nimporte quelle arborescence de site web, avec un zest de configuration Apache 16 pas
trs complique.

Comprendre le systme M-V-C (Model-View-Controller)


CakePHP suit le motif de conception logicielle MVC 17 . Programmer en utilisant MVC spare votre application en 3 couches principales :

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

Chapitre 3. Dbuter avec CakePHP

CakePHP Cookbook Documentation, Version 2.x

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.

Cycle de la requte CakePHP

Figure : 1 : Une requte MVC basique


Figure : 1 Montre la gestion typique dune requte client dans CakePHP
Le cycle dune requte CakePHP typique dbute avec une requte utilisateur qui demande une page ou une
ressource dans votre application. Cette requte est dabord traite par le dispatcheur, qui va slectionner

Comprendre le systme M-V-C (Model-View-Controller)

47

CakePHP Cookbook Documentation, Version 2.x

lobjet controller correct traitant la requte.


Une fois que la requte arrive au controller, celui-ci va communiquer avec la couche Model pour traiter
la rcupration de donnes ou les oprations de sauvegarde qui seraient ncessaires. Cette communication
termine, le controller va donner lobjet vue correct, la tche de gnrer une sortie rsultant des donnes
fournies par le model.
Finalement, quand cette sortie est gnre, elle est immdiatement rendue lutilisateur.
Presque chaque requte de votre application va suivre ce schma classique. Nous ajouterons des dtails plus
tard qui sont spcifiques CakePHP, donc gardez cela lesprit pour la suite.

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

Chapitre 3. Dbuter avec CakePHP

CakePHP Cookbook Documentation, Version 2.x

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.

Les cas de Test


Si vous avez toujours le sentiment que linformation fournie par lAPI est insuffisante, regardez le code des
cas de test fournis avec CakePHP. Ils peuvent servir dexemples pratiques pour lutilisation dune fonction
et de donnes membres dune classe.
lib/Cake/Test/Case

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.

Communauts Officiels CakePHP


CakePHP Google Group 20
CakePHP a aussi son groupe officiel sur Google Groups. Il y a des centaines de personne qui discutent des
projets CakePHP, qui saident les uns les autres, rsolvent des problmes, qui construisent des projets et
19. https ://github.com/cakephp ?tab=members
20. http ://groups.google.com/group/cake-php

O obtenir de laide

49

CakePHP Cookbook Documentation, Version 2.x

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.

Where to get Help in your Language


French
French CakePHP Community 22

21. http ://stackoverflow.com/questions/tagged/cakephp/


22. http ://cakephp-fr.org

50

Chapitre 3. Dbuter avec CakePHP

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

CakePHP Cookbook Documentation, Version 2.x

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();
}

Les paramtres de requte


Quand une requte est fate dans une application CakePHP, Les classes Router et Dispatcher de
CakePHP utilisent la Configuration des Routes pour trouver et crer le bon controller. La requte de donnes
est encapsule dans un objet request. CakePHP met toutes les informations importantes de la requte dans
la proprit $this->request. Regardez la section CakeRequest pour plus dinformations sur lobjet
request de CakePHP.

Les Actions du Controller


Les actions du Controller sont responsables de la conversion des paramtres de la requte dans une rponse
pour le navigateur/utilisateur faisant la requte. CakePHP utilise les conventions pour automatiser le processus et retirer quelques codes boiler-plate que vous auriez besoin dcrire autrement.
Par convention, CakePHP rend une vue avec une version inflecte du nom de laction.
Revenons notre boulangerie en-ligne par exemple, notre RecipesController pourrait contenir les actions view(), share(), et search(). Le controller serait trouv dans
/app/Controller/RecettesController.php et contiendrait :

52

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

# /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..
}
}

Les fichiers de vue pour ces actions seraient app/View/Recettes/view.ctp,


app/View/Recettes/share.ctp, et app/View/Recettes/search.ctp. Le nom du
fichier de vue est par convention le nom de laction en minuscules et avec des underscores.
Les actions du Controller utilisent gnralement set() pour crer un contexte que View utilise pour rendre
la vue. Du fait des conventions que CakePHP utilise, vous navez pas crer et rendre la vue manuellement.
Au lieu de a, une fois quune action du controller est termine, CakePHP va grer le rendu et la livraison
de la Vue.
Si pour certaines raisons, vous voulez viter le comportement par dfaut, les deux techniques suivantes ne
vont pas appliquer le comportement de rendu par dfaut de la vue.
Si vous retournez une chane de caractres, ou un objet qui peut tre converti en une chane de caractres
partir dune action du controller, elle sera utilise comme contenu de rponse.
Vous pouvez retourner un objet CakeResponse avec la rponse compltement cre.
Quand vous utilisez les mthodes du controller avec requestAction(), vous voudrez souvent retourner
les donnes qui ne sont pas des chanes de caractre. Si vous avez des mthodes du controller qui sont
utilises pour des requtes web normales + requestAction, vous devrez vrifier le type de requte avant de
retourner :
class RecipesController extends AppController {
public function popular() {
$popular = $this->Recipe->popular();
if (!empty($this->request->params['requested'])) {
return $popular;
}
$this->set('popular', $popular);
}
}

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

CakePHP Cookbook Documentation, Version 2.x

Request Life-cycle callbacks


class Controller
Les controllers de CakePHP sont livrs par dfaut avec des mthodes de rappel (ou callback) que vous
pouvez utiliser pour insrer de la logique juste avant ou juste aprs que les actions du controller soient
effectues :
Controller::beforeFilter()
Cette fonction est excute avant chaque action du controller. Cest un endroit pratique pour vrifier
le statut dune session ou les permissions dun utilisateur.
Note : La mthode beforeFilter() sera appele pour les actions manquantes et les actions de scaffolding.
Controller::beforeRender()
Cette mthode est appele aprs laction du controller mais avant que la vue ne soit rendue. Ce callback nest pas souvent utilis, mais peut-tre ncessaire si vous appellez render() manuellement
la fin dune action donne.
Controller::afterFilter()
Cette mthode est appele aprs chaque action du controller, et aprs que laffichage soit termin.
Cest la dernire mthode du controller qui est excute.
En plus des callbacks des controllers, les Components (Composants) fournissent aussi un ensemble similaire
de callbacks.

Les Mthodes du Controller


Pour une liste complte des mthodes de controller avec leurs descriptions, consultez lAPI de CakePHP 1 .

Interactions avec les vues


Les Controllers interagissent avec les vues de plusieurs faons. Premirement, ils sont capables de passer
des donnes aux vues, en utilisant set(). Vous pouvez aussi dcider quelle classe de vue utiliser, et quel
fichier de vue doit tre rendu partir du controller.
Controller::set(string $var, mixed $value)
La mthode set() est la voie principale utilise pour transmettre des donnes de votre controller
votre vue. Une fois set() utilise, la variable de votre controller devient accessible par la vue :
// Dans un premier temps vous passez les donnes depuis le controller:
$this->set('couleur', 'rose');
// Ensuite vous pouvez les utiliser dans la vue de cette manire:
?>
1. http ://api.cakephp.org/2.4/class-Controller.html

54

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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);

Lattribut $pageTitle nexiste plus. Utilisez set() pour dfinir le titre :


$this->set('title_for_layout', 'Ceci est la page titre');

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.

Les Mthodes du Controller

55

CakePHP Cookbook Documentation, Version 2.x

Rendre une vue spcifique


Dans votre controller, vous pourriez avoir envie de rendre une vue diffrente de celle rendue par dfaut.
Vous pouvez faire cela en appelant directement render(). Une fois que vous avez appel render()
CakePHP nessaiera pas de re-rendre la vue :
class PostsController extends AppController {
public function mon_action() {
$this->render('fichier_personnalise');
}
}

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
:

class PostsController extends AppController {


public function my_action() {
$this->render('Users.UserDetails/custom_file');
}
}

Cela rendrait la vue app/Plugin/Users/View/UserDetails/custom_file.ctp

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

Vous pouvez aussi passer des donnes laction :


$this->redirect(array('action' => 'editer', $id));

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
));

Un exemple dutilisation des requtes en chanes et hashs ressemblerait ceci :


$this->redirect(array(
'controller' => 'commandes',
'action' => 'confirmation',
'?' => array(
'produit' => 'pizza',
'quantite' => 5
),
'#' => 'top'
));

LURL gnr serait : http://www.example.com/commandes/confirmation?produit=pizza&qua


Controller::flash(string $message, string|array $url, integer $pause, string $layout)
Tout comme redirect(), la mthode flash() est utilise pour rediriger un utilisateur vers une
autre page la fin dune opration. La mthode flash() est toutefois diffrente en ce sens quelle
affiche un message avant de diriger lutilisateur vers une autre url.
Le premier paramtre devrait contenir le message qui sera affich et le second paramtre une URL
relative votre application CakePHP. CakePHP affichera le $message pendant $pause secondes
avant de rediriger lutilisateur.
Si vous souhaitez utiliser un template particulier pour messages flash, vous pouvez spcifier le nom
du layout dans le paramtre $layout.
Pour dfinir des messages flash dans une page, regardez du ct de la mthode
SessionComponent::setFlash() du component Session (SessionComponent).

Les Mthodes du Controller

57

CakePHP Cookbook Documentation, Version 2.x

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...

Autres Mthodes utiles


Controller::constructClasses()
Cette mthode charge en mmoire les models ncessaires au controller. Cette procdure de chargement est normalement effectue par CakePHP, mais cette mthode est garder sous le coude quand
vous avez besoin daccder certains controllers dans une autre perspective. Si vous avez besoin de CakePHP dans un script utilisable en ligne de commande ou dautres utilisations externes,
constructClasses() peut devenir pratique.
Controller::referer(mixed $default = null, boolean $local = false)
Retourne lURL rfrente de la requte courante. Le paramtre $default peut tre utilis pour
fournir une URL par dfaut utiliser si HTTP_REFERER ne peut pas tre lu par les headers. Donc,
au lieu de faire ceci :
class UtilisateursController extends AppController {
public function delete($id) {
// le code de suppression va ici, et ensuite...
if ($this->referer() != '/') {
return $this->redirect($this->referer());
}
return $this->redirect(array('action' => 'index'));
}
}

vous pouvez faire ceci :


class UtilisateursController extends AppController {
public function delete($id) {
// le code de suppression va ici, et ensuite...
return $this->redirect($this->referer(array('action' => 'index')));
}
}

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

Controller::postConditions(array $data, mixed $op, string $bool, boolean $exclusive)


Utilisez cette mthode pour transformer des donnes de formulaire, transmises par POST (depuis
les inputs du Helper Form), en des conditions de recherche pour un model. Cette fonction offre un
raccourci apprciable pour la construction de la logique de recherche. Par exemple, un administrateur
aimerait pouvoir chercher des commandes dans le but de connatre les produits devant tre emballs.
Vous pouvez utiliser les Helpers Form et Html pour construire un formulaire rapide bas sur le model
Commande. Ensuite une action du controller peut utiliser les donnes postes par ce formulaire pour
construire automatiquement les conditions de la recherche :
public function index() {
$conditions = $this->postConditions($this->request->data);
$commandes = $this->Commande->find('all', compact('conditions'));
$this->set('commandes', $orders);
}

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'));

Les Mthodes du Controller

59

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

$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');

En array dans requestAction serait ainsi :


echo $this->requestAction(
array('controller' => 'articles', 'action' => 'featured'),
array('named' => array('limit' => 3))
);
echo $this->requestAction(
array('controller' => 'articles', 'action' => 'view'),
array('pass' => array(5))
);

Note : Contrairement aux autres places o les URLs en tableau sont analogues aux URLs en chane
de caractre, requestAction les traite diffremment.

Les Mthodes du Controller

61

CakePHP Cookbook Documentation, Version 2.x

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();

Les attributs du Controller


Pour une liste complte des attributs du controller et ses descriptions, regardez lAPI de CakePHP 2 .
property Controller::$name
Lattribut $name doit tre dfini selon le nom du controller. Habituellement, cest juste la forme
plurielle du model principal que le controller utilise. Cette proprit nest pas requise, mais vite
CakePHP dinflecter dessus :
// Exemple d'utilisation d'attribut $name du controller
class RecipesController extends AppController {
public $name = 'Recipes';
}

$components, $helpers et $uses


Les autres attributs les plus souvent utiliss permettent dindiquer CakePHP quels $helpers,
$components et models vous utiliserez avec le controller courant. Utiliser ces attributs rend ces classes
MVC, fournies par $components et $uses, disponibles pour le controller, sous la forme de variables
de classe ($this->ModelName, par exemple) et celles fournies par $helpers, disponibles pour la vue
comme une variable rfrence lobjet ($this->{$helpername}).
Note : Chaque controller a dj accs, par dfaut, certaines de ces classes, donc vous navez pas besoin
de les redfinir.
property Controller::$uses
Les controllers ont accs par dfaut leur model primaire respectif. Notre controller Recettes aura
2. http ://api.cakephp.org/2.4/class-Controller.html

62

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

Les attributs du Controller

63

CakePHP Cookbook Documentation, Version 2.x

En savoir plus sur les controllers


Les Objets Request et Response
Les objets request et response sont nouveaux depuis CakePHP 2.0. Dans les versions prcdentes,
ces objets taient reprsents travers des tableaux, et les mthodes lies taient utilises travers
RequestHandlerComponent, Router, Dispatcher et Controller. Il ny avait pas dobjet global qui reprenait les informations de la requte. Depuis CakePHP 2.0, CakeRequest et
CakeResponse sont utiliss pour cela.

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

// 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

Accder aux donnes POST


Toutes les donnes POST peuvent tre atteintes travers CakeRequest::$data. Nimporte quelle
forme de tableau qui contient un prfixe data, va avoir sa donne prfixe retire. Par exemple :
// Un input avec un nom attribute gal 'data[MyModel][title]'
// est accessible
$this->request->data['MyModel']['title'];

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 :

En savoir plus sur les controllers

65

CakePHP Cookbook Documentation, Version 2.x

$foo = $this->request->data('Value.that.does.not.exist');
// $foo == null

Accder aux donnes PUT ou POST


Introduit dans la version 2.2.
Quand vous construisez des services REST, vous acceptez souvent des donnes requtes sur des requtes PUT et DELETE. Depuis 2.2, toute donne de corps de requte
application/x-www-form-urlencoded va automatiquement tre parse et dfinie dans
$this->data pour les requtes PUT et DELETE. Si vous acceptez les donnes JSON ou XML,
regardez ci-dessous comment vous pouvez accder aux corps de ces requtes.
Accder aux donnes XML ou JSON
Les applications employant REST changent souvent des donnes dans des organes post non encodes en URL. Vous pouvez lire les donnes entrantes dans nimporte quel format en utilisant
CakeRequest::input(). En fournissant une fonction de dcodage, vous pouvez recevoir le contenu
dans un format dserializ :
// Obtenir les donnes encodes JSON soumises par une action PUT/POST
$data = $this->request->input('json_decode');

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'));

Accder aux informations du chemin


CakeRequest fournit aussi des informations utiles sur les chemins dans votre application.
CakeRequest::$base et CakeRequest::$webroot sont utiles pour gnrer des URLs, et dterminer si votre application est ou nest pas dans un sous-dossier.
Inspecter la requte
Dans les anciennes versions, dtecter les diffrentes conditions de la requte ncssitait
RequestHandlerComponent. Ces mthodes ont t dplaces dans CakeRequest, ce qui offre une nouvelle interface tout le long, compatible avec les utilisations anciennes :
$this->request->is('post');
$this->request->isPost(); // dprci

66

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

is(delete) Vrifie si la requte courante est un DELETE.


is(head) Vrifie si la requte courante est un HEAD.
is(options) Vrifie si la requte courante est OPTIONS.
is(ajax) Vrifie si la requte courante vient dun X-Requested-With = XMLHttpRequest.
is(ssl) Vrifie si la requte courante est via SSL.
is(flash) Vrifie si la requte courante a un User-Agent de Flash.
is(mobile) Vrifie si la requte courante vient dune liste courante de mobiles.

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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');

Retournerait le user agent utilis pour la requte.


CakeRequest::input($callback[, $options ])
Rcupre les donnes dentre pour une requte, et les passe optionnellement travers une fonction
qui dcode. Utile lors des interactions avec une requte de contenu de corps XML ou JSON. Les
paramtres supplmentaires pour la fonction dcodant peuvent tre passs comme des arguments de
input() :
$this->request->input('json_decode');

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');

Introduit dans la version 2.3.


CakeRequest::is($type)
Vrifie si la requte remplit certains critres ou non. Utilisez les rgles de dtection dj construites
ainsi que toute rgle supplmentaire dfinie dans CakeRequest::addDetector().
CakeRequest::addDetector($name, $options)
Ajoute un dtecteur pour tre utilis avec CakeRequest::is(). Voir Inspecter la requte pour
plus dinformations.

En savoir plus sur les controllers

69

CakePHP Cookbook Documentation, Version 2.x

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();

Vrifie pour un unique type :


$this->request->accepts('application/json');

static CakeRequest::acceptLanguage($language = null)


Obtenir toutes les langues acceptes par le client, ou alors vrifier si une langue spcifique est accepte.
Obtenir la liste des langues acceptes :
CakeRequest::acceptLanguage();

Vrifier si une langue spcifique est accepte :


CakeRequest::acceptLanguage('es-es');

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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 :

En savoir plus sur les controllers

71

CakePHP Cookbook Documentation, Version 2.x

public function sendFile($id) {


$file = $this->Attachment->getFile($id);
$this->response->file($file['path']);
//Retourne un objet reponse pour viter que le controller n'essaie de
// rendre la vue
return $this->response;
}

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')
);

Envoyer une chane en fichier


Vous pouvez rpondre avec un fichier qui nexiste pas sur le disque, par exemple si vous voulez gnrer un
pdf ou un ics la vole et voulez servir la chane gnre en fichier, vous pouvez faire cela en utilisant :
public function sendIcs() {
$icsString = $this->Calendar->generateIcs();
$this->response->body($icsString);
$this->response->type('ics');
//Force le tlchargement de fichier en option
$this->response->download('filename_for_download.ics');
//Retourne l'object pour viter au controller d'essayer de rendre
// une vue
return $this->response;
}

Dfinir les en-ttes


Le rglage des en-ttes est fait avec la mtode CakeResponse::header(). Elle peut tre appele avec
quelques paramtres de configurations :
// Rgler un unique en-tte
$this->response->header('Location', 'http://example.com');
// Rgler plusieurs en-ttes
$this->response->header(array(
'Location' => 'http://example.com',

72

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

'X-Extra' => 'My header'


));
$this->response->header(array(
'WWW-Authenticate: Negotiate',
'Content-type: application/pdf'
));

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

CakePHP Cookbook Documentation, Version 2.x

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

Introduit dans la version 2.1.


Utilis sous le model dexpiration, cet en-tte contient de multiples indicateurs qui peuvent changer la faon
dont les navigateurs ou les proxies utilisent le contenu mis en cache. Un en-tte Cache-Control peut
ressembler ceci :
Cache-Control: private, max-age=3600, must-revalidate

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

Introduit dans la version 2.1.

74

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

Introduit dans la version 2.1.


Cache validation dans HTTP est souvent utilis quand le contenu change constamment et demande lapplication de gnrer seulement les contenus rponse si le cache nest plus rcent. Sous ce model, le client
continue de stocker les pages dans le cache, mais au lieu de lutiliser directement, il demande lapplication
chaque fois si les ressources ont chang ou non. Cest utilis couramment avec des ressources statiques
comme les images et autres choses.
Len-tte etag() (appel balise dentit) est une chane de caractre qui identifie de faon unique les
ressources requtes. Il est trs semblable la somme de contrle dun fichier ; la mise en cache permettra
de comparer les sommes de contrle pour savoir si elles correspondent ou non.
Pour rellement tirer profit de lutilisation de cet en-tte, vous devez soit appeler manuellement la mthode
CakeResponse::checkNotModified(), soit avoir le RequestHandlerComponent inclus dans
votre controller :
public function index() {
$articles = $this->Article->find('all');
$this->response->etag($this->Article->generateHash($articles));
if ($this->response->checkNotModified($this->request)) {
return $this->response;
}
...
}

Len-tte Last-Modified

Introduit dans la version 2.1.


Toujours dans le cadre du model de validation du cache HTTP, vous pouvez dfinir len-tte
Last-Modified pour indiquer la date et le temps pendant lequel la ressource a t modifie pour la
dernire fois. Dfinir cet en-tte aide la rponse de CakePHP pour mettre en cache les clients si la rponse a
t modifie ou nest pas base sur leur cache.
Pour rellement tirer profit de lutilisation de cet en-tte, vous devez soit appeler manuellement la mthode
CakeResponse::checkNotModified(), soit avoir le RequestHandlerComponent inclus dans
votre controller :
En savoir plus sur les controllers

75

CakePHP Cookbook Documentation, Version 2.x

public function view() {


$article = $this->Article->find('first');
$this->response->modified($article['Article']['modified']);
if ($this->response->checkNotModified($this->request)) {
return $this->response;
}
...
}

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');

CakeResponse et les tests


Probablement lune des plus grandes victoires de CakeResponse vient de comment il facilite les tests des
controllers et des components. Au lieu davoir des mthodes rpandues travers plusieurs objets, vous avez
un seul objet pour mocker pendant que les controllers et les components dlguent CakeResponse. Cela
vous aide rester plus prs dun test unitaire et facilite les tests des controllers :
public function testSomething() {
$this->controller->response = $this->getMock('CakeResponse');
$this->controller->response->expects($this->once())->method('header');
// ...
}

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

// Dfinit la localisation du redirect


$this->response->location('http://example.com');
// Rcupre l'en-tte de localisation du redirect actuel
$location = $this->response->location();

Introduit dans la version 2.4.


CakeResponse::charset($charset = null)
Configure le charset qui sera utilis dans la rponse.
CakeResponse::type($contentType = null)
Configure le type de contenu pour la rponse. Vous pouvez soit utiliser un alias de type de contenu
connu, soit le nom du type de contenu complet.
CakeResponse::cache($since, $time = +1 day)
Vous permet de configurer les en-ttes de mise en cache dans la rponse.
CakeResponse::disableCache()
Configure les en-ttes pour dsactiver la mise en cache des clients pour la rponse.
CakeResponse::sharable($public = null, $time = null)
Configure len-tte Cache-Control pour tre soit public soit private et configure optionnellement une directive de la ressource un max-age.
Introduit dans la version 2.1.
CakeResponse::expires($time = null)
Permet de configurer len-tte Expires une date spcifique.
Introduit dans la version 2.1.
CakeResponse::etag($tag = null, $weak = false)
Configure len-tte Etag pour identifier de manire unique une ressource de rponse.
Introduit dans la version 2.1.
CakeResponse::modified($time = null)
Configure len-tte Last-modified une date et un temps donn dans le format correct.
Introduit dans la version 2.1.
CakeResponse::checkNotModified(CakeRequest $request)
Compare les en-ttes mis en cache pour lobjet request avec len-tte mis en cache de la rponse et
dtermine si il peut toujours tre considr comme rcent. Dans ce cas, il supprime tout contenu de
rponse et envoie len-tte 304 Not Modified.
Introduit dans la version 2.1.
CakeResponse::compress()
Dmarre la compression gzip pour la requte.
CakeResponse::download($filename)
Vous permet denvoyer la rponse en pice jointe et de configurer le nom de fichier.
CakeResponse::statusCode($code = null)
Vous permet de configurer le code de statut pour la rponse.

En savoir plus sur les controllers

77

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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';
}

Crer une interface admin simplifie avec scaffolding


Si vous avez activ le routage admin dans votre app/Config/core.php, avec
Configure::write(Routing.prefixes, array(admin));, vous pouvez utiliser
le scaffolding (chafaudage) pour gnrer une interface dadministration.
Une fois que vous avez activ le routage admin, assignez votre prfixe dadministration la variable de
scaffolding :
public $scaffold = 'admin';

Vous serez maintenant capable daccder aux actions scaffoldes


http://example.com/admin/controller/index
http://example.com/admin/controller/view
http://example.com/admin/controller/edit
http://example.com/admin/controller/add
http://example.com/admin/controller/delete

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

CakePHP Cookbook Documentation, Version 2.x

public function admin_view($id = null) {


// du code ici
}

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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 :

En savoir plus sur les controllers

81

CakePHP Cookbook Documentation, Version 2.x

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
}

Ce quil y a au-dessous donnerait un alias MyAuthComponent $this->Auth dans vos controllers.


Note : Faire un alias un component remplace cette instance nimporte o o le component est utilis, en
incluant lintrieur des autres Components.

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,

82

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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 :
class MathComponent extends Component {
public function faireDesOperationsComplexes($montant1, $montant2) {
return $montant1 + $montant2;
}
}

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
En savoir plus sur les controllers

83

CakePHP Cookbook Documentation, Version 2.x

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'
);

Lexemple ci-dessus passerait le tableau contenant precision et generateurAleatoire comme second


paramtre au MathComponent::__construct(). Par convention, si les cls du tableau correspondent aux proprits publiques du component, les proprits seront dfinies avec les valeurs de ces cls.
Utiliser dautres Components dans votre Component

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

public function foo() {


// ...
}
}

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.

En savoir plus sur les controllers

85

CakePHP Cookbook Documentation, Version 2.x

86

Chapitre 4. Controllers (Contrleurs)

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

// Le contenu restant sera disponible en tant que block 'content'


// dans la vue parente.
echo h($post['Post']['body']);

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.

Utiliser les Blocs de Vues


Introduit dans la version 2.1.
Les blocs de vue remplacent les $scripts_for_layout et fournissent une API flexible qui vous permet
de dfinir des slots (emplacements), ou blocs, dans vos vues / layouts qui peuvent tre dfinies ailleurs. Par
exemple, les blocs pour implmenter des choses telles que les sidebars, ou des rgions pour charger des
ressources dans len-tte / pied de page du layout. Un block peut tre dfini de deux manires. Soit en tant
que block capturant, soit en le dclarant explicitement. Les mthodes start(), append() et end()
vous permettent de travailler avec les blocs capturant :
// Creer le block sidebar.
$this->start('sidebar');
echo $this->element('sidebar/recent_topics');
echo $this->element('sidebar/recent_comments');
$this->end();

// Le rattacher a la sidebar plus tard.


$this->append('sidebar');
echo $this->element('sidebar/popular_topics');
$this->end();

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 :

Utiliser les Blocs de Vues

89

CakePHP Cookbook Documentation, Version 2.x

// Nettoyer le contenu prcedent de la sidebar.


$this->assign('sidebar', '');

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.

Afficher les Blocs


Introduit dans la version 2.1.
Vous pouvez afficher les blocs en utilisant la mthode fetch(). Cette dernire va, de manire scurise,
gnrer un bloc, en retournant si le bloc nexiste pas :
echo $this->fetch('sidebar');

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

// 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>

Modifi dans la version 2.3 : Largument $default a t ajout dans 2.3.

Utiliser des Blocks pour les Fichiers de Script et les CSS


Introduit dans la version 2.1.
Les Blocks remplacent la variable de layout $scripts_for_layout qui est dprcie. A la place, vous
devrez utiliser les blocks. HtmlHelper lie dans les blocks de vues avec les mthodes script(), css(),
et meta() qui chacune met jour un block avec le mme nom quand loption inline = false est
utilise :
<?php
// dans votre fichier de vue
$this->Html->script('carousel', array('inline' => false));
$this->Html->css('carousel', array('inline' => false));
?>
// dans votre fichier de layout.
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php echo $this->fetch('title'); ?></title>
<?php echo $this->fetch('script'); ?>
<?php echo $this->fetch('css'); ?>
</head>
// rest du layout suit

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');

Utiliser les Blocs de Vues

91

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

Le block content contient les contenus de la vue rendue.


$title_for_layout contient le titre de la page. Cette variable est gnre automatiquement, mais vous
pouvez la surcharger en la configurant dans votre controller/view.
Note : $title_for_layout est dprci depuis 2.5, utilisez $this->fetch(title) dans votre
layout et $this->assign(title, page title) la place.
Vous pouvez crer autant de layouts que vous souhaitez : placez les juste dans le rpertoire
app/View/Layouts, et passez de lun lautre depuis les actions de votre controller en utilisant la
proprit $layout de votre controller ou de votre vue :
// A partir d'un controller
public function admin_view() {
// stuff
$this->layout = 'admin';
}
// A partir d'un fichier de vue
$this->layout = 'loggedin';

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.

Utiliser les layouts partir de plugins


Introduit dans la version 2.1.

Layouts

93

CakePHP Cookbook Documentation, Version 2.x

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');

Passer des Variables lintrieur dun Element


Vous pouvez passer des donnes dans un element grce au deuxime argument de element :
echo $this->element('helpbox', array(
"helptext" => "Oh, this text is very helpful."
));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Mise en cache des Elements


Vous pouvez tirer profit de la mise en cache de vue de CakePHP si vous fournissez un paramtre cache. Si
dfini true, cela va mettre en cache lelement dans la configuration default de Cache. Sinon, vous pouvez
dfinir la configuration de cache devant tre utilise. Regardez La mise en cache pour plus dinformations
sur la faon de configurer Cache. Un exemple simple de mise en cache dun element serait par exemple :
echo $this->element('helpbox', array(), array('cache' => true));

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.

Requter les Elements partir dun Plugin


2.0
Pour charger un element dun plugin, utilisez loption plugin (retir de loption data dans 1.x) :
echo $this->element('helpbox', array(), array('plugin' => 'Contacts'));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

echo $this->element('helpbox');
// et
echo $this->element('Contacts.helpbox');

Sont quivalents et rsulteront au mme element rendu.


Modifi dans la version 2.1 : Loption $options[plugin] a t dprci et le support pour
Plugin.element a t ajout.

Crer vos propres classes de vue


Vous avez peut-tre besoin de crer vos propres classes de vue pour activer des nouveaux types de donnes
de vue, ou ajouter de la logique supplmentaire de rendu de vue personnalise. Comme la plupart des
components de CakePHP, les classes de vue ont quelques conventions :
Les fichiers de classe de View doivent tre mis dans App/View. Par exemple
App/View/PdfView.php.
Les classes de View doivent tre suffixes avec View. Par exemple PdfView.
Quand vous rfrencez les noms de classe de vue, vous devez omettre le suffixe View. Par exemple
$this->viewClass = Pdf;.
Vous voudrez aussi tendre View pour vous assurer que les choses fonctionnent correctement :
// dans App/View/PdfView.php
App::uses('View', 'View');
class PdfView extends View {
public function render($view = null, $layout = null) {
// logique personnalise ici.
}
}

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');

Crer vos propres classes de vue

97

CakePHP Cookbook Documentation, Version 2.x

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::addScript(string $name, string $content)


Ajoute du contenu au buffer des scripts internes. Ce buffer est rendu disponible dans le layout dans
$scripts_for_layout. Cette mthode est utile quand vous crez des helpers qui ont besoin
dajouter du JavaScript ou du CSS directement au layout. Gardez lesprit que les scripts ajouts
partir du layout, ou des elements du layout ne seront pas ajouts $scripts_for_layout.
Cette mthode est plus souvent utilise de lintrieur des helpers, comme pour les helpers JSHelper
et HTMLHelper.
Obsolte depuis la version 2.1 : Utilisez les fonctionnalits Utiliser les Blocs de Vues la place.
View::blocks()
Rcupre les noms de tous les blocks dfinis en tant que tableau.
View::start($name)
Commence un block de capture pour un block de vue. Regardez la section Utiliser les Blocs de Vues
pour avoir des exemples.
Introduit dans la version 2.1.
View::end()
Termine le block de capture ouvert le plus en haut. Regardez la section sur les Utiliser les Blocs de
Vues pour avoir des exemples.
Introduit dans la version 2.1.
98

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

En savoir plus sur les vues


Thmes
Vous pouvez profiter des thmes, ce qui facilite le changement du visuel et du ressenti de votre page rapidement et facilement.
Pour utiliser les thmes, spcifiez le nom du thme dans votre controller :
class ExempleController extends AppController {
public $theme = 'Exemple';
}

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

Augmenter la performance des assets du plug-in et du thme

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
);

En savoir plus sur les vues

101

CakePHP Cookbook Documentation, Version 2.x

$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.

Vues JSON et XML


Deux nouvelles classes de vue dans CakePHP 2.1. Les vues XmlView et JsonView vous laissent crer
facilement des rponses XML et JSON, et sont intgres avec RequestHandlerComponent.

102

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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'));
}
}

Vous pouvez aussi dfinir _serialize en tableau de variables de vue combiner :


class PostsController extends AppController {
public $components = array('RequestHandler');
public function index() {

En savoir plus sur les vues

103

CakePHP Cookbook Documentation, Version 2.x

// some code that created $posts and $comments


$this->set(compact('posts', 'comments'));
$this->set('_serialize', array('posts', 'comments'));
}
}

Dfinir _serialize en tableau a le bnfice supplmentaire dajouter automatiquement un elment de


top-niveau <response> en utilisant XmlView. Si vous utilisez une valeur de chane de caractre pour
_serialize et XmlView, assurez-vous que vos variables de vue aient un elment unique de top-niveau.
Sans un elment de top-niveau, le Xml ne pourra tre gnr.
Utilisation dune vue de donnes avec les fichiers de vue
Vous devriez utiliser les fichiers de vue si vous avez besoin de faire des manipulations du contenu de votre
vue avant de crer la sortie finale. Par exemple, si vous avez des posts, qui ont un champ contenant du HTML
gnr, vous aurez probablement envie domettre ceci partir dune rponse JSON. Cest une situation o
un fichier de vue est utile :
// Code du controller
class PostsController extends AppController {
public function index() {
$this->set(compact('posts', 'comments'));
}
}
// Code de la vue - app/View/Posts/json/index.ctp
foreach ($posts as &$post) {
unset($post['Post']['generated_html']);
}
echo json_encode(compact('posts', 'comments'));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.
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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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-->

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())

En savoir plus sur les vues

107

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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">

Ce formulaire enverra les donnes votre action add() de RecipesController (RecettesController)


. Cependant, vous pouvez utiliser la mme logique pour crer et modifier des formulaires. Le helper
Form utilise la proprit $this->request->data pour dtecter automatiquement sil faut crer
un formulaire dajout ou de modification. Si $this->request->data contient un tableau nomm
daprs le model du formulaire , et que ce tableau contient une valeur non nulle pour la cl primaire
du model, alors le FormHelper crera un formulaire de modification pour cet enregistrement prcis.
Par exemple, si on va ladresse http ://site.com/recipes/edit/5, nous pourrions avoir cela :
// Controller/RecipesController.php:
public function edit($id = null) {
if (empty($this->request->data)) {
$this->request->data = $this->Recipe->findById($id);
} else {
// La logique de sauvegarde se fera ici
}
}
// View/Recipes/edit.ctp:

En savoir plus sur les vues

109

CakePHP Cookbook Documentation, Version 2.x

// 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">

En spcifiant file cela changera la mthode de soumission post, et ajoutera un enctype


multipart/form-data dans le tag du formulaire. Vous devez lutiliser si vous avez des demandes de
fichiers dans votre formulaire. Labsence de cet attribut enctype empchera le fonctionnement de lenvoi de fichiers.
echo $this->Form->create('User', array('type' => 'file'));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$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">

ou pointer vers un domaine extrieur :


echo $this->Form->create(null, array(
'url' => 'http://www.google.com/search',
'type' => 'get'
));

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() :

En savoir plus sur les vues

111

CakePHP Cookbook Documentation, Version 2.x

// 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>

Vous pouvez spcifier des paramtres dtaills en passant un tableau end() :


$options = array(
'label' => 'Update',
'div' => array(
'class' => 'glass-pill',
)
);
echo $this->Form->end($options);

Affichera :
<div class="glass-pill"><input type="submit" value="Update!" name="Update"></div>

Voir lAPI du Helper Form 1 pour plus de dtails.


Note : si vous utilisez le component scurit SecurityComponent dans votre application vous
devez toujours terminer vos formulaires avec end().
Modifi dans la version 2.5 : Le paramtre $secureAttributes a t ajout dans 2.5.
1. http ://api.cakephp.org/2.4/class-FormHelper.html

112

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

Cration dlments de Formulaire

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');

En savoir plus sur les vues

//text

113

CakePHP Cookbook Documentation, Version 2.x

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');

Un exemple plus complet montrant quelques options pour le champ de date :


echo $this->Form->input('birth_dt', array(
'label' => 'Date de naissance',
'dateFormat' => 'DMY',
'minYear' => date('Y') - 70,
'maxYear' => date('Y') - 18,
));

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'));

Ensuite, ajouter les lignes suivantes votre vue de formulaire :


echo $this->Form->input('group_id');

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 :
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 :

En savoir plus sur les vues

115

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->input('Model.year', array(


'type' => 'text',
'name' => 'data[Model][year]'
));

Options FormHelper::input() supporte un nombre important doptions. En plus de ses propres


options input() accepte des options pour les champs input gnrs, comme les attributs html. Ce qui suit
va couvrir les options spcifiques de FormHelper::input().
$options[type] Vous pouvez forcer le type dun input, remplaant lintrospection du model, en
spcifiant un type. En plus des types de champs vus dans Cration dlments de Formulaire, vous pouvez
aussi crez des fichiers, password et divers types supports par HTML5 :
echo $this->Form->input('field', array('type' => 'file'));
echo $this->Form->input('email', array('type' => 'email'));

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>

Paramtrage de plusieurs attibuts :


echo $this->Form->input('User.name', array(
'div' => array(
'id' => 'mainDiv',
'title' => 'Div Title',
'style' => 'display:block'
)
));

Affichera :

116

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<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>

Dsactiver le rendu de la div


echo $this->Form->input('User.name', array('div' => false)); ?>

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>

Alternativement, dfinissez cette cl false pour dsactiver le rendu du label :


echo $this->Form->input('User.name', array('label' => false));

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>

En savoir plus sur les vues

117

CakePHP Cookbook Documentation, Version 2.x

$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 modifier le type denveloppe de llment et sa classe, utilisez le format suivant :


$this->Form->input('Model.field', array(
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'bzzz'))
));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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.
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

CakePHP Cookbook Documentation, Version 2.x

// 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.
$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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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
<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

CakePHP Cookbook Documentation, Version 2.x

<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>
</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" />

Ceci peut tre dsactiv en dfinissant loption $options[hiddenField] = false :


echo $this->Form->checkbox('published', array('hiddenField' => false));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<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',
));

Les options de Datetime


$options[timeFormat]. Utilis pour spcifier le format des inputs select (menu de slection)
pour un jeu dinput en relation avec le temps. Les valeurs valides sont 12, 24, et null.
$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

En savoir plus sur les vues

123

CakePHP Cookbook Documentation, Version 2.x

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>

FormHelper::text(string $name, array $options)


Les autres mthodes disponibles dans lHelper Form permettent la cration dlments spcifiques de
formulaire. La plupart de ces mthodes utilisent galement un paramtre spcial $options. Toutefois,
dans ce cas, $options est utilis avant tout pour spcifier les attributs des balises HTML (comme la
valeur ou lid DOM dun lment du formulaire).
echo $this->Form->text('username', array('class' => 'users'));

Affichera :
<input name="data[User][username]" type="text" class="users" id="UserUsername" />

FormHelper::password(string $fieldName, array $options)


Cration dun champ password.
echo $this->Form->password('password');

Affichera :
<input name="data[User][password]" value="" id="UserPassword" type="password">

FormHelper::hidden(string $fieldName, array $options)


Crera un form input cach. Exemple :
echo $this->Form->hidden('id');

Affichera :
<input name="data[User][id]" id="UserId" type="hidden">

124

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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>

FormHelper::checkbox(string $fieldName, array $options)


Cre un lment de formulaire checkbox. Cette mthode gnre galement un input de formulaire
cach pour forcer la soumission de donnes pour le champ spcifi.
echo $this->Form->checkbox('done');

Affichera :

En savoir plus sur les vues

125

CakePHP Cookbook Documentation, Version 2.x

<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />


<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />

Il est possible de modifier la valeur du checkbox en utilisant le tableau $options :


echo $this->Form->checkbox('done', array('value' => 555));

Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />

Si vous ne voulez pas que le Helper Form gnre un input cach :


echo $this->Form->checkbox('done', array('hiddenField' => false));

Affichera :
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />

FormHelper::radio(string $fieldName, array $options, array $attributes)


Cre un jeu dinputs radios.
Options
$attributes[value] pour dfinir quelle valeur sera slectionne par dfaut.
$attributes[separator] pour spcifier du HTML entre les boutons (ex <br />).
$attributes[between] spcifie quelques contenus insrer entre la lgende et le premier
argument.
$attributes[disabled] dfinit a true ou disabled dsactivera tous les boutons
radios gnrs.
$attributes[legend] Les lments Radio sont envelopps avec un legend et un fieldset
par dfaut. Dfinir $attributes[legend] false pour les retirer.
$options = array('H' => 'Homme', 'F' => 'Femme');
$attributes = array('legend' => false);
echo $this->Form->radio('genre', $options, $attributes);

Affichera :
<input
<input
<label
<input
<label

name="data[User][genre]" id="UserGenre_" value="" type="hidden">


name="data[User][genre]" id="UserGenreH" value="H" type="radio">
for="UserGenreH">Homme</label>
name="data[User][genre]" id="UserGenreF" value="F" type="radio">
for="UserGenreF">Femme</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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$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));

$attributes[options] Cette cl vous permets de spcifier manuellement des options pour


un input select (menu de slection), ou pour un groupe radio. A moins que le type soit spcifi
radio, le Helper Form supposera que la cible est un input select (menu de slection)
echo $this->Form->select('field', array(1,2,3,4,5));

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 :

En savoir plus sur les vues

127

CakePHP Cookbook Documentation, Version 2.x

$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 :

<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][]" value="Value 1" id="ModelField1" type="check
<label for="ModelField1">Label 1</label>
</div>
<div class="checkbox">
<input name="data[Model][field][]" value="Value 2" id="ModelField2" type="check
<label for="ModelField2">Label 2</label>
</div>
</div>

$attributes[disabled] Lors de la cration de checkboxes, cette option peut tre dfini


pour dsactiver tout ou quelques checkboxes. Pour dsactiver toutes les checkboxes, dfinissez disabled true :
128

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$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.

En savoir plus sur les vues

129

CakePHP Cookbook Documentation, Version 2.x

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;
}

Cre un input file :


echo $this->Form->create('User', array('type' => 'file'));
echo $this->Form->file('avatar');

Affichera :
<form enctype="multipart/form-data" method="post" action="/users/add">
<input name="data[User][avatar]" value="" id="UserAvatar" type="file">

Note : Quand vous utilisez $this->Form->file(), rappelez-vous de dfinir le type dencodage , en


dfinissant loption de type file dans $this->Form->create().

Cration des boutons et des lments submits

FormHelper::submit(string $caption, array $options)


Cre un bouton submit avec la lgende $caption. Si la $caption fournie est lURL dune image
(il contient un caractre .), le bouton submit sera rendu comme une image.
2. http ://php.net/features.file-upload

130

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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>

FormHelper::button(string $title, array $options = array())


Cre un boutton HTML avec le titre spcifi et un type par dfaut button. Dfinir
$options[type] affichera lun des trois types de boutons possibles :
1.submit : Comme celui de la mthode $this->Form->submit- (par dfaut).
2.reset : Cre un bouton reset.
3.button : Cre un bouton standard.
echo
echo
echo
echo

$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));

FormHelper::postButton(string $title, mixed $url, array $options = array ())


Cre un tag<button> avec un <form> lentourant qui soumets travers POST.
Cette mthode cre un lment <form>. Donc nutilisez pas pas cette mthode
dans
un
formulaire
ouvert.
Utilisez
plutt
FormHelper::submit()
ou :php:meth:FormHelper::button() pour crer des boutons a lintrieur de formulaires ouvert.

En savoir plus sur les vues

131

CakePHP Cookbook Documentation, Version 2.x

FormHelper::postLink(string $title, mixed $url = null, array $options = array ())


Cre un lien HTML, mais accde lUrl en utilisant la mthode POST. Requiert que JavaScript soit
autoris dans votre navigateur.
Cette mthode cre un lment <form>. Si vous souhaitez utiliser cette mthode dans un formulaire
existant, vous devez utiliser les options inline ou block pour que le nouveau formulaire soit
affich lextrieur de son formulaire parent.
Si vous cherchez un bouton pour soumettre votre formulaire, vous devrez plutt utiliser
FormHelper::submit() instead.
Modifi dans la version 2.3.
Loption method a t ajoute.
Modifi dans la version 2.5 : Les options inline et block ont t ajoutes. Elles permettent de
mettre en tampon la balise de form gnre au lieu de la retourner avec le lien. Ceci permet dviter
les balises de form imbriques. Dfinir inline => false va ajouter la balise de form en block
de contenu postLink, si vous voulez utiliser un block personnalis vous pouvez le spcifier en
utilisant plutt loption block.
Modifi dans la version 2.6 : Largument $confirmMessage a t dprcie. Utilisez la cl
confirm dans $options la place.
Cre des inputs de date et dheure (date and time inputs)

FormHelper::dateTime($fieldName, $dateFormat = DMY, $timeFormat = 12, $attributes


= array())
Cre un jeu dinputs pour la date et lheure. Les valeurs valides pour $dateformat sont DMY, MDY,
YMD ou NONE. Les valeurs valides pour $timeFormat sont 12, 24, et null.
Vous pouvez spcifier de ne pas afficher les valeurs vides en paramtrant array(empty => false)
dans les paramtres des attributs. il pr-slectionnera galement les champs a la date et heure courante.
FormHelper::year(string $fieldName, int $minYear, int $maxYear, array $attributes)
Cre un lment select(menu de slection) rempli avec les annes depuis $minYear
jusqu $maxYear. Les attributs HTML devrons tre fournis dans $attributes. Si
$attributes[empty] est false, le select ninclura pas doption empty :
echo $this->Form->annee('purchased', 2000, date('Y'));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<option value="2000">2000</option>
</select>

FormHelper::month(string $fieldName, array $attributes)


Cre un lment select (menu de slection) avec le nom des mois :
echo $this->Form->month('mob');

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));

FormHelper::day(string $fieldName, array $attributes)


Cre un lment select (menu de slection) rempli avec les jours (numriques) du mois.
Pour crer une option empty avec laffichage dun texte de votre choix (ex. la premire option est
Jour), vous pouvez fournir le texte comme paramtre final comme ceci :
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>

FormHelper::hour(string $fieldName, boolean $format24Hours, array $attributes)


Cre un lment select (menu de slection) rempli avec les heures de la journe.

En savoir plus sur les vues

133

CakePHP Cookbook Documentation, Version 2.x

FormHelper::minute(string $fieldName, array $attributes)


Cre un lment select (menu de slection) rempli avec les minutes dune heure.
FormHelper::meridian(string $fieldName, array $attributes)
Cre un lment select (menu de slection) rempli avec am et pm.
Afficher et vrifier les erreurs

FormHelper::error(string $fieldName, mixed $text, array $options)


Affiche un message derreur de validation, spcifie par $texte, pour le champ donn, dans le cas o
une erreur de validation a eu lieu.
Options :
escape boolen si il faut ou non que le HTML chappe le contenu de lerreur.
wrap valeur mixte dfinissant sil faut ou pas que le message derreur soit envelopper dune div. Si
cest une chane , sera utilis comme le tag HTML utiliser.
class string Le nom de classe du message derreur.
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');
}

Note : En utilisant FormHelper::input(), les erreurs sont retournes par dfaut.


FormHelper::tagIsInvalid()
Retourne false si le champ fourni dcrit par lentit courante ne contient pas derreur. Sinon retourne
le message de validation.
Configuration par dfaut pour tous les champs

Introduit dans la version 2.2.


Vous pouvez dclarer un ensemble doptions par dfaut pour input() en utilisant
FormHelper::inputDefaults(). Changer les options par dfaut vous permet de consolider
les options rptes dans un appel une unique mthode :
$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() :

134

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->input('password'); // Pas de div, pas de label avec la classe 'fancy'


echo $this->Form->input('username', array('label' => 'Username')); // a un lment label av

Travailler avec le Component Scurity

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');

FormHelper::secure(array $fields = array())


Gnre un champ cach avec hachage sur le champ utilis dans le formulaire.
Mises jour 2.0

$selected parameter removed


Le
paramtre
$selecteda t retir de plusieurs mthodes du Helper
Form (FormHelper). Toutes les mthodes supportent dsormais un cl
$attributes[value] qui devra tre utilise en remplacement de $selected. Ce changement
simplifie les mthodes du Helper Form, en rduisant le nombre darguments, et rduit les duplications que
$selected cre. Les mthodes sont :
FormHelper : :select()
FormHelper : :dateTime()
FormHelper : :year()
FormHelper : :month()
FormHelper : :day()
FormHelper : :hour()
FormHelper : :minute()
FormHelper : :meridian()
LURL par dfaut des formulaires est laction courante
LURL par dfaut pour tous les formulaires, est dsormais lURL courante incluant passed, named, et les
paramtres de la requte (querystring parameters). Vous pouvez redfinir cette valeur par dfaut en fournissant $options[url] dans le second paramtre de $this->Form->create().
FormHelper : :hidden()

En savoir plus sur les vues

135

CakePHP Cookbook Documentation, Version 2.x

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.

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 :
echo $this->Html->charset('ISO-8859-1');

136

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />

HtmlHelper::css(mixed $path, array $options = array())


Modifi dans la version 2.4.
Paramtres
$path (mixed) Soit une chane du fichier CSS lier, ou un tableau avec plusieurs
fichiers.
$options (array) Un tableau doptions ou d attributs html.
Cr un ou plusieurs lien(s) vers un feuille de style CSS. Si la cl inline est dfinie false dans les
paramtres $options, les balises de lien seront ajouts au bloc css lequel sera intgr la balise
entte du document.
Vous pouvez utiliser loption block pour contrler sur lequel des blocs llment li sera ajout. Par
dfaut il sera ajout au bloc css.
Si la cl rel dans le tableau $options est dfini pour import, la feuille de style sera importe.
Cette mthode dinclusion CSS prsume que le CSS spcifi se trouve dans le rpertoire
/app/webroot/css si un chemin ne commence par un /.
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

echo $this->Html->css(Blog.common.css, array(plugin => false)) ;


Modifi dans la version 2.1 : Loption block a t ajoute. Le support de syntaxe de plugin t
ajout.
HtmlHelper::meta(string $type, string $url = null, array $options = array())
En savoir plus sur les vues

137

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

?>
// 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 : Loption block a t ajoute.


HtmlHelper::docType(string $type = xhtml-strict)
Paramtres
$type (string) Le type de doctype fabriqu.
Retourne un balise doctype (X)HTML. Fournissez le doctype en suivant la table suivante :
type
valeur rsultante
html4-strict
HTML4 Strict
html4-trans
HTML4 Transitional
html4-frame HTML4 Frameset
html5
HTML5
xhtml-strict
XHTML1 Strict
xhtml-trans
XHTML1 Transitional
xhtml-frame XHTML1 Frameset
xhtml11
XHTML1.1
echo $this->Html->docType();
// Sortie:
// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
//
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
echo $this->Html->docType('html5');
// Sortie: <!DOCTYPE html>
echo $this->Html->docType('html4-trans');
// Sortie:
// <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
//
"http://www.w3.org/TR/html4/loose.dtd">

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.

En savoir plus sur les vues

139

CakePHP Cookbook Documentation, Version 2.x

$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;

HtmlHelper::image(string $path, array $options = array())


param string $path Chemin de limage.
param array $options Un tableau de attributs html.
Cr une balise image formate. Le chemin fournit devra tre relatif /app/webroot/img/.
echo $this->Html->image('cake_logo.png', array('alt' => 'CakePHP'));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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));

Modifi dans la version 2.1 : Loption fullBase a t ajout. Le support de syntaxe de


plugin a t ajout.
HtmlHelper::link(string $title, mixed $url = null, array $options = array())
Paramtres
$title (string) Le texte afficher comme corps du lien.
$url (mixed) Soit la chane spcifiant le chemin, ou un tableau de routing.
$options (array) Un tableau d :attributs HTML.
Mthode gnrale pour la cration de liens HTML. Utilisez les $options pour spcifier les attributs
des lments et si le $title devra ou non tre chapp.
echo $this->Html->link(
'Enter',
'/pages/home',
array('class' => 'button', 'target' => '_blank')
);

Affichera :
<a href="/pages/home" class="button" target="_blank">Enter</a>

Utilisez loption full_base => true pour des URLs absolues :


echo $this->Html->link(
'Dashboard',
array(
'controller' => 'dashboards',
'action' => 'index',
'full_base' => true
)
);

Affichera :
<a href="http://www.yourdomain.com/dashboards/index">Dashboard</a>

Spcifiez $confirmMessage pour afficher une boite de dialogue de confirmation confirm()


JavaScript :
echo $this->Html->link(
'Delete',
array('controller' => 'recipes', 'action' => 'delete', 6),
array(),
"Are you sure you wish to delete this recipe?"
);

Affichera :

En savoir plus sur les vues

141

CakePHP Cookbook Documentation, Version 2.x

<a href="/recipes/delete/6" onclick="return confirm('Are you sure you wish to delete t

Les chanes de requte peuvent aussi tre cres avec link().


echo $this->Html->link('View image', array(
'controller' => 'images',
'action' => 'view',
1,
'?' => array('height' => 400, 'width' => 500))
);

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<?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 &quot;howdy&quot;">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>

Modifi dans la version 2.4 : Loption escapeTitle a t ajoute.


Modifi dans la version 2.6 : Largument $confirmMessage a t dprcie. Utilisez la cl
confirm dans $options la place.
Regardez aussi la mthode HtmlHelper::url pour plus dexemples des diffrents types dURLs.
HtmlHelper::media(string|array $path, array $options)
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(

En savoir plus sur les vues

143

CakePHP Cookbook Documentation, Version 2.x

'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>

HtmlHelper::tag(string $tag, string $text, array $htmlAttributes)


Paramtres
$tag (string) Le nom de la balise cre.
$text (string) Le contenu de la balise.
$options (array) Un tableau dattributs html attributs html.
Retourne des textes envelopps dans une balise spcifie. Si il ny a pas de texte spcifi alors le
contenu du <tag> sera retourn :
.. code-block:: php

< ?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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<?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>

HtmlHelper::para(string $class, string $text, array $options)


Paramtres
$class (string) Le nom de classe du paragraphe.
$text (string) Le contenu du paragraphe.
$options (array) Un tableau dattributs attributs html.
Retourne un texte envelopp dans une balise CSS <p>. Si aucun texte CSS est fourni, un simple <p>
de dmarrage est retourn. :
<?php
echo $this->Html->para(null, 'Bonjour le Monde');
?>
// Affichera
<p>Bonjour le Monde</p>

HtmlHelper::script(mixed $url, mixed $options)


Paramtres
$url (mixed) Soit un simple fichier Javascript, ou un tableau de chanes pour
plusieurs fichiers.
$options (array) Un tableau dattributs attributs html.
Inclus un(des) fichier(s), prsent soit localement soit une URL distante.
Par dfaut, les tags de script sont ajouts au document inline. Si vous le surcharger en configurant
$options[inline] false, les tags de script vont plutt tre ajouts au block script que
vous pouvez afficher aileurs dans le document. Si vous souhaitez surcharger le nom du block utilis,
vous pouvez le faire en configurant $options[block].
$options[once] contrle si vous voulez ou pas inclure le script une fois par requte. Par dfaut
true.
Vous pouvez utiliser $options pour dfinir des proprits supplmentaires pour la balise script gnre.
Si un tableau de balise script est utilis, les attributs seront appliqus toutes les balises script
gnres.
Cette mthode dinclusion de fichier JavaScript suppose que les fichiers JavaScript spcifis se trouvent dans le rpertoire /app/webroot/js.
echo $this->Html->script('scripts');

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 :

En savoir plus sur les vues

145

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->script('/autrerep/fichier_script');

Vous pouvez aussi lier une URL dun dpt distant :


echo $this->Html->script('http://code.jquery.com/jquery.min.js');

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$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.
$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>

En savoir plus sur les vues

147

CakePHP Cookbook Documentation, Version 2.x

</li>
<li>Spanish</li>
<li>German</li>
</ul>
</li>
</ul>

HtmlHelper::tableHeaders(array $names, array $trOptions = null, array $thOptions =


null)
Paramtres
$names (array) Un tableau de chane pour crer les enttes de tableau.
$trOptions (array) Un tableau d attributs HTML pour le <tr>.
$thOptions (array) Un tableau d attributs HTML pour llment <th>.
Cr une ligne de cellule den-tte placer dans la balise <table>.
echo $this->Html->tableHeaders(array('Date', 'Title', 'Active'));

// 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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<tr>
<th>id</th>
<th class="highlight">Name</th>
<th class="sortable">Date</th>
</tr>

HtmlHelper::tableCells(array $data, array $oddTrOptions = null, array $evenTrOptions =


null, $useCount = false, $continueOddEven = true)
Paramtres
$data (array) Un tableau deux dimensions avec les donnes pour les lignes.
$oddTrOptions (array) Un tableau d attributs HTML pour les <tr> impairs.
$evenTrOptions (array) Un tableau d attributs HTML pour les <tr> pairs.
$useCount (boolean) Ajoute la classe column-$i.
$continueOddEven (boolean) Si false, utilisera une variable $count nonstatique, ainsi le compteur impair/pair est remis zro juste pour cet appel.
Cr des cellules de table, en assignant aux lignes des attributs <tr> diffrents pour les lignes paires
et les lignes impaires. Entoure une simple table de cellule dans un array() pour des attributs <td>
spcifiques.
echo $this->Html->tableCells(array(
array('Jul 7th, 2007', 'Best Brownies', 'Yes'),
array('Jun 21st, 2007', 'Smart Cookies', 'Yes'),
array('Aug 1st, 2006', 'Anti-Java Cake', 'No'),
));

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')
);

En savoir plus sur les vues

149

CakePHP Cookbook Documentation, Version 2.x

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>

HtmlHelper::url(mixed $url = NULL, boolean $full = false)


Paramtres
$url (mixed) Un tableau de routing.
$full (mixed) Soit un boolen sil faut ou pas que la base du chemin soit incluse
ou un tableau doptions pour le router Router::url().
Retourne une URL pointant vers une combinaison controller et action. Si $url est vide, cela retourne
la REQUEST_URI, sinon cela gnre la combinaison dune URL pour le controller et dune action.
Si full est true, la base complte de lURL sera ajoute en amont du rsultat :
echo $this->Html->url(array(
"controller" => "posts",
"action" => "view",
"bar"
));
// Restituera
/posts/view/bar

Voici quelques exemples supplmentaires :


URL avec des paramtres nomms :
echo $this->Html->url(array(
"controller" => "posts",
"action" => "view",
"foo" => "bar"
));
// Restituera
/posts/view/foo:bar

URL avec une extension :


echo $this->Html->url(array(
"controller" => "posts",
"action" => "list",
"ext" => "rss"
));
// Restituera
/posts/list.rss

URL (commenant par /) avec la base complte dURL ajoute :


echo $this->Html->url('/posts', true);
// Restituera
http://somedomain.com/posts

150

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

URL avec des paramtres GET et une ancre nomme :


<?php echo $this->Html->url(array(
"controller" => "posts",
"action" => "search",
"?" => array("foo" => "bar"),
"#" => "first"));
// Restituera
/posts/search?foo=bar#first

Pour plus dinformation voir Router : :url 3 dans l API.


HtmlHelper::useTag(string $tag)
Retourne un bloc existant format de balise $tag :
$this->Html->useTag(
'form',
'http://example.com',
array('method' => 'post', 'class' => 'myform')
);

Output :
<form action="http://example.com" method="post" class="myform">

Changer la restitution des balises avec le Helper Html

HtmlHelper::loadConfig(mixed $configFile, string $path = null)


Les jeux de balises pour le Helper Html HtmlHelper sont conformes au standard XHTML, toutefois
si vous avez besoin de gnrer du HTML pour les standards HTML5 vous aurez besoin de crer et de
charger un nouveau fichier de configuration de balise contenant les balises que vous aimeriez utiliser.
Pour changer les balises utilises, crez un fichier app/Config/html5_tags.php contenant :
$config = array('tags' => array(
'css' => '<link rel="%s" href="%s" %s>',
'style' => '<style%s>%s</style>',
'charset' => '<meta charset="%s">',
'javascriptblock' => '<script%s>%s</script>',
'javascriptstart' => '<script>',
'javascriptlink' => '<script src="%s"%s></script>',
// ...
));

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

En savoir plus sur les vues

151

CakePHP Cookbook Documentation, Version 2.x

Cration dun chemin de navigation avec le Helper Html

HtmlHelper::getCrumbs(string $separator = &raquo ;, string|array|bool $startText =


false)
CakePHP inclut la possibilit de crer automatiquement un chemin de navigation (fil dAriane) dans
votre application. Pour mettre cela en service, ajouter cela dans votre template de layout :
echo $this->Html->getCrumbs(' > ', 'Home');

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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).

En savoir plus sur les vues

153

CakePHP Cookbook Documentation, Version 2.x

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'
);

Avertissement : Assurez-vous de dclarer le Helper Js et son moteur en haut du tableau $helpers


dans votre controller.
Le moteur JavaScript slctionn peut disparatre (remplac par celui par dfaut) de lobjet JsHelper dans
votre helper, si vous oubliez de faire cela et vous obtiendrez du code qui ne correspond pas votre librairie
JavaScript.
Cration dun moteur Javascript

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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)

En savoir plus sur les vues

155

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$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
});

JsHelper::request($url, $options = array())


Gnre un morceau de code Javascript pour crer une requte XmlHttpRequest ou AJAX.
Options de lvnement
complete - Callback lancer si complt.
success - Callback lancer en cas de succs.
before - Callback lancer linitialisation de la requte.
error - Callback lancer en cas derreur de requte.
Options
method - La mthode pour fabriquer la requte avec GET dans plus de librairies.
En savoir plus sur les vues

157

CakePHP Cookbook Documentation, Version 2.x

async - Sil faut ou pas utiliser une requte asynchrone.


data - Donnes additionnelles envoyer.
update - LID du Dom id mettre jour avec le contenu de la requte.
type - Le Type des donnes de la rponse.json et html sont supports. Par dfaut html pour la
plupart des librairies.
evalScripts - sil faut ou pas valuer la balise <script>.
dataExpression -Si la clef data doit tre traite comme un callback. Utile pour fournir
$options[data] comme une autre expression Javascript.
Exemple dutilisation :
$this->Js->event(
'click',
$this->Js->request(
array('action' => 'foo', 'param1'),
array('async' => true, 'update' => '#element')
)
);

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

'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
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.

En savoir plus sur les vues

159

CakePHP Cookbook Documentation, Version 2.x

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
});

JsHelper::effect($name, $options = array())


Cr un effet basique. Par dfaut cette mthode nest pas bufferise et retourne ses rsultats.
noms des effets supports
Les effets suivants sont supports par tous les moteurs JS :
show - rvle un lment.
hide - dissimule un lment.
fadeIn - Fade in un lment.
fadeOut - Fade out un lment.
slideIn - Slide un lment in.
slideOut - Slide un lment out.
Options
speed - Vitesse laquelle lanimation devrait se produire. Les valeurs acceptes sont slow, fast.
Tous les effets nutilisent pas loption speed.

160

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

Exemple dutilisation
Si vous utilisez le moteur jQuery :
$this->Js->get('#element');
$result = $this->Js->effect('fadeIn');
// $result contient $("#foo").fadeIn();

JsHelper::event($type, $content, $options = array())


Attache un vnement la slection courante. $type peut tre un vnement DOM normal ou un type
dvnement personnalis si votre librairie les supporte. $content devrait contenir les fonctions du
body pour le callback. Les Callbacks seront envelopps avec la fonction function (event) {
... } moins quils ne soient dsactivs avec $options.
Options
wrap - Si vous souhaitez que le callback soit envelopp dans une fonction anonyme. (par dfaut
true)
stop - Si vous souhaitez que lvnement sarrte. (par dfaut true)
Exemple dutilisation :
$this->Js->get('#some-link');
$this->Js->event('click', $this->Js->alert('saperlipopette!'));

Si vous employiez la librairie jQuery, vous devriez avoir le code suivant :


$('#some-link').bind('click', function (event) {
alert(saperlipopette!');
return false;
});

Vous pouvez retirer le return false; en passant loption stop false :


$this->Js->get('#some-link');
$this->Js->event(
'click',
$this->Js->alert('saperlipopette!'),
array('stop' => false)
);

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

CakePHP Cookbook Documentation, Version 2.x

$this->Js->get('div.message');
$this->Js->each('$(this).css({color: "red"});');

Lutilisation du moteur jQuery aurait cr le Javascript suivant :


$('div.message').each(function () { $(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');

JsHelper::submit($caption = null, $options = array())


Cr un bouton submit qui permet les formulaires de soumission XmlHttpRequest. Les options peuvent inclure soit celles de FormHelper::submit() et JsBaseEngine : :request(), JsBaseEngine : :event() ;
La soumission a travers un formulaire avec cette mthode, ne permet pas lenvoi de fichiers. Les
fichiers ne se transferts pas travers XmlHttpRequest et requirent un iframe, ou dautres paramtrages plus spcialiss qui sont hors de porte de cet helper.
Options
confirm - Message de confirmation affich avant lenvoi de la requte. Lutilisation de confirm ,
ne remplace pas les mthodes de callback before dans le XmlHttpRequest gnr.
buffer - Dsactive le buffering et retourne une balise script en plus du lien.
wrapCallbacks - Mis false pour dsactiver lenveloppement automatique des callbacks.
Exemple dutilisation :
echo $this->Js->submit('Save', array('update' => '#content'));

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

Montre comment vous pouvez combiner les options de FormHelper::submit() et Helper


Js::request() lutilisation des submits.
JsHelper::link($title, $url = null, $options = array())
Cr un lment ancre HTML qui a un vnement clic rattach. Les options peuvent inclure
celle pour HtmlHelper::link() et Helper Js::request(), Helper Js::event(),
$options est un tableau dattribut attributs html qui sont ajouts llment ancre gnr. Si une
option ne fait pas parti des attributs standard de $htmlAttributes elle sera passe Helper
Js::request() comme une option. Si une Id nest pas fournie, une valeur alatoire sera cre
pour chacun des liens gnrs.
Options
confirm - Gnre une boite de dialogue de confirmation avant lenvoi de lvnement.
id - utilise une id personnalise .
htmlAttributes - attributs HTML non standard supplmentaires. Les attributs standards sont
class, id, rel, title, escape, onblur et onfocus.
buffer - Dsactive le buffering et retourne une balise script en plus du lien.
Exemple dutilisation :
echo $this->Js->link(
'Page 2',
array('page' => 2),
array('update' => '#content')
);

Va cr un lien pointant vers /page:2 et mettre jour #content avec la rponse.


Vous pouvez utiliser les options de htmlAttributes pour ajouter des attributs personnaliss.
echo $this->Js->link('Page 2', array('page' => 2), array(
'update' => '#content',
'htmlAttributes' => array('other' => 'value')
));
// Cr le HTML suivant
<a href="/posts/index/page:2" other="value">Page 2</a>

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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())

En savoir plus sur les vues

165

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.

// appel par NumberHelper


$this->Number->addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals'

// appel par CakeNumber


App::uses('CakeNumber', 'Utility');
CakeNumber::addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals' =>

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

NumberHelper::precision(mixed $number, int $precision = 3)


Paramtres
168

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$number (float) La valeur convertir


$precision (integer) Le nombre de dcimal afficher
Cette mthode affiche un nombre avec le montant de prcision spcifi (place de la dcimal). Elle
arrondira afin de maintenir le niveau de prcision dfini.
// appel avec NumberHelper
echo $this->Number->precision(456.91873645, 2 );
// Sortie
456.92
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::precision(456.91873645, 2 );

NumberHelper::toPercentage(mixed $number, int $precision = 2, array $options = array())


Paramtres
$number (float) La valeur convertir.
$precision (integer) Le nombre de dcimal afficher.
$options (array) Options, voir ci-dessous.
OpDescription
tion
multiBoolen pour indiquer si la valeur doit tre multiplie par 100. Utile pour les
ply
pourcentages avec dcimal.
Comme precision(), cette mthode formate un nombre selon la prcision fournie (o les nombres sont
arrondis pour parvenir ce degr de prcision). Cette mthode exprime aussi le nombre en tant que
pourcentage et prfixe la sortie avec un signe de pourcent.
// appel avec NumberHelper. Sortie: 45.69%
echo $this->Number->toPercentage(45.691873645);
// appel avec CakeNumber. Sortie: 45.69%
App::uses('CakeNumber', 'Utility');
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)
En savoir plus sur les vues

169

CakePHP Cookbook Documentation, Version 2.x

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

NumberHelper::format(mixed $number, mixed $options=false)


Cette mthode vous donne beaucoup plus de contrle sur le formatage des nombres pour lutilisation
dans vos vues (et est utilise en tant que mthode principale par la plupart des autres mthodes de
NumberHelper). Lutilisation de cette mthode pourrait ressembler cela :
// appel avec NumberHelper
$this->Number->format($number, $options);
// appel avec CakeNumber
CakeNumber::format($number, $options);

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

));
// 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'

NumberHelper::formatDelta(mixed $number, mixed $options=array())


Cette mthode affiche les diffrences en valeur comme un nombre sign :
// appel avec NumberHelper
$this->Number->formatDelta($number, $options);
// appel avec CakeNumber
CakeNumber::formatDelta($number, $options);

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'

Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.

En savoir plus sur les vues

171

CakePHP Cookbook Documentation, Version 2.x

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

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.
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 :

172

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<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));

PaginatorHelper::sortDir(string $model = null, mixed $options = array())


rcupre la direction courante du tri du jeu denregistrement.
PaginatorHelper::sortKey(string $model = null, mixed $options = array())
rcupre la cl courante selon laquelle le jeu denregistrement est tri.
Cration des liens de page numrots

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.

En savoir plus sur les vues

173

CakePHP Cookbook Documentation, Version 2.x

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
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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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>

Si il ny avait pas de page prcdente vous obtenez :


<span class="prev disabled"><< previous</span>

Vous pouvez changer la balise enveloppante en utilisant loption tag


echo $this->Paginator->prev(__('previous'), array('tag' => 'li'));

Sortie :
<li class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
</li>

Vous pouvez aussi dsactiver la balise enroulante :


echo $this->Paginator->prev(__('previous'), array('tag' => false));

Output :
<a class="prev" rel="prev"
href="/posts/index/page:1/sort:title/order:desc">
previous
</a>

Modifi dans la version 2.3 : Pour les mthodes : PaginatorHelper::prev() et


PaginatorHelper::next(), il est maintenant possible de dfinir loption tag false pour
dsactiver le wrapper. Les nouvelles options disabledTag ont t ajoutes.
Si vous laissez vide $disabledOptions, le paramtre $options sera utilis. Vous pouvez enregistrer
dautres saisies si les deux groupes doptions sont les mmes.
PaginatorHelper::next($title = Next >>, $options = array(), $disabledTitle = null, $disabledOptions = array())
Cette mthode est identique a prev() avec quelques exceptions. il cr le lien pointant vers la page
suivante au lieu de la prcdente. elle utilise aussi next comme valeur dattribut rel au lieu de prev.

En savoir plus sur les vues

175

CakePHP Cookbook Documentation, Version 2.x

PaginatorHelper::first($first = << first, $options = array())


Retourne une premire ou un nombre pour les premires pages. Si une chane est fournie, alors un
lien vers la premire page avec le texte fourni sera cr :
echo $this->Paginator->first('< first');

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::hasNext(string $model = null)


Retourne true si le rsultat fourni nest pas sur la dernire page.
PaginatorHelper::hasPrev(string $model = null)
Retourne true si le rsultat fourni nest pas sur la premire page.
PaginatorHelper::hasPage(string $model = null, integer $page = 1)
Retourne true si lensemble de rsultats fourni a le numro de page fourni par $page.
Cration dun compteur de page

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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}'
);

En dfinissant format range donnerait en sortie 1 - 3 of 13 :


echo $this->Paginator->counter(array(
'format' => 'range'
));

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

CakePHP Cookbook Documentation, Version 2.x

$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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 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>

Les liens en retour de la mthode sort() du PaginatorHelper permettent au utilisateurs de cliquer


sur les enttes de table pour faire basculer lordre de tri des donnes dun champ donn.
Il est aussi possible de trier une colonne base sur des associations :
<table>
<tr>
<th><?php echo $this->Paginator->sort('titre', 'Titre'); ?></th>
<th><?php echo $this->Paginator->sort('Auteur.nom', 'Auteur'); ?></th>
</tr>
<?php foreach ($data as $recette): ?>
<tr>
<td><?php echo h($recette['Recette']['titre']); ?> </td>
<td><?php echo h($recette['Auteur']['nom']); ?> </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

En savoir plus sur les vues

179

CakePHP Cookbook Documentation, Version 2.x

// 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

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'));

Si cr dans la vue de /posts/index,


/posts/index/page :5/sort :title/direction :desc.

cela

crerait

un

lien

pointant

vers

PaginatorHelper::url($options = array(), $asArray = false, $model = null)


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 :

180

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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
)
*/

PaginatorHelper::param(string $key, string $model = null)


Rcupre le paramtre de pagination spcifique partir de lensemble de rsultats pour le model
donn :
debug($this->Paginator->param('count'));
/*
(int)43
*/

Introduit dans la version 2.4 : La mthode param() a t ajoute dans 2.4.


PaginatorHelper::meta(array $options = array())
Gnre le meta-links pour un rsultat pagin :
echo $this->Paginator->meta(); // Example output for page 5
/*
<link href="/?page=4" rel="prev" /><link href="/?page=6" rel="next" />
*/

Vous pouvez galement ajouter la gnration de la fcontion meta un block nomm :


$this->Paginator->meta(array('block' => true));

Si true est envoy, le block meta est utilis.


Introduit dans la version 2.6 : La mthode meta() a t ajoute dans 2.6.
RSS
class RssHelper(View $view, array $settings = array())
En savoir plus sur les vues

181

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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'));

En savoir plus sur les vues

183

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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.

API de Rss Helper

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

CakePHP Cookbook Documentation, Version 2.x

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')
);

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 :
echo $this->Session->flash();

Ce qui est au-dessus sortira un message simple, avec le HTML suivant :


<div id="flashMessage" class="message">
Vos trucs on t sauvegards.
</div>

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'));

Ceci utilise View/Elements/failure.ctp pour rendre le message. Le message texte sera


disponible dans une variable $message dans llment.
A lintrieur du fichier lment dchec, il y aura quelque chose comme ceci :
<div class="flash flash-failure">
<?php echo $message ?>
</div>

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'
));

En savoir plus sur les vues

187

CakePHP Cookbook Documentation, Version 2.x

// 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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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>

Introduit dans la version 2.4.


TextHelper::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>')
);

En savoir plus sur les vues

189

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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
)

Introduit dans la version 2.3.


Exemple :
$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

TextHelper::excerpt(string $haystack, string $needle, integer $radius=100, string $ending=...)


Paramtres
En savoir plus sur les vues

191

CakePHP Cookbook Documentation, Version 2.x

$haystack (string) La chane chercher.


$needle (string) La chane to excerpt around.
$radius (int) Le nombre de caractres de chaque ct de $needle que vous
souhaitez inclure.
$ending (string) Le Texte ajouter/prfixer au dbut ou la fin du rsultat.
Extrait un excerpt de $haystack surrounding the $needle avec un nombre de caractres de
chaque ct dtermin par $radius, et prefix/suffix with $ending. Cette mthode est spcialement pratique pour les rsultats recherchs. La chane requte ou les mots cls peuvent tre montrs
dans le document rsultant.
// appel avec TextHelper
echo $this->Text->excerpt($lastParagraph, 'method', 50, '...');
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::excerpt($lastParagraph, 'method', 50, '...');

Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...

TextHelper::toList(array $list, $and=and)


Paramtres
$list (array) Tableau dlments combiner dans une list sentence.
$and (string) Le mot utilis pour le dernier join.
Cre une liste spare avec des virgules, o les deux derniers items sont joins avec and.
// appel avec TextHelper
echo $this->Text->toList($colors);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::toList($colors);

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

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'));

Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset


utilis dans 2.1 et suivants.
TimeHelper::convertSpecifiers($format, $time = NULL)
Type retourn string
Convertit une chane de caractres reprsentant le format pour la fonction strftime et retourne un
format Windows safe et i18n aware.
TimeHelper::dayAsSql($dateString, $field_name, $timezone = NULL)
En savoir plus sur les vues

193

CakePHP Cookbook Documentation, Version 2.x

Type retourn string


Cre une chane de caractres dans le mme format que dayAsSql mais ncessite seulement un unique
objet date :
// Appel avec TimeHelper
echo $this->Time->dayAsSql('Aug 22, 2011', 'modified');
// (modified >= '2011-08-22 00:00:00') AND
// (modified <= '2011-08-22 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::dayAsSql('Aug 22, 2011', 'modified');

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::daysAsSql($begin, $end, $fieldName, $userOffset = NULL)
Type retourn string
Retourne une chane de caractres dans le format ($field_name >= 2008-01-21 00 :00 :00) AND
($field_name <= 2008-01-25 23 :59 :59). Cest pratique si vous avez besoin de chercher des enregistrements entre deux dates incluses :
// Appel avec TimeHelper
echo $this->Time->daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');
// (created >= '2011-08-22 00:00:00') AND
// (created <= '2011-08-25 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

// 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.
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');

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::gmt($dateString = NULL)
Type retourn integer
Va retourner la date en un nombre dfini sur Greenwich Mean Time (GMT).
// Appel avec TimeHelper
echo $this->Time->gmt('Aug 22, 2011');
// 1313971200
6. http ://us.php.net/manual/en/function.date.php

En savoir plus sur les vues

195

CakePHP Cookbook Documentation, Version 2.x

// Appel avec CakeTime


App::uses('CakeTime', 'Utility');
echo CakeTime::gmt('Aug 22, 2011');

TimeHelper::i18nFormat($date, $format = NULL, $invalid = false, $timezone = NULL)


Type retourn string
Retourne une chane de date formate, tant donn soit un timestamp UNIX soit une chane de date
valide strtotime(). Il prend en compte le format de la date par dfaut pour le langage courant si un
fichier LC_TIME est utilis. Pour plus dinfos sur le fichier LC_TIME, allez voir ici
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
TimeHelper::nice($dateString = NULL, $timezone = NULL, $format = null)
Type retourn string
Prend une chane de date et la sort au format Tue, Jan 1st 2008, 19 :25 ou avec le param optionnel
$format :
// Appel avec TimeHelper
echo $this->Time->nice('2011-08-22 11:53:00');
// Mon, Aug 22nd 2011, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::nice('2011-08-22 11:53:00');

TimeHelper::niceShort($dateString = NULL, $timezone = NULL)


Type retourn string
Prend une chane de date et la sort au format Jan 1st 2008, 19 :25. Si lobjet date est today, le format
sera Today, 19 :25. Si lobjet date est yesterday, le format sera Yesterday, 19 :25 :
// Appel avec TimeHelper
echo $this->Time->niceShort('2011-08-22 11:53:00');
// Aug 22nd, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::niceShort('2011-08-22 11:53:00');

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::serverOffset()
Type retourn integer
Retourne la valeur du serveur partir du GMT dans les secondes.
TimeHelper::timeAgoInWords($dateString, $options = array())
Type retourn string
196

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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'

Modifi dans la version 2.2 : Loption accuracy a t ajoute.


Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toAtom($dateString, $timezone = NULL)
Type retourn string
En savoir plus sur les vues

197

CakePHP Cookbook Documentation, Version 2.x

Va retourner une chane de date au format Atom 2008-01-12T00 :00 :00Z


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::toQuarter($dateString, $range = false)
Type retourn mixed
Va retourner 1, 2, 3 ou 4 dpendant du quart de lanne sur lequel la date tombe. Si range est dfini
true, un tableau deux lments va tre retourn avec les dates de dbut et de fin au format 2008-0331 :
// Appel avec TimeHelper
echo $this->Time->toQuarter('Aug 22, 2011');
// Afficherait 3
$arr = $this->Time->toQuarter('Aug 22, 2011', true);
/*
Array
(
[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.
198

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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>.
Tester Time

TimeHelper::isToday($dateString, $timezone = NULL)


TimeHelper::isThisWeek($dateString, $timezone = NULL)
TimeHelper::isThisMonth($dateString, $timezone = NULL)
TimeHelper::isThisYear($dateString, $timezone = NULL)
TimeHelper::wasYesterday($dateString, $timezone = NULL)
TimeHelper::isTomorrow($dateString, $timezone = NULL)
TimeHelper::isFuture($dateString, $timezone = NULL)
Introduit dans la version 2.4.
TimeHelper::isPast($dateString, $timezone = NULL)
Introduit dans la version 2.4.
TimeHelper::wasWithinLast($timeInterval, $dateString, $timezone = NULL)
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.
Toutes les fonctions ci-dessus retourneront true ou false quand une chane de date est pass.
wasWithinLast prend une option supplmentaire $time_interval :
// Appel avec TimeHelper
$this->Time->wasWithinLast($time_interval, $dateString);
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
CakeTime::wasWithinLast($time_interval, $dateString);

En savoir plus sur les vues

199

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

}
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();
}
}

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 :

En savoir plus sur les vues

201

CakePHP Cookbook Documentation, Version 2.x

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.

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 :

202

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

/* /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 :
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'); ?>

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.
En savoir plus sur les vues

203

CakePHP Cookbook Documentation, Version 2.x

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 5. Views (Vues)

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.

Comprendre les Models


Un Model reprsente votre model de donnes. En programmation oriente objet, un model est un objet qui
reprsente une chose, comme une voiture, une personne ou une maison. Un blog, par exemple, peut avoir
plusieurs posts et chaque post peut avoir plusieurs commentaires. Blog, Post et Commentaire sont tous des
exemples de models, chacun tant associ avec un autre.
Voici un exemple simple de dfinition de model dans CakePHP :
App::uses('AppModel', 'Model');
class Ingredient extends AppModel {
public $name = 'Ingredient';
}

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$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.

Pour en savoir plus sur les Models


Associations : Lier les models
Une des caractristiques les plus puissantes de CakePHP est sa capacit dtablir les liens ncessaires entre
les models daprs les informations fournies. Dans CakePHP, les liens entre models sont grs par des
associations.
Dfinir les relations entre diffrents objets lintrieur de votre application sera une tche naturelle. Par
exemple : dans une base de donnes de recettes, une recette peut avoir plusieurs versions, chaque version
na quun seul auteur et les auteurs peuvent avoir plusieurs recettes. Le fait de dfinir le fonctionnement de
ces relations vous permet daccder vos donnes de manire intuitive et puissante.
Le but de cette section est de vous montrer comment concevoir, dfinir et utiliser les associations entre les
models au sein de CakePHP.
Bien que les donnes peuvent tre issues dune grande varit de sources, la forme de stockage la plus
rpandue dans les applications web est la base de donnes relationnelle. La plupart de ce qui est couvert par
cette section le sera dans ce contexte.
Pour des informations sur les associations avec les models de Plugin, voyez les Models du Plugin.
Types de relations
Les quatre types dassociations dans CakePHP sont : hasOne (a un seul), hasMany (a plusieurs), belongsTo
(appartient ), et hasAndBelongsToMany (HABTM) (appartient et est compos de plusieurs).
Relation
un vers un
un vers plusieurs
plusieurs vers un
plusieurs vers
plusieurs

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

Pour en savoir plus sur les Models

207

CakePHP Cookbook Documentation, Version 2.x

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',
)
);
}

mais ce qui suit ne fonctionnera pas bien en toute circonstance :


class User extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);

208

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

public $hasAndBelongsToMany = array(


'Member' => array(
'className' => 'Group',
)
);
}
class Group extends AppModel {
public $hasMany = array(
'MyRecipe' => array(
'className' => 'Recipe',
)
);
public $hasAndBelongsToMany = array(
'Member' => array(
'className' => 'User',
)
);
}

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.

Pour en savoir plus sur les Models

209

CakePHP Cookbook Documentation, Version 2.x

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
)
);
}

Les cls possibles pour les tableaux dassociation incluent :


className : le nom de la classe du model que lon souhaite associer au model actuel. Si lon souhaite
dfinir la relation User a un Profile, la valeur associe la cl className devra tre Profile.
foreignKey : le nom de la cl trangre que lon trouve dans lautre model. Ceci sera particulirement
pratique si vous avez besoin de dfinir des relations hasOne multiples. La valeur par dfaut de cette cl
est le nom du model actuel (avec des underscores) suffix avec _id. Dans lexemple ci-dessus la valeur
par dfaut aurait t user_id.
conditions : un tableau des conditions compatibles avec find() ou un fragment de code SQL tel que
array(Profile.approved => true).
fields : une liste des champs rcuprer lorsque les donnes du model associ sont parcourues. Par dfaut,
cela retourne tous les champs.
order : Un tableau des clauses order compatible avec la fonction find() ou un fragment de code SQL tel
que array(Profile.last_name => ASC).
dependent : lorsque la valeur de la cl dependent est true et que la mthode delete() du model est
appele avec le paramtre cascade valant true galement, les enregistrements des models associs sont

210

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 :

Pour en savoir plus sur les Models

211

CakePHP Cookbook Documentation, Version 2.x

class Profile extends AppModel {


public $belongsTo = array(
'User' => array(
'className' => 'User',
'foreignKey' => 'user_id'
)
);
}

Les cls possibles pour les tableaux dassociation belongsTo incluent :


className : le nom de classe du model associ au model courant. Si vous dfinissez une relation Profile
belongsTo User, la cl du nom de classe devra tre User.
foreignKey : le nom de la cl trangre trouve dans le model courant. Cest particulirement pratique
si vous avez besoin de dfinir de multiples relations belongsTo. La valeur par dfaut pour cette cl est le
nom au singulier de lautre model avec des underscores, suffix avec _id.
conditions : un tableau de conditions compatibles find() ou de chanes SQL comme
array(User.active => true).
type : le type de join utiliser dans la requte SQL, par dfaut LEFT ce qui peut ne pas correspondre
vos besoins dans toutes les situations, INNER peut tre utile quand vous voulez tout de votre model
principal ainsi que de vos models associs ! (Utile quand utilis avec certaines conditions bien sur). (NB :
la valeur de type est en lettre minuscule - ex. left, inner)
fields : Une liste des champs retourner quand les donnes du model associ sont rcupres. Retourne
tous les champs par dfaut.
order : un tableau de clauses order qui sont compatibles avec find() ou des chanes SQL comme
array(User.username => ASC)
counterCache : Si dfini true, le Model associ va automatiquement augmenter ou diminuer le champ
[singular_model_name]_count dans la table trangre quand vous faites un save() ou un delete().
Si cest une chane alors il sagit du nom du champ utiliser. La valeur dans le champ counter reprsente le
nombre de lignes lies. Vous pouvez aussi spcifier de multiples caches counter en dfinissant un tableau,
regardez Multiple counterCache.
counterScope : Un tableau de conditions optionnelles utiliser pour la mise jour du champ du cache
counter.
Une fois que cette association a t dfinie, les oprations de find sur le model Profile vont aussi rcuprer
un enregistrement li de User si il existe :
//Exemples de rsultats d'un appel de $this->Profile->find().
Array
(
[Profile] => Array
(
[id] => 12
[user_id] => 121
[skill] => Baking Cakes
[created] => 2007-05-01 10:31:01
)
[User] => Array
(
[id] => 121
[name] => Gwoo the Kungwoo

212

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[created] => 2007-05-01 10:31:01


)
)

counterCache - Cache your count()


Cette fonction vous aide mettre en cache le count des donnes lies. Au lieu de compter les enregistrements
manuellement via find(count), le model suit lui-mme tout ajout/suppression travers le model
$hasMany associ et augmente/diminue un champ numrique ddi dans la table du model parent.
Le nom du champ est le nom du model particulier suivi par un underscore et le mot count :
my_model_count

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(

Pour en savoir plus sur les Models

213

CakePHP Cookbook Documentation, Version 2.x

'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.

Avec la configuration de votre belongsTo qui ressemblerait cela :


class Message extends AppModel {
public $belongsTo = array(
'User' => array(
'counterCache' => array(
'messages_read' => array('Message.is_read' => 1),
'messages_unread' => array('Message.is_read' => 0)
)
)
);
}

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

class User extends AppModel {


public $hasMany = 'Comment';
}

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
)
);
}

Les cls possibles pour les tableaux dassociation hasMany sont :


className : le nom de la classe du model que lon souhaite associer au model actuel. Si lon souhaite
dfinir la relation User hasMany Comment (lUser a plusieurs Comments), la valeur associe la clef
className devra tre Comment.
foreignKey : le nom de la cl trangre que lon trouve dans lautre model. Ceci sera particulirement
pratique si vous avez besoin de dfinir des relations hasMany multiples. La valeur par dfaut de cette cl
est le nom du model actuel (avec des underscores) suffix avec _id
conditions : un tableau de conditions compatibles avec find() ou des chanes SQL comme array(Comment.visible => true).
order : un tableau de clauses order compatibles avec find() ou des chanes SQL comme array(Profile.last_name => ASC).
limit : Le nombre maximum de lignes associes que vous voulez retourner.
offset : Le nombre de lignes associes enlever (tant donn les conditions et lorder courant) avant la
rcupration et lassociation.
dependent : Lorsque dependent vaut true, une suppression rcursive du model est possible. Dans cet
exemple, les enregistrements Comment seront supprims lorsque leur User associ laura t.
exclusive : Lorsque exclusive est fix true, la suppression rcursive de model effectue la suppression
avec un deleteAll() au lieu du supprimer chaque entit sparment. Cela amliore grandement la performance, mais peut ne pas tre idal dans toutes les circonstances.
finderQuery : Une requte SQL complte que CakePHP peut utiliser pour retrouver les enregistrements
associs au model. Ceci ne devrait tre utilis que dans les situations qui ncessitent des rsultats trs
personnaliss. Si une de vos requtes a besoin dune rfrence lID du model associ, utilisez le marqueur spcial {$__cakeID__$} dans la requte. Par exemple, si votre model Pomme hasMany Orange,
la requte devrait ressembler a : SELECT Orange.* from oranges as Orange WHERE
Orange.pomme_id = {$__cakeID__$};
Une fois que cette association a t dfinie, les oprations de recherche sur le model User rcupreront
galement les Comments lis si ils existent :
//Exemple de rsultats d'un appel $this->User->find().
Array

Pour en savoir plus sur les Models

215

CakePHP Cookbook Documentation, Version 2.x

(
[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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Champs de la table HABTM


ingredients_recipes.id, ingredients_recipes.ingredient_id,
ingredients_recipes.recipe_id
cakes_fans.id, cakes_fans.cake_id, cakes_fans.fan_id
bars_foos.id, bars_foos.foo_id, bars_foos.bar_id

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[user_id] => 2346


)
[Ingredient] => Array
(
[0] => Array
(
[id] => 123
[name] => Chocolate
)
[1] => Array
(
[id] => 124
[name] => Sugar
)
[2] => Array
(
[id] => 125
[name] => Bombs
)
)
)

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)

hasMany through (Le Model Join)


Il est parfois ncessaire de stocker des donnes supplmentaires avec une association many to many. Considrons ce qui suit
Student hasAndBelongsToMany Course
Course hasAndBelongsToMany Student
En dautres termes, un Student peut avoir plusieurs (many) Courses et un Course peut tre pris par plusieurs
(many) Students. Cest une association simple de many to many ncessitant une table comme ceci :
id | student_id | course_id

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 :

Pour en savoir plus sur les Models

219

CakePHP Cookbook Documentation, Version 2.x

id | student_id | course_id | days_attended | grade

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

$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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

)
)
)
);

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'

Pour en savoir plus sur les Models

223

CakePHP Cookbook Documentation, Version 2.x

)
);
public $hasMany = array(
'Children' => array(
'className' => 'Post',
'foreignKey' => 'parent_id'
)
);
}

Rcuprer un tableau imbriqu denregistrements associs :


Si votre table a un champ parent_id, vous pouvez aussi utiliser find(threaded) pour rcuprer un tableau
imbriqu denregistrements en utilisant une seule requte sans dfinir aucune association.
Tables jointes
En SQL, vous pouvez combiner des tables lies en utilisant la clause JOIN. Ceci vous permet de raliser
des recherches complexes travers des tables multiples (par ex. : rechercher les posts selon plusieurs tags
donns).
Dans CakePHP, certaines associations (belongsTo et hasOne) effectuent des jointures automatiques pour
rcuprer les donnes, vous pouvez donc lancer des requtes pour rcuprer les models bass sur les donnes
de celui qui est li.
Mais ce nest pas le cas avec les associations hasMany et hasAndBelongsToMany. Cest l que les jointures
forces viennent notre secours. Vous devez seulement dfinir les jointures ncessaires pour combiner les
tables et obtenir les rsultats dsirs pour votre requte.
Note : Souvenez-vous que vous avez besoin de dfinir la rcursivit -1 pour que cela fonctionne. Par
exemple : $this->Channel->recursive = -1 ;
Pour forcer une jointure entre tables, vous avez besoin dutiliser la syntaxe moderne de Model : :find(), en
ajoutant une cl joins au tableau $options. Par exemple :
$options['joins'] = array(
array('table' => 'channels',
'alias' => 'Channel',
'type' => 'LEFT',
'conditions' => array(
'Channel.id = Item.channel_id',
)
)
);
$Item->find('all', $options);

Note : Notez que les tableaux joins ne sont pas indexs.

224

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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);

Au besoin, vous pourriez raliser plusieurs jointures dans une hasAndBelongsToMany :


Supposez une association Book hasAndBelongsToMany Tag. Cette relation utilise une table books_tags
comme table de jointure, donc vous avez besoin de joindre la table books la table books_tags et celle-ci
avec la table tags :
$options['joins'] = array(
array('table' => 'books_tags',
'alias' => 'BooksTag',
'type' => 'inner',
'conditions' => array(
'Book.id = BooksTag.book_id'
)
),
array('table' => 'tags',
'alias' => 'Tag',
'type' => 'inner',
'conditions' => array(
'BooksTag.tag_id = Tag.id'
)
)
);
$options['conditions'] = array(
'Tag.tag' => 'Novel'
);
$books = $Book->find('all', $options);

Pour en savoir plus sur les Models

225

CakePHP Cookbook Documentation, Version 2.x

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.

Rcuprer vos donnes


Comme mentionn prcdemment, un des rles de la couche Model est dobtenir les donnes partir de
plusieurs types de stockage. La classe Model de CakePHP est livre avec quelques fonctions qui vous aident
chercher ces donnes, les trier, les paginer, et les filtrer. La fonction la plus courante que vous utiliserez
dans les models est Model::find().
find
find(string $type = first, array $params = array())
Find est, parmi toutes les fonctions de rcupration de donnes des models, une vritable bte de
somme multi-fonctionnelle. $type peut tre all, first, count, list, neighbors,
threaded, ou tout autre fonction de recherche que vous dfinissez. Gardez lesprit que $type est
sensible la casse. Utiliser un caractre majuscule (par exemple All) ne produira pas le rsultat attendu.
$params est utilise pour passer tous les paramtres aux diffrentes formes de find et il a les cls suivantes
disponibles par dfaut - qui sont toutes optionnelles :
array(
//tableau de conditions
'conditions' => array('Model.field' => $cetteValeur),
'recursive' => 1, //int
//tableau de champs nomms
'fields' => array('Model.champ1', 'DISTINCT Model.champ2'),
//chane de caractre ou tableau dfinissant order
'order' => array('Model.created', 'Model.champ3 DESC'),
'group' => array('Model.champ'), //champs en GROUP BY
'limit' => n, //int
'page' => n, //int
'offset' => n, //int
//autres valeurs possibles sont false, 'before', 'after'
'callbacks' => true
)

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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(

Pour en savoir plus sur les Models

227

CakePHP Cookbook Documentation, Version 2.x

'fields' => 'DISTINCT Article.user_id',


'conditions' => array('Article.status !=' => 'pending')
));
// ...
}

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[champ1] => valeur1


[champ2] => valeur2
[champ3] => valeur3
)
)
)

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

CakePHP Cookbook Documentation, Version 2.x

public function une_function() {


// ...
$juste_les_usernames = $this->Article->User->find('list', array(
'fields' => array('User.username')
));
$correspondanceUsername = $this->Article->User->find('list', array(
'fields' => array('User.username', 'User.first_name')
));
$groupesUsername = $this->Article->User->find('list', array(
'fields' => array('User.username', 'User.first_name', 'User.group')
));
// ...
}

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

[NomDuModelAssocie] => Array


(
[id] => 1
[champ1] => valeur1
[champ2] => valeur2
[champ3] => valeur3
)
[children] => Array
(
[0] => Array
(
[NomDuModel] =>
(
[id] => 42
[parent_id]
[champ1] =>
[champ2] =>
[champ3] =>

Pour en savoir plus sur les Models

Array

=> 83
valeur1
valeur2
valeur3

231

CakePHP Cookbook Documentation, Version 2.x

)
[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')
));
}

Sinon le tableau retourn ne sera pas de la structure imbrique attendue du dessus.

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

Crer des types de recherche personnaliss


La mthode find est assez flexible pour accepter vos recherches personnalises, ceci est fait en dclarant
vos propres types dans une variable de model et en intgrant une fonction spciale dans votre classe de
model.

Pour en savoir plus sur les Models

233

CakePHP Cookbook Documentation, Version 2.x

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));

Ci-dessous les diffrents types de find du coeur :


first
all
count
list
threaded
neighbors
Mais quen est-il des autres types ? Mettons que vous souhaitiez un finder pour tous les articles publis dans
votre base de donnes. Le premier changement que vous devez faire est dajouter votre type dans la variable
Model::$findMethods dans le model
class Article extends AppModel {
public $findMethods = array('available' =>
}

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);

protected function _findAvailable($state, $query, $results = array()) {


if ($state === 'before') {
$query['conditions']['Article.publie'] = true;
return $query;
}
return $results;
}
}

Cela vient avec lexemple suivant (code du controller) :


class ArticlesController extends AppController {
// Trouvera tous les articles publis et les ordonne en fonction de la colonne created
public function index() {
$articles = $this->Article->find('available', array(
'order' => array('created' => 'desc')
));
}
}

234

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

235

CakePHP Cookbook Documentation, Version 2.x

*
* @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);
}
}
?>

Modifi dans la version 2.2.


Vous navez plus besoin de surcharger _findCount pour rgler les problmes des count de rsultat incorrects.
Ltat before de vos finders personnaliss vous permettent maintenant dtre appels nouveaux avec
$query[operation] = count. Le $query retourn va tre utilis dans _findCount(). Si ncessaire, vous
pouvez distinguer en vrifiant pour la cl operation et retourner un $query diffrent :
protected function _findAvailable($state, $query, $results = array()) {
if ($state === 'before') {
$query['conditions']['Article.published'] = true;
if (!empty($query['operation']) && $query['operation'] === 'count') {
return $query;
}
$query['joins'] = array(
//array of required joins
);
return $query;
}
return $results;
}

236

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

Types Magiques de Recherche


Ces fonctions magiques peuvent tre utilises comme un raccourci pour rechercher dans vos tables sur un
champ prcis. Ajoutez simplement le nom du champ (au format CamelCase) la fin de ces fonctions et
fournissez le critre de recherche pour ce champ comme premier paramtre.
Les fonctions findAllBy() retourneront des rsultats dans un format comme find(all), alors que
findBy() retourne dans le mme format que find(first)
findAllBy

findAllBy<fieldName>(string $value, array $fields, array $order, int


$limit, int $page, int $recursive)
findAllBy<x> Exemple
Corresponding SQL Fragment
$this->Product->findAllByOrderStatus(3); Product.order_status = 3
$this->Recipe->findAllByType(Cookie);
Recipe.type = Cookie
$this->User->findAllByLastName(Anderson);User.last_name =
Anderson
$this->Cake->findAllById(7);
Cake.id = 7
$this->User->findAllByEmailOrUsername(jhon,jhon);
User.email = jhon OR
User.username = jhon;
$this->User->findAllByUsernameAndPassword(jhon,
User.username = jhon AND
123);
User.password = 123;
$this->User->findAllByLastName(psychic, User.last_name = psychic
array(), array(User.user_name =>
ORDER BY User.user_name
asc));
ASC
Le rsultat retourn est un tableau format un peu comme ce que donnerait find(all).
Finders Magiques Personnaliss

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

CakePHP Cookbook Documentation, Version 2.x

Les fonctions magiques findBy acceptent aussi quelques paramtres optionnels :


findBy<fieldName>(string $value[, mixed $fields[, mixed $order]]);
findBy<x> Exemple
Corresponding SQL Fragment
$this->Produit->findByOrderStatus(3);
Product.order_status = 3
$this->Recipe->findByType(Cookie); Recipe.type = Cookie
$this->User->findByLastName(Anderson);
User.last_name = Anderson;
$this->User->findByEmailOrUsername(jhon,jhon);
User.email = jhon OR
User.username = jhon;
$this->User->findByUsernameAndPassword(jhon,
User.username = jhon AND
123);
User.password = 123;
$this->Cake->findById(7);
Cake.id = 7
Les fonctions findBy() retournent des rsultats comme find(first).
Model::query()
query(string $query)
Les appels SQL que vous ne pouvez pas ou ne voulez pas faire grce aux autres mthodes de model peuvent
tre excuts en utilisant la mthode query() (bien quil y ait trs peu de circonstances o cela se vrifie).
Si vous utilisez cette mthode, assurez-vous dchapper correctement tous les paramtres en utilisant la
mthode value() sur le driver de la base de donnes. Ne pas chapper les paramtres va crer des vulnrabilits de type injection SQL.
Note : query() ne respecte pas $Model->cacheQueries car cette fonctionnalit est par nature dconnecte
de tout ce qui concerne lappel du model. Pour viter les appels au cache de requtes, fournissez un second
argument false, par exemple : query($query, $cachequeries = false).
query() utilise le nom de la table dclare dans la requte comme cl du tableau de donnes retourn,
plutt que le nom du model. Par exemple :
$this->Picture->query("SELECT * FROM pictures LIMIT 2;");

pourrait retourner :
Array
(
[0] => Array
(
[pictures] => Array
(
[id] => 1304
[user_id] => 759
)
)
[1] => Array
(
[pictures] => Array

238

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

(
[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

Pour en savoir plus sur les Models

239

CakePHP Cookbook Documentation, Version 2.x

// affiche le nom de la dernire instance cre


echo $this->Post->field(
'name',
array('created <' => date('Y-m-d H:i:s')),
'created DESC'
);

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.

Conditions de recherche complexes


La plupart des appels de recherche de models impliquent le passage dun jeu de conditions dune manire
ou dune autre. Le plus simple est dutiliser un bout de clause WHERE SQL. Si vous vous avez besoin de
plus de contrle, vous pouvez utiliser des tableaux.
Lutilisation de tableaux est plus claire et simple lire, et rend galement la construction de requtes trs
simple. Cette syntaxe spare galement les lments de votre requte (champs, valeurs, oprateurs etc.) en
parties manipulables et discrtes. Cela permet CakePHP de gnrer les requtes les plus efficaces possibles,
dassurer une syntaxe SQL correcte, et dchapper convenablement chaque partie de la requte. Utiliser une
syntaxe en tableau permet aussi CakePHP de scuriser vos requtes contre toute attaque dinjection SQL.
Avertissement : CakePHP chappe seulement les valeurs de tableau. Vous ne devriez jamais mettre les
donnes dutilisateur dans les cls. Faire ceci vous rendra vulnrable aux injections SQL.
Dans sa forme la plus simple, une requte base sur un tableau ressemble ceci :

240

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$conditions = array("Post.title" => "This is a post", "Post.author_id" => 1);


// Exemple d'utilisation avec un model:
$this->Post->find('first', array('conditions' => $conditions));

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
)

Pour en savoir plus sur les Models

241

CakePHP Cookbook Documentation, Version 2.x

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
)
)

Pour grer les requtes BETWEEN, vous pouvez utiliser ceci :


array('Post.read_count BETWEEN ? AND ?' => array(1,10))

Note : CakePHP quotera les valeurs numriques selon le type du champ dans votre base de donnes.
Quen est-il de GROUP BY ? :

242

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

array(
'fields' => array(
'Produit.type',
'MIN(Produit.prix) as prix'
),
'group' => 'Produit.type'
)

Les donnes retournes seront dans le format suivant :


Array
(
[0] => Array
(
[Produit] => Array
(
[type] => Vetement
)
[0] => Array
(
[prix] => 32
)
)
[1] => Array
...

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'))
)
)
)
)
)

Pour en savoir plus sur les Models

243

CakePHP Cookbook Documentation, Version 2.x

Qui produira la requte SQL suivante :


SELECT `Entreprise`.`id`, `Entreprise`.`nom`,
`Entreprise`.`description`, `Entreprise`.`location`,
`Entreprise`.`created`, `Entreprise`.`status`, `Entreprise`.`taille`
FROM
`entreprises` AS `Entreprise`
WHERE
((`Entreprise`.`nom` = 'Futurs Gains')
OR
(`Entreprise`.`ville` = 'CA'))
AND
((`Entreprise`.`status` = 'active')
OR (NOT (`Entreprise`.`status` IN ('inactive', 'suspendue'))))

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'));

Ceci devrait gnrer la commande SQL suivante :

244

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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')
);

Sauvegarder vos Donnes


CakePHP rend la sauvegarde des donnes dun model trs rapide. Les donnes prtes tre sauvegardes
doivent tre passes la mthode save() du model en utilisant le format basique suivant :
Array
(
[NomDuModele] => Array
(
[nomduchamp1] => 'valeur'
[nomduchamp2] => 'valeur'
)
)

Pour en savoir plus sur les Models

245

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$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())

Le tableau $params peut avoir nimporte quelle option disponible suivante en cl :


validate Dfini true/false pour activer/dsactiver la validation.
fieldList Un tableau de champs que vous souhaitez autoriser pour la sauvegarde.
callbacks Dfini false permet la dsactivation des callbacks. En utilisant before ou after activera
seulement ces callbacks.
counterCache (depuis 2.4) Boolen pour contrler la mise jour des counter caches (si il y en a).
atomic (depuis 2.6) Boolen pour indiquer que vous voulez sauvegarder les enregistrements dans une
transaction.
Plus dinformations sur les callbacks du model sont disponibles ici.
Astuce : Si vous ne voulez pas le que champ modified soit mis jour pendant la sauvegarde de certaines
donnes, ajoutez modified => false votre tableau de $data.
Une fois quune sauvegarde est termine, lID de lobjet peut tre trouv dans lattribut $id de lobjet
Model - quelque chose de spcialement pratique quand on cre de nouveaux objets.
Pour en savoir plus sur les Models

247

CakePHP Cookbook Documentation, Version 2.x

$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);

Model::create(array $data = array())


Cette mthode initialise la classe du model pour sauvegarder de nouvelles informations. Cela ne cre pas
rellement un enregistrement dans la base de donnes mais efface Model : :$id et dfinit Model : :$data bas
sur les champs par dfaut dans votre base de donnes. Si vous navez dfini aucun champ par dfaut dans
votre base de donnes, Model : :$data sera dfini comme un tableau vide.
Si le paramtre $data (utilisant le format de tableau soulign ci-dessus) est pass, il sera fusionn avec
les champs par dfaut de la base de donnes et linstance du model sera prte tre sauvegarde avec ces
donnes (accessible dans $this->data).
Si false ou null sont passs pour le paramtre $data, Model : :$data sera dfini comme un tableau
vide.
Astuce : Si vous voulez insrer une nouvelle ligne au lieu de mettre jour une ligne existante, vous devriez
toujours appeler en premier lieu create(). Cela vite les conflits avec dventuels appels save en amont
dans les callbacks ou tout autre endroit.

Model::saveField(string $fieldName, string $fieldValue, $validate =


false)
Utilise pour sauvegarder la valeur dun seul champ. Fixez lID du model ($this->ModelName->id =
$id) juste avant dappeler saveField(). Lors de lutilisation de cette mthode, $fieldName ne doit
contenir que le nom du champ, pas le nom du model et du champ.

248

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 $params peut avoir en cl, les options disponibles suivantes :


validate Dfinie true/false pour activer/dsactiver la validation.
callbacks Dfinie false pour dsactiver les callbacks. Utiliser before ou after activera seulement
ces callbacks.
counterCache (depuis 2.4) Boolen pour contrler la mise jour des counter caches (si il y en a).
Model::updateAll(array $fields, mixed $conditions)
Met jour plusieurs enregistrements en un seul appel. Les enregistrements mettre jour, ainsi quavec
leurs valeurs, sont identifis par le tableau $fields. Les enregistrements mettre jour sont identifis par
le tableau $conditions. Si largument $conditions nest pas fourni ou si il nest pas dfini true,
tous les enregistrements seront mis jour.
Par exemple, si je voulais approuver tous les bakers qui sont membres depuis plus dun an, lappel update
devrait ressembler quelque chose du style :
$thisYear = date('Y-m-d H:i:s', strtotime('-1 year'));
$this->Baker->updateAll(
array('Baker.approve' => true),
array('Baker.created <=' => $thisYear)
);

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.

Pour en savoir plus sur les Models

249

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

);
$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')),
)

Model::saveAssociated(array $data = null, array $options = array())


Mthode utilise pour sauvegarder des associations de model en une seule fois. Les options suivantes peuvent tre utilises :
validate : Dfinie false pour dsactiver la validation, true pour valider chaque enregistrement avant
sauvegarde, first pour valider tous les enregistrements avant toute sauvegarde (par dfaut).
atomic : Si true (par dfaut), va tenter 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 de Model : :save().
deep : (depuis 2.1) Si dfinie true, les donnes pas seulement associes directement vont tre sauvegardes, mais aussi les donnes associes imbriques plus profondment. Par dfaut false.
counterCache (depuis 2.4) Boolen pour contrler la mise jour des counter caches (si il y en a).
Pour sauvegarder un enregistrement et tous ses enregistrements lis avec une association hasOne ou belongsTo, le tableau de donnes devra ressembler cela :
array(
'User' => array('username' => 'billy'),
'Profile' => array('sex' => 'Male', 'occupation' => 'Programmer'),
)

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),

Pour en savoir plus sur les Models

251

CakePHP Cookbook Documentation, Version 2.x

),
);

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

Et sauvegarder cette donne avec :


$Article->saveAssociated($data, array('deep' => true));

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);

Pour en savoir plus sur les Models

253

CakePHP Cookbook Documentation, Version 2.x

// Si l\'user a t sauvegard, maintenant nous ajoutons cette information aux donn


// et sauvegardons le Profile.
if (!empty($user)) {
// L'ID de l\'user nouvellement cre a t dfini
// dans $this->User->id.
$this->request->data['Profile']['user_id'] = $this->User->id;
// Parce que notre User hasOne Profile, nous pouvons accder
// au model Profile travers le model User:
$this->User->Profile->save($this->request->data);
}
}
}

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

$this->Form->create('Company', array('action' => 'add'));


$this->Form->input('Company.name', array('label' => 'Company name'));
$this->Form->input('Company.description');
$this->Form->input('Company.location');

echo $this->Form->input('Account.0.name', array('label' => 'Account name'));


echo $this->Form->input('Account.0.username');
echo $this->Form->input('Account.0.email');
echo $this->Form->end('Add');

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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'); ?>

Pour en savoir plus sur les Models

255

CakePHP Cookbook Documentation, Version 2.x

<?php echo $this->Form->input('Course.name'); ?>


<?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(); ?>

Le tableau de donnes ressemblera ceci quand il sera soumis.


Array
(
[Student] => Array
(
[first_name] => Joe
[last_name] => Bloggs
)
[Course] => Array
(
[name] => Cake
)
[CourseMembership] => Array
(
[days_attended] => 5
[grade] => A
)
)

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[Course] => Array


(
[id] => 1
[name] => Cake
)
)
)

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

Pour en savoir plus sur les Models

257

CakePHP Cookbook Documentation, Version 2.x

(
[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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[Recipe] => Array


(
[id] => 43
)
[Tag] => Array
(
[name] => Pasta
)
)
[2] => Array
(
[Recipe] => Array
(
[id] => 51
)
[Tag] => Array
(
[name] => Mexican
)
)
[3] => Array
(
[Recipe] => Array
(
[id] => 17
)
[Tag] => Array
(
[name] => American (new)
)
)
)

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)
)
)

Pour en savoir plus sur les Models

259

CakePHP Cookbook Documentation, Version 2.x

[1] => Array


(
[Post] => Array
(
[title] => 'Dr Who's Name is Revealed'
)
[Tag] => Array
(
[Tag] => Array(7, 9, 15, 19)
)
)
[2] => Array
(
[Post] => Array
(
[title] => 'I Came, I Saw and I Conquered'
)
[Tag] => Array
(
[Tag] => Array(11, 12, 15, 19)
)
)
[3] => Array
(
[Post] => Array
(
[title] => 'Simplicity is the Ultimate Sophistication'
)
[Tag] => Array
(
[Tag] => Array(12, 22, 25, 29)
)
)
)

Passer le tableau ci-dessus la fonction saveAll($data, array(deep => true)) remplira la


table jointe posts_tags avec lassociation Tag vers Post.
Par exemple, nous allons construire un formulaire qui cre un nouveau tag et gnrerons le tableau de
donnes appropri pour lassocier la vole avec certaines recipies.
Le formulaire le plus simple ressemblerait ceci (nous supposerons que $recipe_id est dj dfinie
une valeur) :
<?php echo $this->Form->create('Tag');?>
<?php echo $this->Form->input(
'Recipe.id',
array('type' => 'hidden', 'value' => $recipe_id)); ?>
<?php echo $this->Form->input('Tag.name'); ?>
<?php echo $this->Form->end('Add Tag'); ?>

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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',
),

Pour en savoir plus sur les Models

261

CakePHP Cookbook Documentation, Version 2.x

);
}

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

Une autre faon de regarder cela est dajouter un model Membership :


Child hasMany Membership
Membership belongsTo Child, Club
Club hasMany Membership.

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

Pour en savoir plus sur les Models

263

CakePHP Cookbook Documentation, Version 2.x

Supprimer des Donnes


La classe Model de CakePHP offre de nombreuses faons de supprimer des enregistrements de votre base
de donnes.
delete
delete(integer $id = null, boolean $cascade = true);
Supprime lenregistrement identifi par $id. Par dfaut, supprime galement les enregistrements dpendants
de lenregistrement mentionn comme devant tre supprim.
Par exemple, lors de la suppression dun enregistrement User li plusieurs enregistrements Recipe (User
hasMany ou hasAndBelongsToMany Recipes) :
si $cascade est fixe true, les entres Recipe lies sont aussi supprimes si les valeurs dependant des
models sont true.
si $cascade est fixe false, les entres Recipe resteront aprs que lUser a t supprim.
Si votre base de donnes permet les cls trangres et les suppressions en cascade, il est souvent plus efficace
de les utiliser plutt que le cascade de CakePHP. Le seul bnfice pour lutilisation de la fonctionnalit de
cascade de Model::delete() est quelle vous permet dinfluencer les callbacks des behaviors et des
Models :
$this->Comment->delete($this->request->data('Comment.id'));

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

Validation des Donnes


La validation des donnes est une partie importante de toute application, puisquelle permet de sassurer que
les donnes dun model respectent les rgles mtiers de lapplication. Par exemple, vous aimeriez vrifier
que les mots de passe sont longs dau moins huit caractres ou bien vous assurer que les noms dusers sont
uniques. La dfinition des rgles de validation facilite grandement la gestion des formulaires.
Il y a de nombreux aspects diffrents dans le processus de validation. Ce que nous aborderons dans cette
section cest le ct model des choses. En rsum : ce qui se produit lorsque vous appelez la mthode save()
de votre model. Pour obtenir plus dinformations sur la manire dafficher les erreurs de validation, regardez
la section traitant des helpers FormHelper.
La premire tape pour la validation de donnes est de crer les rgles dans le Model. Pour ce faire, utilisez
le tableau Model : :validate dans la dfinition du model, par exemple :
class User extends AppModel {
public $validate = array();
}

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.

Pour en savoir plus sur les Models

265

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

Par exemple, pour sassurer que luser fournit une adresse email correcte, vous pouvez utiliser cette rgle :
public $validate = array('user_email' => 'email');

Une rgle par champ


Cette technique de dfinition permet un meilleur contrle sur le fonctionnement des rgles de validation.
Mais avant daborder ce point, regardons le schma dutilisation gnral pour ajouter une rgle un seul
champ :

public $validate = array(


'champ1' => array(
'rule'
=> 'nomRegle', // ou bien : array('nomRegle', 'parametre1', 'parametre
'required'
=> true,
'allowEmpty' => false,
'on'
=> 'create', // ou bien: 'update'
'message'
=> 'Votre message d\'erreur'
)
);

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)
)
);

Pour en savoir plus sur les Models

267

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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)

Plusieurs rgles par champ


La technique que nous venons de voir nous donne plus de flexibilit que lassignation simple de rgles, mais
il y a une tape supplmentaire que nous pouvons mettre en uvre, pour avoir un contrle encore plus fin
sur la validation des donnes. La prochaine technique que nous allons voir nous permet daffecter plusieurs
rgles de validation par champ de model.
Si vous souhaitiez affecter plusieurs rgles de validation un seul champ, voici basiquement comment il
faudrait faire :
public $validate = array(
'nomChamp' => array(
'nomRegle' => array(
'rule' => 'nomRegle',
// cls supplmentaires comme 'on', 'required', etc. mettre ici
),
'nomRegle2' => array(
'rule' => 'nomRegle2',
// cls supplmentaires comme 'on', 'required', etc. mettre ici
)
)
);

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

Pour en savoir plus sur les Models

269

CakePHP Cookbook Documentation, Version 2.x

),
'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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

Rgles personnalises de validation des donnes


Si ce qui prcde ne vous convient pas, vous pouvez toujours crer vos propres rgles de validation. Il y
a deux moyens de raliser cela : en dfinissant des expressions rgulires ou en crant des mthodes de
validation personnalises.
Validation avec Expression Rgulire personnalise

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;
}
}

Pour en savoir plus sur les Models

271

CakePHP Cookbook Documentation, Version 2.x

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 :

class Post extends AppModel {


public $validate = array(
'slug' => array(
'rule' => 'alphaNumericDashUnderscore',
'message' => 'Le slug ne peut contenir que des lettres, des nombres, des tirets
)
);

public function alphaNumericDashUnderscore($check) {


// le tableau $check est pass en utilisant le nom du champ de formulaire comme cl
// nous devons extraire la valeur pour rendre la fonction gnrique
$valeur = array_values($check);
$valeur = $valeur[0];
return preg_match('|^[0-9a-zA-Z_-]*$|', $valeur);
}
}

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

retirer dynamiquement des rgles de validation dun ensemble pr-dfini.


Toutes les rgles de validation sont stockes dans un objet ModelValidator, qui contient chaque rgle
pour chaque champ dfinie dans votre model. Dfinir de nouvelles rgles de validation est aussi facile que
de dire cet objet de stocker de nouvelles mthodes de validation pour les champs que vous souhaitez.
Ajouter de nouvelles rgles de validation

Introduit dans la version 2.2.


Les objets ModelValidator permettent de nombreuses faons dajouter de nouveaux champs dfinir.
Le premier est lutilisation de la mthode add :
// Dans une classe de model
$this->validator()->add('password', 'required', array(
'rule' => 'notBlank',
'required' => 'create'
));

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(

Pour en savoir plus sur les Models

273

CakePHP Cookbook Documentation, Version 2.x

'rule' => 'isUnique',


'required' => 'create'
),
'alphanumeric' => array(
'rule' => 'alphanumeric'
)
);

Modifier les rgles de validation courantes

Introduit dans la version 2.2.


Modifier les rgles de validation courantes est aussi possible en utilisant lobjet validator, il y a plusieurs
faons pour modifier les rgles courantes, les mthodes dajout un champ ou le retrait complet dune rgle
partir dune rgle dfinie dun champ :
// Dans une classe de model
$this->validator()->getField('password')->setRule('required', array(
'rule' => 'required',
'required' => true
));

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$validator['username']['unique']->last = true;
$validator['username']['unique']->message = 'Name already taken';

Retirer des rgles dun ensemble

Introduit dans la version 2.2.


Il est possible de retirer compltement toutes les rgles pour un champ ou de supprimer une rgle unique
dans un ensemble de rgles de champ :
// Retire compltement toutes les rgles pour un champ
$this->validator()->remove('username');
// Retire la rgle 'required' de password
$this->validator()->remove('password', 'required');

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']);

Rgles de validation incluses


class Validation
La classe de validation de CakePHP contient un certain nombre de rgles prdfinies, qui rendent la validation des donnes plus simple dans vos models. Cette classe contient de nombreuses rgles souvent utilises
que vous naurez pas r-crire vous mme. Ci-dessous vous trouverez une liste complte de toutes les
rgles, illustres par des exemples dutilisation.
static Validation::alphaNumeric(mixed $check)
Les donnes pour ce champ ne doivent contenir que chiffres et lettres :

public $validate = array(


'login' => array(
'rule' => 'alphaNumeric',
'message' => 'Les donnes pour ce champ ne doivent contenir que lettres et chi
)
);

static Validation::between(string $check, integer $min, integer $max)


La longueur des donnes du champ doit tre comprise dans la plage numrique spcifie. Les valeurs
minimum et maximum doivent tre toutes les deux fournies. Cette mthode utilise <= et non < :

Pour en savoir plus sur les Models

275

CakePHP Cookbook Documentation, Version 2.x

public $validate = array(


'mot_de_passe' => array(
'rule' => array('between', 5, 15),
'message' => 'Le mot de passe doit avoir une longueur comprise entre 5 et 15 c
)
);

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::boolean(string $check)


Les donnes pour ce champ doivent tre une valeur boolenne. Les valeurs possibles sont : true ou
false, les entiers 0 ou 1, les chanes 0 ou 1.
public $validate = array(
'maCaseACocher' => array(
'rule' => array('boolean'),
'message' => 'Valeur incorrecte pour maCaseACocher'
)
);

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 :

public $validate = array(


'numero_cc' => array(
'rule' => array('cc', array('visa', 'maestro'), false, null),
'message' => 'Le numro de carte de crdit que vous avez saisi tait invalide.
)
);

static Validation::comparison(mixed $check1, string $operator = null, integer $check2 =


null)
Comparison est utilis pour comparer des valeurs numriques. Il supporte est suprieur, est infrieur, suprieur ou gal, infrieur ou gal, gal et non gal. Quelques exemples sont
indiqus ci-dessous :
public $validate = array(
'age' => array(
'rule' => array('comparison', '>=', 18),
'message' => 'Vous devez avoir 18 ans au moins pour vous inscrire.'
)
);
public $validate = array(
'age' => array(
'rule' => array('comparison', 'greater or equal', 18),
'message' => 'Vous devez avoir 18 ans au moins pour vous inscrire.'
)
);

static Validation::custom(mixed $check, string $regex = null)


Utilis quand une rgle personnalise est ncessaire :
public $validate = array(
'infinite' => array(
'rule' => array('custom', '\u221E'),
'message' => 'Merci de rentrer un nombre infini.'
)
);

static Validation::date(string $check, mixed $format = ymd, string $regex = null)


Cette rgle sassure que les donnes soumises sont dans des formats de date valides. Un seul paramtre
(qui peut tre un tableau) doit tre pass et sera utilis pour vrifier le format de la date soumise. La
valeur de ce paramtre peut tre lune des suivantes :

Pour en savoir plus sur les Models

277

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

'message' => 'Merci de rentrer une date et un time valide.'


)
);

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)
)
);

static Validation::email(string $check, boolean $deep = false, string $regex = null)


Celle-ci vrifie que la donne est une adresse email valide. En passant un boolen true comme second
paramtre de cette rgle, elle tentera de vrifier aussi, que lhte de ladresse est valide :
public $validate = array('email' => array('rule' => 'email'));
public $validate = array(
'email' => array(
'rule' => array('email', true),
'message' => 'Merci de soumettre une adresse email valide.'
)
);

static Validation::equalTo(mixed $check, mixed $compareTo)


Cette rgle sassurera que la valeur est gale la valeur passe et quelle est du mme type.
public $validate = array(
'nourriture' => array(
'rule' => array('equalTo', 'gteau'),
'message' => 'Cette valeur devrait tre la chane gteau'
)
);

static Validation::extension(mixed $check, array $extensions = array(gif, jpeg, png,


jpg))
Cette rgle vrifie les extensions valides de fichier, comme .jpg ou .png. Permet la vrification dextensions multiples, en les passant sous forme de tableau.
public $validate = array(
'image' => array(
'rule' => array('extension', array('gif', 'jpeg', 'png', 'jpg')),
'message' => 'Merci de soumettre une image valide.'

Pour en savoir plus sur les Models

279

CakePHP Cookbook Documentation, Version 2.x

)
);

static Validation::fileSize($check, $operator = null, $size = null)


Cette rgle vous permet de vrifier les tailles de fichier. Vous pouvez utiliser $operator pour
dcider du type de comparaison que vous souhaitez utiliser. Tous les oprateurs supports par
comparison() sont ici aussi supports. Cette mthode va grer automatiquement les tableaux de
valeur partir de $_FILES en lisant la cl tmp_name si $check est un tableau qui contient cette
cl :
public $validate = array(
'image' => array(
'rule' => array('fileSize', '<=', '1MB'),
'message' => 'L\'Image doit tre infrieur 1MB'
)
);

Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3


static Validation::inList(string $check, array $list, boolean $caseInsensitive = false)
Cette rgle sassurera que la valeur est dans un ensemble donn. Elle ncessite un tableau des valeurs.
Le champ est valide si sa valeur vrifie lune des valeurs du tableau donn.
Exemple :
public $validate = array(
'fonction' => array(
'choixAutorise' => array(
'rule' => array('inList', array('Foo', 'Bar')),
'message' => 'Entrez soit Foo, soit Bar.'
)
)
);

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

'message' => 'Ce nom d\'user a dj t choisi.'


)
);

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.'
),
);

Pour en savoir plus sur les Models

281

CakePHP Cookbook Documentation, Version 2.x

static Validation::minLength(string $check, integer $min)


Cette rgle sassure que les donnes ont une obligation de longueur minimum.
public $validate = array(
'login' => array(
'rule' => array('minLength', 8),
'message' => 'Usernames must be at least 8 characters long.'
)
);

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.'
)
);

static Validation::multiple(mixed $check, mixed $options = array(), boolean $caseInsensitive = false)


Utilisez cette rgle pour valider un champ select multiple. Elle accepte les paramtres in, max et
min.
public $validate = array(
'multiple' => array(
'rule' => array('multiple', array(
'in' => array('do', 'r', 'mi', 'fa', 'sol', 'la', 'si'),
'min' => 1,
'max' => 3
)),
'message' => 'Merci de choisir une, deux ou trois options'
)
);

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

public $validate = array(


'titre' => array(
'rule' => 'notBlank',
'message' => 'Ce champ ne peut pas rester vide'
)
);

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.'
)
);

static Validation::naturalNumber(mixed $check, boolean $allowZero = false)


Introduit dans la version 2.2.
Cette rgle vrifie si une donne passe est un nombre entier naturel valide. Si $allowZero est
dfinie true, la valeur zero est aussi accepte.
public $validate = array(
'wheels' => array(
'rule' => 'naturalNumber',
'message' => 'Merci de fournir le nombre de pneus.'
),
'airbags' => array(
'rule' => array('naturalNumber', true),
'message' => 'Merci de remplir le nombre d'airbags.'
),
);

static Validation::phone(mixed $check, string $regex = null, string $country = all)


Phone valide les numros de tlphone US. Si vous voulez valider des numros de tlphones non-US,
vous pouvez fournir une expression rgulire comme second paramtre pour couvrir des formats de
numros supplmentaires.
public $validate = array(
'telephone' => array(
'rule' => array('phone', null, 'us')
)
);

static Validation::postal(mixed $check, string $regex = null, string $country = us)


Postal est utilis pour valider des codes postaux des U.S.A. (us), du Canada (ca), du Royaume-Uni
(uk), de lItalie (it), dAllemagne (de) et de Belgique (be). Pour les autres formats de codes postaux,
vous devez fournir une expression rgulire comme second paramtre.

Pour en savoir plus sur les Models

283

CakePHP Cookbook Documentation, Version 2.x

public $validate = array(


'code_postal' => array(
'rule' => array('postal', null, 'us')
)
);

static Validation::range(string $check, integer $lower = null, integer $upper = null)


Cette rgle sassure que la valeur est dans une fourchette donne. Si aucune fourchette nest soumise,
la rgle sassurera que la valeur est un nombre limite valide pour la plateforme courante.
public $validate = array(
'nombre' => array(
'rule' => array('range', -1, 11),
'message' => 'Merci d\'entrer un nombre entre -1 et 11'
)
);

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')
)
);

static Validation::time(string $check)


La validation du Time, dtermine si une chane de caractres est un time valide. Valide le time en 24hr
(HH :MM) ou am/pm ([H]H :MM[a|p]m). Nautorise/ne valide pas les secondes.
static Validation::uploadError(mixed $check)
Introduit dans la version 2.2.
Cet rgle vrifie si un upload de fichier connait une erreur.
public $validate = array(
'image' => array(
'rule' => 'uploadError',
'message' => 'Something went wrong with the upload.'
),
);

static Validation::url(string $check, boolean $strict = false)


Cette rgle vrifie les formats valides dURL. Elle supporte les protocoles http(s), ftp(s), file, news et
gopher :

284

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

public $validate = array(


'siteweb' => array(
'rule' => 'url'
)
);

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) {
// ...
}
}

Ce fichier pourra tre plac dans APP/Validation/ ou App/PluginName/Validation/, mais


doit tre import via App : :uses() avant tout tentative dutilisation. Dans votre validation de model, vous
pourrez utiliser votre classe NlValidation en faisant ce qui suit :
public $validate = array(
'phone_no' => array('rule' => array('phone', null, 'nl')),
'postal_code' => array('rule' => array('postal', null, 'nl')),
);

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

CakePHP Cookbook Documentation, Version 2.x

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.

Validation des donnes partir du Controller

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 :

$errors = $this->ModelName->invalidFields(); // contient le tableau des ErreursDeValidation

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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)

Pour en savoir plus sur les Models

287

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

Pour en savoir plus sur les Models

289

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

291

CakePHP Cookbook Documentation, Version 2.x

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'));
}

Vous pouvez aussi attacher le behavior la vole, comme ceci


$this->Post->Behaviors->attach('Acl', array('type' => 'controlled'));

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 :
$this->User->id = 1;
$noeud = $this->User->node();
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user);

Ces deux exemples retourneront la mme information de nud Acl.


Si vous avez paramtr le behavior Acl (AclBehavior) pour crer la fois les noeuds ARO et ACO, vous
devez spcifier quel type de noeud vous desirez :
$this->User->id = 1;
$noeud = $this->User->node(null, 'Aro');
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user, 'Aro');

Containable
class ContainableBehavior

Pour en savoir plus sur les Models

293

CakePHP Cookbook Documentation, Version 2.x

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');
}

Vous pouvez aussi attacher le behavior la vole :


$this->Post->Behaviors->attach('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
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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

)
[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');

Vous pouvez utiliser la magie de Containable lintrieur dun appel find() :


$this->Post->find('all', array('contain' => false));

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
)

Pour en savoir plus sur les Models

295

CakePHP Cookbook Documentation, Version 2.x

)
[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');

Nous pouvons nouveau utiliser la cl contain dans lappel find() :


$this->Post->find('all', array('contain' => 'Tag'));

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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
(

Pour en savoir plus sur les Models

297

CakePHP Cookbook Documentation, Version 2.x

[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
(
[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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

)
)
[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

Pour en savoir plus sur les Models

299

CakePHP Cookbook Documentation, Version 2.x

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.

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 :

300

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$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));

Utiliser Containable avec la pagination En incluant le paramtre contain dans la proprit


$paginate, la pagination sera applique la fois au find(count) et au find(all) dans le model.
Voir la section Utilisation de Containable pour plus de dtails.
Voici un exemple pour limiter les associations en paginant :
$this->paginate['User'] = array(
'contain' => array('Profile', 'Account'),
'order' => 'User.username'
);
$users = $this->paginate('User');

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.

Pour en savoir plus sur les Models

301

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

Pour en savoir plus sur les Models

303

CakePHP Cookbook Documentation, Version 2.x

class Post extends AppModel {


public $actsAs = array(
'Translate' => array(
'title' => 'titleTranslation'
)
);
}

Avec ce paramtrage, le rsultat de votre $this->Post->find() devrait ressembler quelque chose


comme cela
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
)
)
)

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

$this->Post->bindTranslation(array('name' => 'titleTranslation'));


$this->Post->find('all', array('recursive' => 1)); // il est ncessaire d'avoir au moins un

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 en savoir plus sur les Models

305

CakePHP Cookbook Documentation, Version 2.x

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'));
}
}
}
}

Exemple B : Dans votre model :


class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Option 1) just define the property directly
public $locale = 'en_us';
// Option 2) create a simple method
public function setLanguage($locale) {
$this->locale = $locale;
}
}

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'

306

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

)
);
// 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.

Pour en savoir plus sur les Models

307

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

(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);
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);

Pour en savoir plus sur les Models

`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

CakePHP Cookbook Documentation, Version 2.x

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,
'&nbsp;&nbsp;&nbsp;'
);
debug($data); die;
}
}

et une dfinition de model encore plus simple :


// app/Model/Category.php
class Category extends AppModel {
public $actsAs = array('Tree');
}

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

// 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
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

CakePHP Cookbook Documentation, Version 2.x

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));

Comme on pouvait sy attendre, la structure serait modifie comme suit :


My Categories
Fun
Sport
Surfing
Skating
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories
Extreme fishing Moved
Suppression des donnes Le behavior Tree fournit un certain nombre de faons de grer la suppression
des donnes. Pour commencer par le plus simple exemple, disons que la catgorie des rapports nest plus
utile. Pour lenlever * et tous les enfants quil peut avoir * il suffit dappeler et supprimer comme vous le
feriez pour nimporte quel model. Par exemple, avec le code suivant :

312

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

// pseudo code du controller


$this->Category->id = 10;
$this->Category->delete();

Larbre des Catgories serait modifi comme suit :


My Categories
Fun
Sport
Surfing
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 :

Pour en savoir plus sur les Models

313

CakePHP Cookbook Documentation, Version 2.x

$allChildren = $this->Category->children(1); // un tableau plat 11 lments


// -- ou -$this->Category->id = 1;
$allChildren = $this->Category->children(); // un tableau plat 11 lments

// Ne retourne que les enfants directs


$directChildren = $this->Category->children(1, true); // un tableau plat avec 2 lmen

Note : Si vous voulez un tableau recursif utilisez find(threaded)


childCount($id = null, $direct = false)
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

generateTreeList($conditions=null, $keyPath=null, $valuePath=null, $spacer= _,


$recursive=null)
Paramtres
$conditions Utilise les mmes conditions quun find().
$keyPath Chemin du champ utiliser pour la cl.
$valuePath Chemin du champ utiliser pour le label.
$spacer La chane utiliser devant chaque lment pour indiquer la profondeur.
$recursive Le nombre de niveaux de profondeur pour rechercher les enregistrements associs.
Cette mthode retourne des donnes similaires :ref : model-find-list, avec un prfixe en retrait pour
montrer la structure de vos donnes. Voici un exemple de ce quoi vous attendre comme retour avec
cette mthode :
$treelist = $this->Category->generateTreeList();

Sortie :
array(
[1] =>
[2] =>
[3] =>
[4] =>
[16] =>
[6] =>
[7] =>
[8] =>

314

"My Categories",
"_Fun",
"__Sport",
"___Surfing",
"___Skating",
"__Friends",
"___Gerald",
"___Gwendolyn",

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[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

getPath($id = null, $fields = null, $recursive = null)


Le path (chemin) quand vous vous rferez des donnes hirarchiques, cest le moyen retrouver o
vous tes depuis le sommet. Par exemple le path (chemin) de la catgorie International est :
My Categories
...
Work
Trips
...
International
En utilisant lid de international, getPath retournera chacun des parents rencontrs (depuis le haut) :
$parents = $this->Category->getPath(15);
// contenu de $parents
array(
[0] => array(
'Category' => array('id' => 1, 'name' => 'My Categories', ..)

Pour en savoir plus sur les Models

315

CakePHP Cookbook Documentation, Version 2.x

),
[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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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);

Le noeud Sport sera retir du haut du noeud :


My Categories
Fun
Surfing
Extreme knitting
Skating
Sport Moved
Cela dmontre le behavior par dfaut du removeFromTree de dplacement dun noeud pour ne plus avoir
de parent, et de re-parenter tous les enfants.

Pour en savoir plus sur les Models

317

CakePHP Cookbook Documentation, Version 2.x

Si toutefois lextrait de code suivant tait utilis avec lid Sport :


$this->Node->removeFromTree($id, true);

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.

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.

318

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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');
// 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 :

Pour en savoir plus sur les Models

319

CakePHP Cookbook Documentation, Version 2.x

$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"

Niveau du Noeud (Profondeur)

Introduit dans la version 2.7.


Connatre la profondeur des noeuds dun arbre peut tre utile quand vous voulez rcuprer les noeuds seulement pour un certain niveau par exemple, quand vous gnrez des menus. Vous pouvez utiliser loption
level pour spcifier le champ qui sauvegardera le niveau de chaque noeud :
public $actAs = array('Tree' => array(
'level' => 'level', // Defaults to null, i.e. no level saving
));

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 :
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');

Pour en savoir plus sur les Models

321

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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'
)
);
}

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');
}

Pour en savoir plus sur les Models

323

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

Pour en savoir plus sur les Models

325

CakePHP Cookbook Documentation, Version 2.x

ModelBehavior::beforeDelete(Model $Model, boolean $cascade = true)


Vous pouvez retourner false dun beforeDelete dun behavior pour annuler la suppression. Retourne
true pour autoriser la suite.
ModelBehavior::afterDelete(Model $Model)
Vous pouvez utiliser afterDelete pour effectuer des oprations de nettoyage lies votre behavior.

DataSources (Sources de Donnes)


Les Sources de donnes (DataSources) sont les liens entre les models et la source de donnes quils
reprsentent. Dans de nombreux cas, les donnes sont rcupres depuis une base de donnes relationnelle telle MySQL, PostgreSQL ou Microsoft SQL Server. CakePHP est distribu avec de nombreuses sources de donnes spcifiques dune base de donnes (voir les fichiers de classe dans
lib/Cake/Model/Datasource/Database), un rsum de ceux-ci est list ici pour votre confort :
Mysql
Postgres
Sqlite
Sqlserver
Note : Vous pouvez trouver des sources de donnes contributives de la communaut supplmentaires dans
le Dpt de Sources de Donnes CakePHP sur github 2 .
Quand vous spcifiez une configuration de connexion une base de donnes dans
app/Config/database.php, CakePHP utilise de manire transparente la source de donnes
correspondant la base de donnes pour toutes les oprations de model. Donc, mme si vous pensiez ne
rien connatre aux sources de donnes, vous les utilisez tout le temps.
Toutes les sources ci-dessus drivent dune classe de base DboSource, qui agrge de la logique commune
la plupart des bases de donnes relationnelles. Si vous dcidez dcrire une source de donne RDBMS,
travailler partir de lune dentre elles (par ex MySQL ou SQLite) est plus sr.
La plupart des gens cependant, sont intresss par lcriture de sources de donnes pour des sources externes,
telles les APIs REST distantes ou mme un serveur LDAP. Cest donc ce que nous allons voir maintenant.
API basique pour les Sources de Donnes
Une source de donnes peut et devrait implmenter au moins lune des mthodes suivantes : create,
read, update et/ou delete (les signatures exactes de mthode et les dtails dimplmentation ne sont
pas importants pour le moment, ils seront dcrits plus tard). Vous ntes pas oblig dimplmenter plus que
ncessaire, parmi les mthodes listes ci-dessus - si vous avez besoin dune source de donnes en lecture
seule, il ny a aucune raison dimplmenter create, update et delete.
Mthodes qui doivent tre implmentes pour toutes les mthodes CRUD :
describe($model)
listSources($data = null)
calculate($model, $func, $params)
Au moins une des suivantes :
2. https ://github.com/cakephp/datasources/tree/2.0

326

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

create(Model $model, $fields = null, $values = null)


read(Model $model, $queryData = array(), $recursive = null)
update(Model $model, $fields = null, $values = null, $conditions =
null)
delete(Model $model, $id = null)
Il est possible galement (et souvent trs pratique), de dfinir lattribut de classe $_schema au sein de la
source de donnes elle-mme, plutt que dans le model.
Et cest peu prs tout ce quil y a dire ici. En couplant cette source de donnes un model, vous tes
alors en mesure dutiliser Model::find()/save()/delete(), comme vous le feriez normalement ;
les donnes et/ou paramtres appropris, utiliss pour appeler ces mthodes, seront passs la source de
donnes elle-mme, dans laquelle vous pouvez dcider dimplmenter toutes les fonctionnalits dont vous
avez besoin (par exemple les options de Model : :find comme le parsing conditions, limit ou
mme vos paramtres personnaliss).
Un Exemple
Une des raisons pour laquelle vous voudriez crire votre propre source
tre la volont daccder lAPI dune librairie tierce en utilisant les
Model::find()/save()/delete(). Ecrivons une source de donnes qui
JSON distante et fictive. Nous allons lappeler FarAwaySource et nous
app/Model/Datasource/FarAwaySource.php :

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,

Pour en savoir plus sur les Models

327

CakePHP Cookbook Documentation, Version 2.x

),
'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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

* facile est de juste retourner la chane 'COUNT' et de la vrifier


* dans ``read()`` o ``$data['fields'] === 'COUNT'``.
*/
public function calculate(Model $model, $func, $params = array()) {
return 'COUNT';
}

/**
* 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

Pour en savoir plus sur les Models

329

CakePHP Cookbook Documentation, Version 2.x

* 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;
}
}

Nous pouvons prsent configurer la source de donnes


app/Config/database.php en y ajoutant quelque chose comme ceci :

dans

notre

fichier

public $faraway = array(


'datasource' => 'FarAwaySource',
'apiKey'
=> '1234abcd',
);

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$this->MyModel->save(array(
'name' => 'Some Person',
'message' => 'New Message',
));

Mettre jour le prcdent message :


$this->MyModel->id = 42;
$this->MyModel->save(array(
'message' => 'Updated message',
));

Et supprimer le message :
$this->MyModel->delete(42);

Plugin de source de donnes


Vous pouvez galement empaqueter vos sources de donnes dans des plugins.
Placez
simplement
votre
fichier
de
source
de
donnes

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',
);

Se connecter un serveur SQL


La source de donnes Sqlserver dpend de lextension PHP de Microsoft appele pdo_sqlsrv. Cette extension
PHP nest pas inclue dans linstallation de base de PHP et doit tre installe sparment.
Le Client Native du Serveur SQL doit aussi tre install pour que lextension fonctionne. Puisque le Client
Native est disponible seulement pour Windows, vous ne serez pas capable de linstaller sur Linux, Mac OS
X ou FreeBSD.
Donc si les erreurs de la source de donnes Sqlserver sortent :
Error: Database connection "Sqlserver" is missing, or could not be created.

Vrifiez dabord lextension PHP du Serveur SQL pdo_sqlsrv et le Client Native du Serveur SQL.

Pour en savoir plus sur les Models

331

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

class Example extends AppModel {


public $tablePrefix = 'alternate_'; // va regarder 'alternate_examples'
}

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 :

class Example extends AppModel {


public $primaryKey = 'example_id'; // example_id est le nom du champ dans la base de do
}

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.

Pour en savoir plus sur les Models

333

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

biginteger Correspond au type BIGINT fourni par la base de donnes.


decimal Correspond aux types DECIMAL et NUMERIC.
float Correspond aux types REAL et DOUBLE PRECISION.
boolean Correspond au BOOLEAN sauf pour MySQL, o TINYINT(1) est utilis pour reprsenter les
boolens.
binary Correspond aux types BLOB ou BYTEA fournis par la base de donnes.
date Correspond au type de colonne DATE sans timezone.
datetime Correspond au type de colonne DATETIME sans timezone. Dans PostgreSQL et SQL Server, ceci
retourne un type TIMESTAMP ou TIMESTAMPTZ.
timestamp Correspond au type TIMESTAMP.
time Correspond au type TIME dans toutes les bases de donnes.
null
default value
length
Exemple dutilisation :
protected $_schema = array(
'first_name' => array(
'type' => 'string',
'length' => 30
),
'last_name' => array(
'type' => 'string',
'length' => 30
),
'email' => array(
'type' => 'string',
'length' => 30
),
'message' => array('type' => 'text')
);

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.

Pour en savoir plus sur les Models

335

CakePHP Cookbook Documentation, Version 2.x

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.

Mthodes et Proprits supplmentaires


Bien que les fonctions de model de CakePHP devraient vous emmener l o vous souhaitez aller, noubliez
pas que les classes de models ne sont rien de plus que cela : des classes qui vous permettent dcrire vos
propres mthodes ou de dfinir vos propres proprits.
Nimporte quelle opration qui prend en charge la sauvegarde ou la restitution de donnes est mieux situe
dans vos classes de model. Ce concept est souvent appel fat model (model gras).

class Exemple extends AppModel {


public function getRecent() {
$conditions = array(
'created BETWEEN (curdate() - interval 7 day) and (curdate() - interval 0 day))

336

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

);
return $this->find('all', compact('conditions'));
}
}

Cette mthode getRecent() peut maintenant tre utilise dans le controller.


$recent = $this->Exemple->getRecent();

Model::associations()
Obtenir les associations :
$result = $this->Exemple->associations();
// $result quivaut array('belongsTo', 'hasOne', 'hasMany', 'hasAndBelongsToMany')

Model::buildQuery(string $type = first, array $query = array())


Construit la requte tableau qui est utilise par la source de donnes pour gnrer la requte pour rcuprer
les donnes.
Model::deconstruct(string $field, mixed $data)
Dconstruit un type de donnes complexe (tableau ou objet) dans une valeur de champ unique.
Model::escapeField(string $field = null, string $alias = null)
Echappe le nom du champ et ajoute le nom du model. Lchappement est fait en fonction des rgles du
driver de la base de donnes courante.
Model::exists($id)
Retourne true si lenregistrement avec un ID particulier existe.
Si lID nest pas fourni, elle appelle Model::getID() pour obtenir lID de lenregistrement courant
pour vrifier, et excute ensuite un Model::find(count) sur la source de donnes actuellement
configure pour vrifier lexistence de lenregistrement dans un stockage persistant.
Note : Le Paramtre $id a t ajout dans 2.1. Avant cela, elle ne prenait aucun paramtre.
$this->Exemple->id = 9;
if ($this->Exemple->exists()) {
// ...
}
$exists = $this->Foo->exists(2);

Pour en savoir plus sur les Models

337

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

public $virtualFields = array(


'nom' => 'CONCAT(User.prenom, " ", User.nom_famille)'
);

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 :

$this->User->hasField('nom'); // Retournera false, puisqu'il n'y a pas de champ concret app


$this->User->hasField('nom', true); // Retournera true puisqu'il y a un champ virtuel appel

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 :

Pour en savoir plus sur les Models

339

CakePHP Cookbook Documentation, Version 2.x

$this->User->getVirtualField('nom'); //retoune 'CONCAT(User.prenom, ' ', User.nom_famille)'

Model : :find() et virtual fields

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.
)
);

Pagination et champs virtuels

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 :

public function __construct($id = false, $table = null, $ds = null) {


parent::__construct($id, $table, $ds);
$this->virtualFields['nom'] = sprintf('CONCAT(%s.prenom, " ", %s.nom_famille)', $this->
}

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 :

$this->Timelog->query("SELECT project_id, SUM(id) as TotalHours FROM timelogs AS Timelog GR

340

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

retourne quelque chose comme ceci :


Array
(
[0] => Array
(
[Timelog] => Array
(
[project_id] => 1234
)
[0] => Array
(
[TotalHours] => 25.5
)
)
)

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 :

$this->Timelog->query("SELECT project_id, SUM(id) as Timelog__TotalHours FROM timelogs AS T

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
)
)
)

Limitations des champs virtuels


Limplmentation de virtualFields a quelques limitations. Premirement, vous ne pouvez pas utiliser
virtualFields sur les models associs pour les conditions, les order, ou les tableaux de champs. Faire
ainsi rsulte gnralement en une erreur SQL puisque les champs ne sont pas remplacs par lORM. Cela
est d la difficult destimer la profondeur laquelle un model associ peut tre trouv.

Pour en savoir plus sur les Models

341

CakePHP Cookbook Documentation, Version 2.x

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();
}

Les transactions imbriques


Il est possible de commencer une transaction plusieurs fois en utilisant la mthode
Datasource::begin(). La transaction va seulement finir quand le nombre de commit et de
rollback correspond ceux du dbut :
$dataSource->begin();
// Excute quelques tches
$dataSource->begin();
// Quelques tches en plus
if (/*la dernire tche ok*/) {
$dataSource->commit();
} else {
$dataSource->rollback();
// Changer quelque chose dans la tche principale
}
$dataSource->commit();

342

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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;.

Pour en savoir plus sur les Models

dfaut.

Activez-la

en

utilisant

343

CakePHP Cookbook Documentation, Version 2.x

344

Chapitre 6. Models (Modles)

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

CakePHP Cookbook Documentation, Version 2.x

pour sprintf(). Vous pouvez fournir des arguments supplmentaires pour remplacer les espaces
rservs dans votre chane :
__('You have %s unread messages', h($number));

Note : Regardez la section Internationalisation & Localisation pour plus dinformation.


__c(string $msg, integer $category, mixed $args = null)
Notez que la catgorie doit tre spcifie avec une constante de classe I18n, au lieu dun nom de
constante. Les valeurs sont :
I18n : :LC_ALL - LC_ALL
I18n : :LC_COLLATE - LC_COLLATE
I18n : :LC_CTYPE - LC_CTYPE
I18n : :LC_MONETARY - LC_MONETARY
I18n : :LC_NUMERIC - LC_NUMERIC
I18n : :LC_TIME - LC_TIME
I18n : :LC_MESSAGES - LC_MESSAGES
__d(string $domain, string $msg, mixed $args = null)
Vous permet de remplacer le domaine courant lors de la recherche dun message.
Utile pour internationaliser un plugin : echo __d(plugin_name, This is my
plugin);
__dc(string $domain, string $msg, integer $category, mixed $args = null)
Vous permet de remplacer le domaine courant pour la recherche dun message. Permet galement de
spcifier une catgorie.
Notez que la catgorie doit tre spcifie avec une constante de classe I18n au lieu du nom de la
constante. Les valeurs sont :
I18n : :LC_ALL - LC_ALL
I18n : :LC_COLLATE - LC_COLLATE
I18n : :LC_CTYPE - LC_CTYPE
I18n : :LC_MONETARY - LC_MONETARY
I18n : :LC_NUMERIC - LC_NUMERIC
I18n : :LC_TIME - LC_TIME
I18n : :LC_MESSAGES - LC_MESSAGES
__dcn(string $domain, string $singular, string $plural, integer $count, integer $category, mixed
$args = null)
Vous permet de remplacer le domaine courant pour la recherche simple au pluriel dun message. Cela
permet galement de spcifier une catgorie. Retourne la forme correcte dun message identifi par
$singular et $plural pour le compteur $count depuis le domaine $domain. Certaines langues ont plus
dune forme de pluriel dpendant du compteur.
Notez que la catgorie doit tre spcifie avec des une constante de classe I18n, au lieu des noms de
constantes. Les valeurs sont :
I18n : :LC_ALL - LC_ALL
I18n : :LC_COLLATE - LC_COLLATE
I18n : :LC_CTYPE - LC_CTYPE
I18n : :LC_MONETARY - LC_MONETARY
I18n : :LC_NUMERIC - LC_NUMERIC
346

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

I18n : :LC_TIME - LC_TIME


I18n : :LC_MESSAGES - LC_MESSAGES
__dn(string $domain, string $singular, string $plural, integer $count, mixed $args = null)
Vous permet de redfinir le domaine courant pour une recherche simple au pluriel dun message.
Retourne la forme pluriel correcte dun message identifi par $singular et $plural pour le compteur
$count depuis le domaine $domain.
__n(string $singular, string $plural, integer $count, mixed $args = null)
Retourne la forme correcte dun message identifi par $singular et $plural pour le compteur $count.
Certaines langues ont plus dune forme de pluriel dpendant du compteur
am(array $one, $two, $three...)
Fusionne tous les tableaux passs en paramtre et retourne le tableau fusionn.
config()
Peut tre utilis pour charger des fichiers depuis le dossier config de votre application via include_once. La fonction vrifie lexistence du fichier avant de linclure et retourne un boolen. Prend
un nombre optionnel darguments.
Exemple : config(un_fichier, maconfig);
convertSlash(string $string)
Convertit les slashes en underscores et supprime les premier et dernier underscores dans une chane.
Retourne la chane convertie.
debug(mixed $var, boolean $showHtml = null, $showFrom = true)
Si le niveau de DEBUG de lapplication est diffrent de zro, $var est affich. Si $showHTML est
true (vrai) ou laiss null, la donne est formate pour tre visualise facilement dans un navigateur.
Si $showFrom nest pas dfini false, debug retournera en sortie la ligne depuis laquelle il a t
appel. Voir aussi Debugger
stackTrace(array $options = array())
Imprine la stack trace si le niveau de DEBUG de lapplication est suprieur 0.
env(string $key)
Rcupre une variable denvironnement depuis les sources disponibles. Utilis en secours si
$_SERVER ou $_ENV sont dsactivs.
Cette fonction mule galement PHP_SELF et DOCUMENT_ROOT sur les serveurs ne les supportant
pas. En fait, cest une bonne ide de toujours utiliser env() plutt que $_SERVER ou getenv()
(notamment si vous prvoyez de distribuer le code), puisque cest un wrapper dmulation totale.
fileExistsInPath(string $file)
Vrifie que le fichier donn est dans le include_path PHP actuel. Renvoie une valeur boolenne.
h(string $text, boolean $double = true, string $charset = null)
Raccourci pratique pour htmlspecialchars().
LogError(string $message)
Raccourci pour : Log::write().
pluginSplit(string $name, boolean $dotAppend = false, string $plugin = null)
Divise le nom dun plugin en notation par point en plugin et classname (nom de classe). Si $name de
contient pas de point, alors lindex 0 sera null.

Usage Gnral

347

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

static App::uses(string $class, string $package)


Type retourn void
Les classes sont charges toutes seules dans CakePHP, cependant avant que lautoloader puisse trouver
vos classes que vous avez besoin de dire App, o il peut trouver les fichiers. En disant App dans
quel package une classe peut tre trouve, il peut bien situer le fichier et le charger la premire fois
quune classe est utilise.
Quelques exemples pour les types courants de classes sont :
Console Commands App::uses(AppShell, Console/Command);
Console Tasks App::uses(BakeTask, Console/Command/Task);
Controllers App::uses(PostsController, Controller);
350

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Components App::uses(AuthComponent, Controller/Component);


Models App::uses(MyModel, Model);
Behaviors App::uses(TreeBehavior, Model/Behavior);
Views App::uses(ThemeView, View);
Helpers App::uses(HtmlHelper, View/Helper);
Libs App::uses(PaymentProcessor, Lib);
Vendors App::uses(Textile, Vendor);
Utilities App::uses(CakeText, Utility);
Donc au fond, le deuxime paramtre devrait simplement correspondre au chemin du dossier de la
classe de fichier dans core ou app.
Note : Charger des vendors signifie gnralement que vous chargez des packages qui ne suivent pas les
conventions. Pour la plupart des packages vendor, lutilisation de App::import() est recommande.

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');

// Charge la classe class CommentComponent dans app/Plugin/PluginName/Controller/Component/


App::uses('CommentComponent', 'PluginName.Controller/Component');

Trouver des chemins vers les packages en utilisant App : :path()

static App::path(string $package, string $plugin = null)


Type retourn array
Utilis pour lire les informations sur les chemins stocks :
// retourne les chemins de model dans votre application
App::path('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

CakePHP Cookbook Documentation, Version 2.x

Type retourn array


Utilis pour trouver le chemin vers un package lintrieur de CakePHP :
// Rcupre le chemin vers les moteurs de Cache.
App::core('Cache/Engine');

static App::location(string $className)


Type retourn string
Retourne le nom du package do une classe a t localise.
Ajoutez des chemins dans App pour trouver des packages

static App::build(array $paths = array(), mixed $mode = App : :PREPEND)


Type retourn void
Dfinit chaque localisation de package dans le systme de fichier. Vous pouvez configurer des chemins
de recherche multiples pour chaque package, ceux-ci vont tre utiliss pour rechercher les fichiers, un
dossier la fois, dans lordre spcifi. Tous les chemins devraient tre termins par un sparateur de
rpertoire.
Ajouter des chemins de controller supplmentaires pourraient par exemple modifier o CakePHP
regarde pour les controllers. Cela vous permet de sparer votre application travers le systme de
fichier.
Utilisation :
//Va configurer un nouveau chemin de recherche pour le package Model
App::build(array('Model' => array('/a/full/path/to/models/')));
//Va configurer le chemin comme le seule chemin valide pour chercher les models
App::build(array('Model' => array('/path/to/models/')), App::RESET);
//Va configurer les chemins de recherche multiple pour les helpers
App::build(array('View/Helper' => array('/path/to/helpers/', '/another/path/')));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

static App::objects(string $type, mixed $path = null, boolean $cache = true)


Type retourn mixed Retourne un tableau dobjets du type donn ou false si incorrect
Vous pouvez trouver quels objets App connat en utilisant App::objects(Controller) par
exemple pour trouver quels controllers de lapplication App connat.
Exemple dutilisation :
//retourne array('DebugKit', 'Blog', 'User');
App::objects('plugin');
//retourne array('PagesController', 'BlogController');
App::objects('Controller');

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');

Modifi dans la version 2.0.


1.Retourne array() au lieu de false pour les rsultats vides ou les types invalides.
2.Ne retourne plus les objets du coeur, App::objects(core) retournera array().
3.Retourne le nom de classe complet.
Localiser les plugins

static App::pluginPath(string $plugin)


Type retourn string
Les
Plugins
peuvent
tre
localiss
aussi
avec
App.
En
utilisant
App::pluginPath(DebugKit); par exemple, vous donnera le chemin complet vers
le plugin DebugKit :

Usage Gnral

353

CakePHP Cookbook Documentation, Version 2.x

$path = App::pluginPath('DebugKit');

Localiser les thmes

static App::themePath(string $theme)


Type retourn string
Les Thmes peuvent tre trouvs App::themePath(purple);, vous donnerait le chemin
complet vers le thme purple.
Inclure les fichiers avec App : :import()

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Surcharger les classes dans CakePHP

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');

Pour charger app/Vendor/some.name.php :


App::import('Vendor', 'SomeName', array('file' => 'some.name.php'));

Pour charger app/Vendor/services/well.named.php :

Usage Gnral

355

CakePHP Cookbook Documentation, Version 2.x

App::import('Vendor', 'WellNamed', array('file' => 'services' . DS . 'well.named.php'));

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 :

App::import('Vendor', 'aUniqueIdentifier', array('file' => 'vendorName' .DS . 'libFile.php'

Les Mthodes Init/Load/Shutdown de App

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Accder aux Gestionnaires dEvent

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

$statistics = new UserStatistic();


$this->Order->getEventManager()->attach($statistics);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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 :

// Paramtrage des priorits pour un callback


$callback = array($this, 'doSomething');
$this->getEventManager()->attach($callback, 'Model.Order.afterPlace', array('priority' => 2

// Paramtrage des priorit pour un couteur(listener)


class UserStatistic implements CakeEventListener {
public function implementedEvents() {
return array(
'Model.Order.afterPlace' => array('callable' => 'updateBuyStatistic', 'priority
);
}
}

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

CakePHP Cookbook Documentation, Version 2.x

// Paramtrage des priorits pour le callback


$callback = array($this, 'doSomething');
$this->getEventManager()->attach($callback, 'Model.Order.afterPlace', array('passParams' =>

// Paramtrage des priorits pour l'couteur (listener)


class UserStatistic implements CakeEventListener {
public function implementedEvents() {
return array(
'Model.Order.afterPlace' => array('callable' => 'updateBuyStatistic', 'passPara
);
}
public function updateBuyStatistic($orderData) {
// ...
}
}

Dans lexemple ci-dessus la fonction doSomething et la mthode updateBuyStatistic recevrons $orderData


au lieu de lobjet $event. Cest comme cela parce que dans notre premier exemple nous avons dclench
lvnement Model.Order.afterPlace avec quelques donnes :
$this->getEventManager()->dispatch(new CakeEvent('Model.Order.afterPlace', $this, array(
'order' => $order
)));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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;

// Un autre couteur (listener) de callback


public function doSomethingElse($event) {
// ...
$event->result['order'] = $alteredData;
}
// Utilisation du rsultat de l'vnement
public function place($order) {
$event = new CakeEvent('Model.Order.beforePlace', $this, array('order' => $order));
$this->getEventManager()->dispatch($event);
if (!empty($event->result['order'])) {
$order = $event->result['order'];
}
if ($this->Order->save($order)) {
// ...
}

Usage Gnral

363

CakePHP Cookbook Documentation, Version 2.x

// ...
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'));
}

Vous pouvez aussi attacher le behavior la vole, comme ceci


1. http ://en.wikipedia.org/wiki/Mixin

Usage Gnral

367

CakePHP Cookbook Documentation, Version 2.x

$this->Post->Behaviors->attach('Acl', array('type' => 'controlled'));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$this->User->id = 1;
$noeud = $this->User->node();
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user);

Ces deux exemples retourneront la mme information de nud Acl.


Si vous avez paramtr le behavior Acl (AclBehavior) pour crer la fois les noeuds ARO et ACO, vous
devez spcifier quel type de noeud vous desirez :
$this->User->id = 1;
$noeud = $this->User->node(null, 'Aro');
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user, 'Aro');

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');
}

Vous pouvez aussi attacher le behavior la vole :


$this->Post->Behaviors->attach('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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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');

Vous pouvez utiliser la magie de Containable lintrieur dun appel find() :


$this->Post->find('all', array('contain' => false));

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

CakePHP Cookbook Documentation, Version 2.x

Nous pouvons nouveau utiliser la cl contain dans lappel find() :


$this->Post->find('all', array('contain' => 'Tag'));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

(
[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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'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(
'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

CakePHP Cookbook Documentation, Version 2.x

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));

Utiliser Containable avec la pagination En incluant le paramtre contain dans la proprit


$paginate, la pagination sera applique la fois au find(count) et au find(all) dans le model.
Voir la section Utilisation de Containable pour plus de dtails.
Voici un exemple pour limiter les associations en paginant :
$this->paginate['User'] = array(
'contain' => array('Profile', 'Account'),
'order' => 'User.username'
);
$users = $this->paginate('User');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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

CakePHP Cookbook Documentation, Version 2.x

);
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

class Post extends AppModel {


public $actsAs = array(
'Translate' => array(
'title' => 'titleTranslation'
)
);
}

Avec ce paramtrage, le rsultat de votre $this->Post->find() devrait ressembler quelque chose


comme cela
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
)
)
)

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

CakePHP Cookbook Documentation, Version 2.x

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.

$this->Post->bindTranslation(array('name' => 'titleTranslation'));


$this->Post->find('all', array('recursive' => 1)); // il est ncessaire d'avoir au moins un

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'));
}
}
}
}

Exemple B : Dans votre model :


class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Option 1) just define the property directly
public $locale = 'en_us';
// Option 2) create a simple method
public function setLanguage($locale) {
$this->locale = $locale;
}
}

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

CakePHP Cookbook Documentation, Version 2.x

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.
Tree
class TreeBehavior

382

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

class CategoriesController extends AppController {


public function index() {
$data = $this->Category->generateTreeList(
null,
null,
null,
'&nbsp;&nbsp;&nbsp;'
);
debug($data); die;
}
}

et une dfinition de model encore plus simple :


// app/Model/Category.php
class Category extends AppModel {
public $actsAs = array('Tree');
}

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

CakePHP Cookbook Documentation, Version 2.x

// 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
Skating
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
386

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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));

Comme on pouvait sy attendre, la structure serait modifie comme suit :


My Categories
Fun
Sport
Surfing
Skating
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories
Extreme fishing Moved
Suppression des donnes Le behavior Tree fournit un certain nombre de faons de grer la suppression
des donnes. Pour commencer par le plus simple exemple, disons que la catgorie des rapports nest plus
utile. Pour lenlever * et tous les enfants quil peut avoir * il suffit dappeler et supprimer comme vous le
feriez pour nimporte quel model. Par exemple, avec le code suivant :
// pseudo code du controller
$this->Category->id = 10;
$this->Category->delete();

Larbre des Catgories serait modifi comme suit :


My Categories
Fun
Sport
Surfing
Usage Gnral

387

CakePHP Cookbook Documentation, Version 2.x

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

// Ne retourne que les enfants directs


$directChildren = $this->Category->children(1, true); // un tableau plat avec 2 lmen

Note : Si vous voulez un tableau recursif utilisez find(threaded)


childCount($id = null, $direct = false)
388

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

generateTreeList($conditions=null, $keyPath=null, $valuePath=null, $spacer= _,


$recursive=null)
Paramtres
$conditions Utilise les mmes conditions quun find().
$keyPath Chemin du champ utiliser pour la cl.
$valuePath Chemin du champ utiliser pour le label.
$spacer La chane utiliser devant chaque lment pour indiquer la profondeur.
$recursive Le nombre de niveaux de profondeur pour rechercher les enregistrements associs.
Cette mthode retourne des donnes similaires :ref : model-find-list, avec un prfixe en retrait pour
montrer la structure de vos donnes. Voici un exemple de ce quoi vous attendre comme retour avec
cette mthode :
$treelist = $this->Category->generateTreeList();

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

CakePHP Cookbook Documentation, Version 2.x

$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

getPath($id = null, $fields = null, $recursive = null)


Le path (chemin) quand vous vous rferez des donnes hirarchiques, cest le moyen retrouver o
vous tes depuis le sommet. Par exemple le path (chemin) de la catgorie International est :
My Categories
...
Work
Trips
...
International
En utilisant lid de international, getPath retournera chacun des parents rencontrs (depuis le haut) :
$parents = $this->Category->getPath(15);
// contenu de $parents
array(
[0] => array(
'Category' => array('id'
),
[1] => array(
'Category' => array('id'
),
[2] => array(
'Category' => array('id'
),
[3] => array(
'Category' => array('id'
),
)

390

=> 1, 'name' => 'My Categories', ..)

=> 9, 'name' => 'Work', ..)

=> 13, 'name' => 'Trips', ..)

=> 15, 'name' => 'International', ..)

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

'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);

Le noeud Sport sera retir du haut du noeud :


My Categories
Fun
Surfing
Extreme knitting
Skating
Sport Moved
Cela dmontre le behavior par dfaut du removeFromTree de dplacement dun noeud pour ne plus avoir
de parent, et de re-parenter tous les enfants.
Si toutefois lextrait de code suivant tait utilis avec lid Sport :
$this->Node->removeFromTree($id, true);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

// 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"

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[10] => Array


(
[0] =>
[1] =>
[2] =>
)
[99] => Array
(
[0] =>
[1] =>
[2] =>
)

"index"
123
"missing"

"node"
163
"left greater than right"

Niveau du Noeud (Profondeur) Introduit dans la version 2.7.


Connatre la profondeur des noeuds dun arbre peut tre utile quand vous voulez rcuprer les noeuds seulement pour un certain niveau par exemple, quand vous gnrez des menus. Vous pouvez utiliser loption
level pour spcifier le champ qui sauvegardera le niveau de chaque noeud :
public $actAs = array('Tree' => array(
'level' => 'level', // Defaults to null, i.e. no level saving
));

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

CakePHP Cookbook Documentation, Version 2.x

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');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// 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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.
ModelBehavior::beforeDelete(Model $Model, boolean $cascade = true)
Vous pouvez retourner false dun beforeDelete dun behavior pour annuler la suppression. Retourne
true pour autoriser la suite.
ModelBehavior::afterDelete(Model $Model)
Vous pouvez utiliser afterDelete pour effectuer des oprations de nettoyage lies votre behavior.
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'

400

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

)
),
'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
}

Ce quil y a au-dessous donnerait un alias MyAuthComponent $this->Auth dans vos controllers.


Note : Faire un alias un component remplace cette instance nimporte o o le component est utilis, en
Usage Gnral

401

CakePHP Cookbook Documentation, Version 2.x

incluant lintrieur des autres Components.

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

class MathComponent extends Component {


public function faireDesOperationsComplexes($montant1, $montant2) {
return $montant1 + $montant2;
}
}

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'
);

Lexemple ci-dessus passerait le tableau contenant precision et generateurAleatoire comme second


paramtre au MathComponent::__construct(). Par convention, si les cls du tableau correspondent aux proprits publiques du component, les proprits seront dfinies avec les valeurs de ces cls.
Utiliser dautres Components dans votre Component 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();
}

Usage Gnral

403

CakePHP Cookbook Documentation, Version 2.x

public function bar() {


// ...
}
}
// app/Controller/Component/ExistingComponent.php
class ExistingComponent extends Component {
public function initialize($controller) {
$this->Parent->bar();
}
public function foo() {
// ...
}
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

// 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 :
<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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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">

Ce formulaire enverra les donnes votre action add() de RecipesController (RecettesController)


. Cependant, vous pouvez utiliser la mme logique pour crer et modifier des formulaires. Le helper
Form utilise la proprit $this->request->data pour dtecter automatiquement sil faut crer
un formulaire dajout ou de modification. Si $this->request->data contient un tableau nomm
daprs le model du formulaire , et que ce tableau contient une valeur non nulle pour la cl primaire
du model, alors le FormHelper crera un formulaire de modification pour cet enregistrement prcis.
Par exemple, si on va ladresse http ://site.com/recipes/edit/5, nous pourrions avoir cela :
// Controller/RecipesController.php:
public function edit($id = null) {
if (empty($this->request->data)) {
$this->request->data = $this->Recipe->findById($id);
} else {
// La logique de sauvegarde se fera ici
}
}
// View/Recipes/edit.ctp:
// 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().
Usage Gnral

409

CakePHP Cookbook Documentation, Version 2.x

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">

En spcifiant file cela changera la mthode de soumission post, et ajoutera un enctype


multipart/form-data dans le tag du formulaire. Vous devez lutiliser si vous avez des demandes de
fichiers dans votre formulaire. Labsence de cet attribut enctype empchera le fonctionnement de lenvoi de fichiers.
echo $this->Form->create('User', array('type' => 'file'));

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">

ou pointer vers un domaine extrieur :


echo $this->Form->create(null, array(
'url' => 'http://www.google.com/search',
'type' => 'get'
));

410

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Vous pouvez spcifier des paramtres dtaills en passant un tableau end() :


$options = array(
'label' => 'Update',
'div' => array(
'class' => 'glass-pill',
)
);
echo $this->Form->end($options);

Affichera :
<div class="glass-pill"><input type="submit" value="Update!" name="Update"></div>

Voir lAPI du Helper Form 2 pour plus de dtails.


Note : si vous utilisez le component scurit SecurityComponent dans votre application vous
devez toujours terminer vos formulaires avec end().
Modifi dans la version 2.5 : Le paramtre $secureAttributes a t ajout dans 2.5.
Cration dlments de Formulaire 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
2. http ://api.cakephp.org/2.4/class-FormHelper.html

412

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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');
echo $this->Form->input('password');
echo $this->Form->input('approved');
echo $this->Form->input('quote');

//text
//password
//day, month, year, hour, minute,
//meridian
//textarea

echo $this->Form->end('Add');

Un exemple plus complet montrant quelques options pour le champ de date :


echo $this->Form->input('birth_dt', array(
'label' => 'Date de naissance',
'dateFormat' => 'DMY',
'minYear' => date('Y') - 70,
'maxYear' => date('Y') - 18,
));

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

CakePHP Cookbook Documentation, Version 2.x

$this->set('groups', $this->User->Group->find('list'));

Ensuite, ajouter les lignes suivantes votre vue de formulaire :


echo $this->Form->input('group_id');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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]'
));

Options FormHelper::input() supporte un nombre important doptions. En plus de ses propres


options input() accepte des options pour les champs input gnrs, comme les attributs html. Ce qui suit
va couvrir les options spcifiques de FormHelper::input().
$options[type] Vous pouvez forcer le type dun input, remplaant lintrospection du model, en
spcifiant un type. En plus des types de champs vus dans Cration dlments de Formulaire, vous pouvez
aussi crez des fichiers, password et divers types supports par HTML5 :
echo $this->Form->input('field', array('type' => 'file'));
echo $this->Form->input('email', array('type' => 'email'));

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

CakePHP Cookbook Documentation, Version 2.x

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>

Paramtrage de plusieurs attibuts :


echo $this->Form->input('User.name', array(
'div' => array(
'id' => 'mainDiv',
'title' => 'Div Title',
'style' => 'display:block'
)
));

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>

Dsactiver le rendu de la div


echo $this->Form->input('User.name', array('div' => false)); ?>

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>

Alternativement, dfinissez cette cl false pour dsactiver le rendu du label :


echo $this->Form->input('User.name', array('label' => false));

Affichera :

416

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<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 modifier le type denveloppe de llment et sa classe, utilisez le format suivant :


$this->Form->input('Model.field', array(
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'bzzz'))
));

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

CakePHP Cookbook Documentation, Version 2.x

$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

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" />
<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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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]'));

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

CakePHP Cookbook Documentation, Version 2.x

$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<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

CakePHP Cookbook Documentation, Version 2.x

</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" />

Ceci peut tre dsactiv en dfinissant loption $options[hiddenField] = false :


echo $this->Form->checkbox('published', array('hiddenField' => false));

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',
));

Les options de Datetime


$options[timeFormat]. Utilis pour spcifier le format des inputs select (menu de slection)
pour un jeu dinput en relation avec le temps. Les valeurs valides sont 12, 24, et null.

422

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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>

FormHelper::text(string $name, array $options)


Les autres mthodes disponibles dans lHelper Form permettent la cration dlments spcifiques de
formulaire. La plupart de ces mthodes utilisent galement un paramtre spcial $options. Toutefois,
dans ce cas, $options est utilis avant tout pour spcifier les attributs des balises HTML (comme la
valeur ou lid DOM dun lment du formulaire).
Usage Gnral

423

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->text('username', array('class' => 'users'));

Affichera :
<input name="data[User][username]" type="text" class="users" id="UserUsername" />

FormHelper::password(string $fieldName, array $options)


Cration dun champ password.
echo $this->Form->password('password');

Affichera :
<input name="data[User][password]" value="" id="UserPassword" type="password">

FormHelper::hidden(string $fieldName, array $options)


Crera un form input cach. Exemple :
echo $this->Form->hidden('id');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

FormHelper::checkbox(string $fieldName, array $options)


Cre un lment de formulaire checkbox. Cette mthode gnre galement un input de formulaire
cach pour forcer la soumission de donnes pour le champ spcifi.
echo $this->Form->checkbox('done');

Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />

Il est possible de modifier la valeur du checkbox en utilisant le tableau $options :


echo $this->Form->checkbox('done', array('value' => 555));

Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />

Si vous ne voulez pas que le Helper Form gnre un input cach :


echo $this->Form->checkbox('done', array('hiddenField' => false));

Affichera :
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />

FormHelper::radio(string $fieldName, array $options, array $attributes)


Cre un jeu dinputs radios.
Options
$attributes[value] pour dfinir quelle valeur sera slectionne par dfaut.
$attributes[separator] pour spcifier du HTML entre les boutons (ex <br />).
$attributes[between] spcifie quelques contenus insrer entre la lgende et le premier
argument.
$attributes[disabled] dfinit a true ou disabled dsactivera tous les boutons
radios gnrs.

Usage Gnral

425

CakePHP Cookbook Documentation, Version 2.x

$attributes[legend] Les lments Radio sont envelopps avec un legend et un fieldset


par dfaut. Dfinir $attributes[legend] false pour les retirer.
$options = array('H' => 'Homme', 'F' => 'Femme');
$attributes = array('legend' => false);
echo $this->Form->radio('genre', $options, $attributes);

Affichera :
<input
<input
<label
<input
<label

name="data[User][genre]" id="UserGenre_" value="" type="hidden">


name="data[User][genre]" id="UserGenreH" value="H" type="radio">
for="UserGenreH">Homme</label>
name="data[User][genre]" id="UserGenreF" value="F" type="radio">
for="UserGenreF">Femme</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));

$attributes[options] Cette cl vous permets de spcifier manuellement des options pour


un input select (menu de slection), ou pour un groupe radio. A moins que le type soit spcifi
radio, le Helper Form supposera que la cible est un input select (menu de slection)
echo $this->Form->select('field', array(1,2,3,4,5));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<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

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->select('Model.field', $options, array(


'multiple' => 'checkbox'
));

Affichera :

<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][]" value="Value 1" id="ModelField1" type="check
<label for="ModelField1">Label 1</label>
</div>
<div class="checkbox">
<input name="data[Model][field][]" value="Value 2" id="ModelField2" type="check
<label for="ModelField2">Label 2</label>
</div>
</div>

$attributes[disabled] Lors de la cration de checkboxes, cette option peut tre dfini


pour dsactiver tout ou quelques checkboxes. Pour dsactiver toutes les checkboxes, dfinissez disabled true :
$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 :
428

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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,
);

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

CakePHP Cookbook Documentation, Version 2.x

Cre un input file :


echo $this->Form->create('User', array('type' => 'file'));
echo $this->Form->file('avatar');

Affichera :
<form enctype="multipart/form-data" method="post" action="/users/add">
<input name="data[User][avatar]" value="" id="UserAvatar" type="file">

Note : Quand vous utilisez $this->Form->file(), rappelez-vous de dfinir le type dencodage , en


dfinissant loption de type file dans $this->Form->create().

Cration des boutons et des lments submits


FormHelper::submit(string $caption, array $options)
Cre un bouton submit avec la lgende $caption. Si la $caption fournie est lURL dune image
(il contient un caractre .), le bouton submit sera rendu comme une image.
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>

FormHelper::button(string $title, array $options = array())


Cre un boutton HTML avec le titre spcifi et un type par dfaut button. Dfinir
$options[type] affichera lun des trois types de boutons possibles :
1.submit : Comme celui de la mthode $this->Form->submit- (par dfaut).
2.reset : Cre un bouton reset.
3.button : Cre un bouton standard.
echo
echo
echo
echo

$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<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));

FormHelper::postButton(string $title, mixed $url, array $options = array ())


Cre un tag<button> avec un <form> lentourant qui soumets travers POST.
Cette mthode cre un lment <form>. Donc nutilisez pas pas cette mthode
dans
un
formulaire
ouvert.
Utilisez
plutt
FormHelper::submit()
ou :php:meth:FormHelper::button() pour crer des boutons a lintrieur de formulaires ouvert.
FormHelper::postLink(string $title, mixed $url = null, array $options = array ())
Cre un lien HTML, mais accde lUrl en utilisant la mthode POST. Requiert que JavaScript soit
autoris dans votre navigateur.
Cette mthode cre un lment <form>. Si vous souhaitez utiliser cette mthode dans un formulaire
existant, vous devez utiliser les options inline ou block pour que le nouveau formulaire soit
affich lextrieur de son formulaire parent.
Si vous cherchez un bouton pour soumettre votre formulaire, vous devrez plutt utiliser
FormHelper::submit() instead.
Modifi dans la version 2.3.
Loption method a t ajoute.
Modifi dans la version 2.5 : Les options inline et block ont t ajoutes. Elles permettent de
mettre en tampon la balise de form gnre au lieu de la retourner avec le lien. Ceci permet dviter
les balises de form imbriques. Dfinir inline => false va ajouter la balise de form en block
de contenu postLink, si vous voulez utiliser un block personnalis vous pouvez le spcifier en
utilisant plutt loption block.
Modifi dans la version 2.6 : Largument $confirmMessage a t dprcie. Utilisez la cl
confirm dans $options la place.
Cre des inputs de date et dheure (date and time inputs)
FormHelper::dateTime($fieldName, $dateFormat = DMY, $timeFormat = 12, $attributes
= array())
Cre un jeu dinputs pour la date et lheure. Les valeurs valides pour $dateformat sont DMY, MDY,
YMD ou NONE. Les valeurs valides pour $timeFormat sont 12, 24, et null.
Vous pouvez spcifier de ne pas afficher les valeurs vides en paramtrant array(empty => false)
dans les paramtres des attributs. il pr-slectionnera galement les champs a la date et heure courante.
FormHelper::year(string $fieldName, int $minYear, int $maxYear, array $attributes)
Cre un lment select(menu de slection) rempli avec les annes depuis $minYear
jusqu $maxYear. Les attributs HTML devrons tre fournis dans $attributes. Si
$attributes[empty] est false, le select ninclura pas doption empty :

Usage Gnral

431

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->annee('purchased', 2000, date('Y'));

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>

FormHelper::month(string $fieldName, array $attributes)


Cre un lment select (menu de slection) avec le nom des mois :
echo $this->Form->month('mob');

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));

FormHelper::day(string $fieldName, array $attributes)


Cre un lment select (menu de slection) rempli avec les jours (numriques) du mois.
Pour crer une option empty avec laffichage dun texte de votre choix (ex. la premire option est
Jour), vous pouvez fournir le texte comme paramtre final comme ceci :

432

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

FormHelper::hour(string $fieldName, boolean $format24Hours, array $attributes)


Cre un lment select (menu de slection) rempli avec les heures de la journe.
FormHelper::minute(string $fieldName, array $attributes)
Cre un lment select (menu de slection) rempli avec les minutes dune heure.
FormHelper::meridian(string $fieldName, array $attributes)
Cre un lment select (menu de slection) rempli avec am et pm.
Afficher et vrifier les erreurs
FormHelper::error(string $fieldName, mixed $text, array $options)
Affiche un message derreur de validation, spcifie par $texte, pour le champ donn, dans le cas o
une erreur de validation a eu lieu.
Options :
escape boolen si il faut ou non que le HTML chappe le contenu de lerreur.
wrap valeur mixte dfinissant sil faut ou pas que le message derreur soit envelopper dune div. Si
cest une chane , sera utilis comme le tag HTML utiliser.
class string Le nom de classe du message derreur.
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');
}

Note : En utilisant FormHelper::input(), les erreurs sont retournes par dfaut.


FormHelper::tagIsInvalid()
Retourne false si le champ fourni dcrit par lentit courante ne contient pas derreur. Sinon retourne
le message de validation.
Configuration par dfaut pour tous les champs Introduit dans la version 2.2.
Vous pouvez dclarer un ensemble doptions par dfaut pour input() en utilisant
FormHelper::inputDefaults(). Changer les options par dfaut vous permet de consolider
les options rptes dans un appel une unique mthode :
Usage Gnral

433

CakePHP Cookbook Documentation, Version 2.x

$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() :

echo $this->Form->input('password'); // Pas de div, pas de label avec la classe 'fancy'


echo $this->Form->input('username', array('label' => 'Username')); // a un lment label av

Travailler avec le Component Scurity 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');

FormHelper::secure(array $fields = array())


Gnre un champ cach avec hachage sur le champ utilis dans le formulaire.
Mises jour 2.0 $selected parameter removed
Le
paramtre
$selecteda t retir de plusieurs mthodes du Helper
Form (FormHelper). Toutes les mthodes supportent dsormais un cl
$attributes[value] qui devra tre utilise en remplacement de $selected. Ce changement
simplifie les mthodes du Helper Form, en rduisant le nombre darguments, et rduit les duplications que
$selected cre. Les mthodes sont :
FormHelper : :select()
FormHelper : :dateTime()
FormHelper : :year()
FormHelper : :month()
FormHelper : :day()
FormHelper : :hour()
FormHelper : :minute()
FormHelper : :meridian()

434

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

LURL par dfaut des formulaires est laction courante


LURL par dfaut pour tous les formulaires, est dsormais lURL courante incluant passed, named, et les
paramtres de la requte (querystring parameters). Vous pouvez redfinir cette valeur par dfaut en fournissant $options[url] dans le second paramtre de $this->Form->create().
FormHelper : :hidden()
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.

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

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->charset('ISO-8859-1');

Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />

HtmlHelper::css(mixed $path, array $options = array())


Modifi dans la version 2.4.
Paramtres
$path (mixed) Soit une chane du fichier CSS lier, ou un tableau avec plusieurs
fichiers.
$options (array) Un tableau doptions ou d attributs html.
Cr un ou plusieurs lien(s) vers un feuille de style CSS. Si la cl inline est dfinie false dans les
paramtres $options, les balises de lien seront ajouts au bloc css lequel sera intgr la balise
entte du document.
Vous pouvez utiliser loption block pour contrler sur lequel des blocs llment li sera ajout. Par
dfaut il sera ajout au bloc css.
Si la cl rel dans le tableau $options est dfini pour import, la feuille de style sera importe.
Cette mthode dinclusion CSS prsume que le CSS spcifi se trouve dans le rpertoire
/app/webroot/css si un chemin ne commence par un /.
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

echo $this->Html->css(Blog.common.css, array(plugin => false)) ;


Modifi dans la version 2.1 : Loption block a t ajoute. Le support de syntaxe de plugin t
ajout.
436

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

HtmlHelper::meta(string $type, string $url = null, array $options = array())


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'

Usage Gnral

437

CakePHP Cookbook Documentation, Version 2.x

);
?>
// 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 : Loption block a t ajoute.


HtmlHelper::docType(string $type = xhtml-strict)
Paramtres
$type (string) Le type de doctype fabriqu.
Retourne un balise doctype (X)HTML. Fournissez le doctype en suivant la table suivante :
type
valeur rsultante
html4-strict
HTML4 Strict
html4-trans
HTML4 Transitional
html4-frame HTML4 Frameset
html5
HTML5
xhtml-strict
XHTML1 Strict
xhtml-trans
XHTML1 Transitional
xhtml-frame XHTML1 Frameset
xhtml11
XHTML1.1
echo $this->Html->docType();
// Sortie:
// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
//
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
echo $this->Html->docType('html5');
// Sortie: <!DOCTYPE html>
echo $this->Html->docType('html4-trans');
// Sortie:
// <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
//
"http://www.w3.org/TR/html4/loose.dtd">

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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;

HtmlHelper::image(string $path, array $options = array())


param string $path Chemin de limage.
param array $options Un tableau de attributs html.
Cr une balise image formate. Le chemin fournit devra tre relatif /app/webroot/img/.
echo $this->Html->image('cake_logo.png', array('alt' => 'CakePHP'));

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

CakePHP Cookbook Documentation, Version 2.x

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));

Modifi dans la version 2.1 : Loption fullBase a t ajout. Le support de syntaxe de


plugin a t ajout.
HtmlHelper::link(string $title, mixed $url = null, array $options = array())
Paramtres
$title (string) Le texte afficher comme corps du lien.
$url (mixed) Soit la chane spcifiant le chemin, ou un tableau de routing.
$options (array) Un tableau d :attributs HTML.
Mthode gnrale pour la cration de liens HTML. Utilisez les $options pour spcifier les attributs
des lments et si le $title devra ou non tre chapp.
echo $this->Html->link(
'Enter',
'/pages/home',
array('class' => 'button', 'target' => '_blank')
);

Affichera :
<a href="/pages/home" class="button" target="_blank">Enter</a>

Utilisez loption full_base => true pour des URLs absolues :


echo $this->Html->link(
'Dashboard',
array(
'controller' => 'dashboards',
'action' => 'index',
'full_base' => true
)
);

Affichera :
<a href="http://www.yourdomain.com/dashboards/index">Dashboard</a>

Spcifiez $confirmMessage pour afficher une boite de dialogue de confirmation confirm()


JavaScript :
echo $this->Html->link(
'Delete',
array('controller' => 'recipes', 'action' => 'delete', 6),
array(),
"Are you sure you wish to delete this recipe?"
);

Affichera :

440

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<a href="/recipes/delete/6" onclick="return confirm('Are you sure you wish to delete t

Les chanes de requte peuvent aussi tre cres avec link().


echo $this->Html->link('View image', array(
'controller' => 'images',
'action' => 'view',
1,
'?' => array('height' => 400, 'width' => 500))
);

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

CakePHP Cookbook Documentation, Version 2.x

<?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 &quot;howdy&quot;">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>

Modifi dans la version 2.4 : Loption escapeTitle a t ajoute.


Modifi dans la version 2.6 : Largument $confirmMessage a t dprcie. Utilisez la cl
confirm dans $options la place.
Regardez aussi la mthode HtmlHelper::url pour plus dexemples des diffrents types dURLs.
HtmlHelper::media(string|array $path, array $options)
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(

442

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'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>

HtmlHelper::tag(string $tag, string $text, array $htmlAttributes)


Paramtres
$tag (string) Le nom de la balise cre.
$text (string) Le contenu de la balise.
$options (array) Un tableau dattributs html attributs html.
Retourne des textes envelopps dans une balise spcifie. Si il ny a pas de texte spcifi alors le
contenu du <tag> sera retourn :
.. code-block:: php

< ?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

CakePHP Cookbook Documentation, Version 2.x

<?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>

HtmlHelper::para(string $class, string $text, array $options)


Paramtres
$class (string) Le nom de classe du paragraphe.
$text (string) Le contenu du paragraphe.
$options (array) Un tableau dattributs attributs html.
Retourne un texte envelopp dans une balise CSS <p>. Si aucun texte CSS est fourni, un simple <p>
de dmarrage est retourn. :
<?php
echo $this->Html->para(null, 'Bonjour le Monde');
?>
// Affichera
<p>Bonjour le Monde</p>

HtmlHelper::script(mixed $url, mixed $options)


Paramtres
$url (mixed) Soit un simple fichier Javascript, ou un tableau de chanes pour
plusieurs fichiers.
$options (array) Un tableau dattributs attributs html.
Inclus un(des) fichier(s), prsent soit localement soit une URL distante.
Par dfaut, les tags de script sont ajouts au document inline. Si vous le surcharger en configurant
$options[inline] false, les tags de script vont plutt tre ajouts au block script que
vous pouvez afficher aileurs dans le document. Si vous souhaitez surcharger le nom du block utilis,
vous pouvez le faire en configurant $options[block].
$options[once] contrle si vous voulez ou pas inclure le script une fois par requte. Par dfaut
true.
Vous pouvez utiliser $options pour dfinir des proprits supplmentaires pour la balise script gnre.
Si un tableau de balise script est utilis, les attributs seront appliqus toutes les balises script
gnres.
Cette mthode dinclusion de fichier JavaScript suppose que les fichiers JavaScript spcifis se trouvent dans le rpertoire /app/webroot/js.
echo $this->Html->script('scripts');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->script('/autrerep/fichier_script');

Vous pouvez aussi lier une URL dun dpt distant :


echo $this->Html->script('http://code.jquery.com/jquery.min.js');

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

CakePHP Cookbook Documentation, Version 2.x

$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.
$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

</li>
<li>Spanish</li>
<li>German</li>
</ul>
</li>
</ul>

HtmlHelper::tableHeaders(array $names, array $trOptions = null, array $thOptions =


null)
Paramtres
$names (array) Un tableau de chane pour crer les enttes de tableau.
$trOptions (array) Un tableau d attributs HTML pour le <tr>.
$thOptions (array) Un tableau d attributs HTML pour llment <th>.
Cr une ligne de cellule den-tte placer dans la balise <table>.
echo $this->Html->tableHeaders(array('Date', 'Title', 'Active'));

// 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

CakePHP Cookbook Documentation, Version 2.x

<tr>
<th>id</th>
<th class="highlight">Name</th>
<th class="sortable">Date</th>
</tr>

HtmlHelper::tableCells(array $data, array $oddTrOptions = null, array $evenTrOptions =


null, $useCount = false, $continueOddEven = true)
Paramtres
$data (array) Un tableau deux dimensions avec les donnes pour les lignes.
$oddTrOptions (array) Un tableau d attributs HTML pour les <tr> impairs.
$evenTrOptions (array) Un tableau d attributs HTML pour les <tr> pairs.
$useCount (boolean) Ajoute la classe column-$i.
$continueOddEven (boolean) Si false, utilisera une variable $count nonstatique, ainsi le compteur impair/pair est remis zro juste pour cet appel.
Cr des cellules de table, en assignant aux lignes des attributs <tr> diffrents pour les lignes paires
et les lignes impaires. Entoure une simple table de cellule dans un array() pour des attributs <td>
spcifiques.
echo $this->Html->tableCells(array(
array('Jul 7th, 2007', 'Best Brownies', 'Yes'),
array('Jun 21st, 2007', 'Smart Cookies', 'Yes'),
array('Aug 1st, 2006', 'Anti-Java Cake', 'No'),
));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

HtmlHelper::url(mixed $url = NULL, boolean $full = false)


Paramtres
$url (mixed) Un tableau de routing.
$full (mixed) Soit un boolen sil faut ou pas que la base du chemin soit incluse
ou un tableau doptions pour le router Router::url().
Retourne une URL pointant vers une combinaison controller et action. Si $url est vide, cela retourne
la REQUEST_URI, sinon cela gnre la combinaison dune URL pour le controller et dune action.
Si full est true, la base complte de lURL sera ajoute en amont du rsultat :
echo $this->Html->url(array(
"controller" => "posts",
"action" => "view",
"bar"
));
// Restituera
/posts/view/bar

Voici quelques exemples supplmentaires :


URL avec des paramtres nomms :
echo $this->Html->url(array(
"controller" => "posts",
"action" => "view",
"foo" => "bar"
));
// Restituera
/posts/view/foo:bar

URL avec une extension :


echo $this->Html->url(array(
"controller" => "posts",
"action" => "list",
"ext" => "rss"
));
// Restituera
/posts/list.rss

URL (commenant par /) avec la base complte dURL ajoute :


echo $this->Html->url('/posts', true);
// Restituera
http://somedomain.com/posts

Usage Gnral

449

CakePHP Cookbook Documentation, Version 2.x

URL avec des paramtres GET et une ancre nomme :


<?php echo $this->Html->url(array(
"controller" => "posts",
"action" => "search",
"?" => array("foo" => "bar"),
"#" => "first"));
// Restituera
/posts/search?foo=bar#first

Pour plus dinformation voir Router : :url 4 dans l API.


HtmlHelper::useTag(string $tag)
Retourne un bloc existant format de balise $tag :
$this->Html->useTag(
'form',
'http://example.com',
array('method' => 'post', 'class' => 'myform')
);

Output :
<form action="http://example.com" method="post" class="myform">

Changer la restitution des balises avec le Helper Html


HtmlHelper::loadConfig(mixed $configFile, string $path = null)
Les jeux de balises pour le Helper Html HtmlHelper sont conformes au standard XHTML, toutefois
si vous avez besoin de gnrer du HTML pour les standards HTML5 vous aurez besoin de crer et de
charger un nouveau fichier de configuration de balise contenant les balises que vous aimeriez utiliser.
Pour changer les balises utilises, crez un fichier app/Config/html5_tags.php contenant :
$config = array('tags' => array(
'css' => '<link rel="%s" href="%s" %s>',
'style' => '<style%s>%s</style>',
'charset' => '<meta charset="%s">',
'javascriptblock' => '<script%s>%s</script>',
'javascriptstart' => '<script>',
'javascriptlink' => '<script src="%s"%s></script>',
// ...
));

Vous
pouvez
alors
charger
ces
balises
$this->Html->loadConfig(html5_tags);.

dfinis

en

appelant

Cration dun chemin de navigation avec le Helper Html


HtmlHelper::getCrumbs(string $separator = &raquo ;, string|array|bool $startText =
false)
CakePHP inclut la possibilit de crer automatiquement un chemin de navigation (fil dAriane) dans
votre application. Pour mettre cela en service, ajouter cela dans votre template de layout :
4. http ://api.cakephp.org/2.4/class-Router.html#_url

450

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->getCrumbs(' > ', 'Home');

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'
);

Avertissement : Assurez-vous de dclarer le Helper Js et son moteur en haut du tableau $helpers


dans votre controller.
Le moteur JavaScript slctionn peut disparatre (remplac par celui par dfaut) de lobjet JsHelper dans
votre helper, si vous oubliez de faire cela et vous obtiendrez du code qui ne correspond pas votre librairie
JavaScript.
Cration dun moteur Javascript 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 :

Usage Gnral

453

CakePHP Cookbook Documentation, Version 2.x

$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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
});

JsHelper::request($url, $options = array())


Gnre un morceau de code Javascript pour crer une requte XmlHttpRequest ou AJAX.
Options de lvnement
complete - Callback lancer si complt.
success - Callback lancer en cas de succs.
before - Callback lancer linitialisation de la requte.
error - Callback lancer en cas derreur de requte.
Options
method - La mthode pour fabriquer la requte avec GET dans plus de librairies.
async - Sil faut ou pas utiliser une requte asynchrone.
data - Donnes additionnelles envoyer.
update - LID du Dom id mettre jour avec le contenu de la requte.
type - Le Type des donnes de la rponse.json et html sont supports. Par dfaut html pour la
plupart des librairies.
evalScripts - sil faut ou pas valuer la balise <script>.
dataExpression -Si la clef data doit tre traite comme un callback. Utile pour fournir
$options[data] comme une autre expression Javascript.
Exemple dutilisation :
$this->Js->event(
'click',
$this->Js->request(
array('action' => 'foo', 'param1'),
array('async' => true, 'update' => '#element')
)
);

456

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.
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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'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
});

JsHelper::effect($name, $options = array())


Cr un effet basique. Par dfaut cette mthode nest pas bufferise et retourne ses rsultats.
noms des effets supports
Les effets suivants sont supports par tous les moteurs JS :
show - rvle un lment.
hide - dissimule un lment.
fadeIn - Fade in un lment.
fadeOut - Fade out un lment.
slideIn - Slide un lment in.
slideOut - Slide un lment out.
Options
speed - Vitesse laquelle lanimation devrait se produire. Les valeurs acceptes sont slow, fast.
Tous les effets nutilisent pas loption speed.
Exemple dutilisation
Si vous utilisez le moteur jQuery :
$this->Js->get('#element');
$result = $this->Js->effect('fadeIn');
// $result contient $("#foo").fadeIn();

JsHelper::event($type, $content, $options = array())


Attache un vnement la slection courante. $type peut tre un vnement DOM normal ou un type
dvnement personnalis si votre librairie les supporte. $content devrait contenir les fonctions du
body pour le callback. Les Callbacks seront envelopps avec la fonction function (event) {
... } moins quils ne soient dsactivs avec $options.
Options
wrap - Si vous souhaitez que le callback soit envelopp dans une fonction anonyme. (par dfaut
true)
stop - Si vous souhaitez que lvnement sarrte. (par dfaut true)
Exemple dutilisation :

Usage Gnral

459

CakePHP Cookbook Documentation, Version 2.x

$this->Js->get('#some-link');
$this->Js->event('click', $this->Js->alert('saperlipopette!'));

Si vous employiez la librairie jQuery, vous devriez avoir le code suivant :


$('#some-link').bind('click', function (event) {
alert(saperlipopette!');
return false;
});

Vous pouvez retirer le return false; en passant loption stop false :


$this->Js->get('#some-link');
$this->Js->event(
'click',
$this->Js->alert('saperlipopette!'),
array('stop' => false)
);

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"});');

Lutilisation du moteur jQuery aurait cr le Javascript suivant :


$('div.message').each(function () { $(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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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');

JsHelper::submit($caption = null, $options = array())


Cr un bouton submit qui permet les formulaires de soumission XmlHttpRequest. Les options peuvent inclure soit celles de FormHelper::submit() et JsBaseEngine : :request(), JsBaseEngine : :event() ;
La soumission a travers un formulaire avec cette mthode, ne permet pas lenvoi de fichiers. Les
fichiers ne se transferts pas travers XmlHttpRequest et requirent un iframe, ou dautres paramtrages plus spcialiss qui sont hors de porte de cet helper.
Options
confirm - Message de confirmation affich avant lenvoi de la requte. Lutilisation de confirm ,
ne remplace pas les mthodes de callback before dans le XmlHttpRequest gnr.
buffer - Dsactive le buffering et retourne une balise script en plus du lien.
wrapCallbacks - Mis false pour dsactiver lenveloppement automatique des callbacks.
Exemple dutilisation :
echo $this->Js->submit('Save', array('update' => '#content'));

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
));

Montre comment vous pouvez combiner les options de FormHelper::submit() et Helper


Js::request() lutilisation des submits.
JsHelper::link($title, $url = null, $options = array())
Cr un lment ancre HTML qui a un vnement clic rattach. Les options peuvent inclure
celle pour HtmlHelper::link() et Helper Js::request(), Helper Js::event(),
$options est un tableau dattribut attributs html qui sont ajouts llment ancre gnr. Si une
option ne fait pas parti des attributs standard de $htmlAttributes elle sera passe Helper
Js::request() comme une option. Si une Id nest pas fournie, une valeur alatoire sera cre
pour chacun des liens gnrs.
Options
confirm - Gnre une boite de dialogue de confirmation avant lenvoi de lvnement.
id - utilise une id personnalise .
htmlAttributes - attributs HTML non standard supplmentaires. Les attributs standards sont
class, id, rel, title, escape, onblur et onfocus.
buffer - Dsactive le buffering et retourne une balise script en plus du lien.
Exemple dutilisation :

Usage Gnral

461

CakePHP Cookbook Documentation, Version 2.x

echo $this->Js->link(
'Page 2',
array('page' => 2),
array('update' => '#content')
);

Va cr un lien pointant vers /page:2 et mettre jour #content avec la rponse.


Vous pouvez utiliser les options de htmlAttributes pour ajouter des attributs personnaliss.
echo $this->Js->link('Page 2', array('page' => 2), array(
'update' => '#content',
'htmlAttributes' => array('other' => 'value')
));
// Cr le HTML suivant
<a href="/posts/index/page:2" other="value">Page 2</a>

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// 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 :
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

CakePHP Cookbook Documentation, Version 2.x

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.

// appel par NumberHelper


$this->Number->addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals'

// appel par CakeNumber


App::uses('CakeNumber', 'Utility');
CakeNumber::addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals' =>

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

NumberHelper::precision(mixed $number, int $precision = 3)


Paramtres
$number (float) La valeur convertir
$precision (integer) Le nombre de dcimal afficher
Cette mthode affiche un nombre avec le montant de prcision spcifi (place de la dcimal). Elle
arrondira afin de maintenir le niveau de prcision dfini.
// appel avec NumberHelper
echo $this->Number->precision(456.91873645, 2 );
// Sortie
456.92
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::precision(456.91873645, 2 );

NumberHelper::toPercentage(mixed $number, int $precision = 2, array $options = array())


Paramtres
$number (float) La valeur convertir.
$precision (integer) Le nombre de dcimal afficher.
$options (array) Options, voir ci-dessous.
OpDescription
tion
multiBoolen pour indiquer si la valeur doit tre multiplie par 100. Utile pour les
ply
pourcentages avec dcimal.
Comme precision(), cette mthode formate un nombre selon la prcision fournie (o les nombres sont
arrondis pour parvenir ce degr de prcision). Cette mthode exprime aussi le nombre en tant que
pourcentage et prfixe la sortie avec un signe de pourcent.
// appel avec NumberHelper. Sortie: 45.69%
echo $this->Number->toPercentage(45.691873645);

Usage Gnral

467

CakePHP Cookbook Documentation, Version 2.x

// appel avec CakeNumber. Sortie: 45.69%


App::uses('CakeNumber', 'Utility');
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

NumberHelper::format(mixed $number, mixed $options=false)


Cette mthode vous donne beaucoup plus de contrle sur le formatage des nombres pour lutilisation
dans vos vues (et est utilise en tant que mthode principale par la plupart des autres mthodes de
NumberHelper). Lutilisation de cette mthode pourrait ressembler cela :
// appel avec NumberHelper
$this->Number->format($number, $options);
// appel avec CakeNumber
CakeNumber::format($number, $options);

468

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'

NumberHelper::formatDelta(mixed $number, mixed $options=array())


Cette mthode affiche les diffrences en valeur comme un nombre sign :
// appel avec NumberHelper
$this->Number->formatDelta($number, $options);
// appel avec CakeNumber
CakeNumber::formatDelta($number, $options);

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

CakePHP Cookbook Documentation, Version 2.x

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'

Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.


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
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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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));

PaginatorHelper::sortDir(string $model = null, mixed $options = array())


rcupre la direction courante du tri du jeu denregistrement.
PaginatorHelper::sortKey(string $model = null, mixed $options = array())
rcupre la cl courante selon laquelle le jeu denregistrement est tri.

Usage Gnral

471

CakePHP Cookbook Documentation, Version 2.x

Cration des liens de page numrots


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 donnes pagines.
PaginatorHelper::prev($title = << Previous, $options = array(), $disabledTitle = null,
$disabledOptions = array())

472

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

Si il ny avait pas de page prcdente vous obtenez :


<span class="prev disabled"><< previous</span>

Vous pouvez changer la balise enveloppante en utilisant loption tag


echo $this->Paginator->prev(__('previous'), array('tag' => 'li'));

Sortie :
<li class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
</li>

Vous pouvez aussi dsactiver la balise enroulante :


echo $this->Paginator->prev(__('previous'), array('tag' => false));

Output :
<a class="prev" rel="prev"
href="/posts/index/page:1/sort:title/order:desc">
previous
</a>

Usage Gnral

473

CakePHP Cookbook Documentation, Version 2.x

Modifi dans la version 2.3 : Pour les mthodes : PaginatorHelper::prev() et


PaginatorHelper::next(), il est maintenant possible de dfinir loption tag false pour
dsactiver le wrapper. Les nouvelles options disabledTag ont t ajoutes.
Si vous laissez vide $disabledOptions, le paramtre $options sera utilis. Vous pouvez enregistrer
dautres saisies si les deux groupes doptions sont les mmes.
PaginatorHelper::next($title = Next >>, $options = array(), $disabledTitle = null, $disabledOptions = array())
Cette mthode est identique a prev() avec quelques exceptions. il cr le lien pointant vers la page
suivante au lieu de la prcdente. elle utilise aussi next comme valeur dattribut rel au lieu de prev.
PaginatorHelper::first($first = << first, $options = array())
Retourne une premire ou un nombre pour les premires pages. Si une chane est fournie, alors un
lien vers la premire page avec le texte fourni sera cr :
echo $this->Paginator->first('< first');

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::hasNext(string $model = null)


Retourne true si le rsultat fourni nest pas sur la dernire page.
PaginatorHelper::hasPrev(string $model = null)
Retourne true si le rsultat fourni nest pas sur la premire page.
PaginatorHelper::hasPage(string $model = null, integer $page = 1)
Retourne true si lensemble de rsultats fourni a le numro de page fourni par $page.
474

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Cration dun compteur de page


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}'
);

En dfinissant format range donnerait en sortie 1 - 3 of 13 :


echo $this->Paginator->counter(array(
'format' => 'range'
));

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

CakePHP Cookbook Documentation, Version 2.x

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')
));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

Les liens en retour de la mthode sort() du PaginatorHelper permettent au utilisateurs de cliquer


sur les enttes de table pour faire basculer lordre de tri des donnes dun champ donn.
Il est aussi possible de trier une colonne base sur des associations :
<table>
<tr>
<th><?php echo $this->Paginator->sort('titre', 'Titre'); ?></th>
<th><?php echo $this->Paginator->sort('Auteur.nom', 'Auteur'); ?></th>
</tr>
<?php foreach ($data as $recette): ?>
<tr>
<td><?php echo h($recette['Recette']['titre']); ?> </td>
<td><?php echo h($recette['Auteur']['nom']); ?> </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

CakePHP Cookbook Documentation, Version 2.x

// 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
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'));

Si cr dans la vue de /posts/index, cela crerait un lien


/posts/index/page :5/sort :title/direction :desc.
PaginatorHelper::url($options = array(), $asArray = false, $model = null)

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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
)
*/

PaginatorHelper::param(string $key, string $model = null)


Rcupre le paramtre de pagination spcifique partir de lensemble de rsultats pour le model
donn :
debug($this->Paginator->param('count'));
/*
(int)43
*/

Introduit dans la version 2.4 : La mthode param() a t ajoute dans 2.4.


PaginatorHelper::meta(array $options = array())
Gnre le meta-links pour un rsultat pagin :
echo $this->Paginator->meta(); // Example output for page 5
/*
<link href="/?page=4" rel="prev" /><link href="/?page=6" rel="next" />
*/

Vous pouvez galement ajouter la gnration de la fcontion meta un block nomm :


$this->Paginator->meta(array('block' => true));

Si true est envoy, le block meta est utilis.


Introduit dans la version 2.6 : La mthode meta() a t ajoute dans 2.6.
RSS
class RssHelper(View $view, array $settings = array())
Le Helper RSS permet de gnrer facilement des XML pour les flux RSS.
Usage Gnral

479

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'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'));

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

API de Rss Helper


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.
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().
Usage Gnral

483

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

echo $this->Session->flash();

Ce qui est au-dessus sortira un message simple, avec le HTML suivant :


<div id="flashMessage" class="message">
Vos trucs on t sauvegards.
</div>

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'));

Ceci utilise View/Elements/failure.ctp pour rendre le message. Le message texte sera


disponible dans une variable $message dans llment.
A lintrieur du fichier lment dchec, il y aura quelque chose comme ceci :
<div class="flash flash-failure">
<?php echo $message ?>
</div>

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Output :
<p>Pour plus d\'information<br />
selon nos clbres ptes et desserts.<p>
<p>contact info@example.com</p>

Introduit dans la version 2.4.


TextHelper::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 :
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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

array(
'ellipsis' => '...',
'exact' => true
)

Introduit dans la version 2.3.


Exemple :
$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

TextHelper::excerpt(string $haystack, string $needle, integer $radius=100, string $ending=...)


Paramtres
$haystack (string) La chane chercher.
$needle (string) La chane to excerpt around.
$radius (int) Le nombre de caractres de chaque ct de $needle que vous
souhaitez inclure.
$ending (string) Le Texte ajouter/prfixer au dbut ou la fin du rsultat.
Extrait un excerpt de $haystack surrounding the $needle avec un nombre de caractres de
chaque ct dtermin par $radius, et prefix/suffix with $ending. Cette mthode est spcialement pratique pour les rsultats recherchs. La chane requte ou les mots cls peuvent tre montrs
dans le document rsultant.
// appel avec TextHelper
echo $this->Text->excerpt($lastParagraph, 'method', 50, '...');

Usage Gnral

489

CakePHP Cookbook Documentation, Version 2.x

// appel avec CakeText


App::uses('CakeText', 'Utility');
echo CakeText::excerpt($lastParagraph, 'method', 50, '...');

Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...

TextHelper::toList(array $list, $and=and)


Paramtres
$list (array) Tableau dlments combiner dans une list sentence.
$and (string) Le mot utilis pour le dernier join.
Cre une liste spare avec des virgules, o les deux derniers items sont joins avec and.
// appel avec TextHelper
echo $this->Text->toList($colors);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::toList($colors);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'));

Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset


utilis dans 2.1 et suivants.
TimeHelper::convertSpecifiers($format, $time = NULL)
Type retourn string
Convertit une chane de caractres reprsentant le format pour la fonction strftime et retourne un
format Windows safe et i18n aware.
TimeHelper::dayAsSql($dateString, $field_name, $timezone = NULL)
Type retourn string
Cre une chane de caractres dans le mme format que dayAsSql mais ncessite seulement un unique
objet date :
// Appel avec TimeHelper
echo $this->Time->dayAsSql('Aug 22, 2011', 'modified');
// (modified >= '2011-08-22 00:00:00') AND
// (modified <= '2011-08-22 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::dayAsSql('Aug 22, 2011', 'modified');

Usage Gnral

491

CakePHP Cookbook Documentation, Version 2.x

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::daysAsSql($begin, $end, $fieldName, $userOffset = NULL)
Type retourn string
Retourne une chane de caractres dans le format ($field_name >= 2008-01-21 00 :00 :00) AND
($field_name <= 2008-01-25 23 :59 :59). Cest pratique si vous avez besoin de chercher des enregistrements entre deux dates incluses :
// Appel avec TimeHelper
echo $this->Time->daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');
// (created >= '2011-08-22 00:00:00') AND
// (created <= '2011-08-25 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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');

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::gmt($dateString = NULL)
Type retourn integer
Va retourner la date en un nombre dfini sur Greenwich Mean Time (GMT).
// Appel avec TimeHelper
echo $this->Time->gmt('Aug 22, 2011');
// 1313971200
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::gmt('Aug 22, 2011');

TimeHelper::i18nFormat($date, $format = NULL, $invalid = false, $timezone = NULL)


Type retourn string
Retourne une chane de date formate, tant donn soit un timestamp UNIX soit une chane de date
valide strtotime(). Il prend en compte le format de la date par dfaut pour le langage courant si un
fichier LC_TIME est utilis. Pour plus dinfos sur le fichier LC_TIME, allez voir ici
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
7. http ://us.php.net/manual/en/function.date.php

Usage Gnral

493

CakePHP Cookbook Documentation, Version 2.x

TimeHelper::nice($dateString = NULL, $timezone = NULL, $format = null)


Type retourn string
Prend une chane de date et la sort au format Tue, Jan 1st 2008, 19 :25 ou avec le param optionnel
$format :
// Appel avec TimeHelper
echo $this->Time->nice('2011-08-22 11:53:00');
// Mon, Aug 22nd 2011, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::nice('2011-08-22 11:53:00');

TimeHelper::niceShort($dateString = NULL, $timezone = NULL)


Type retourn string
Prend une chane de date et la sort au format Jan 1st 2008, 19 :25. Si lobjet date est today, le format
sera Today, 19 :25. Si lobjet date est yesterday, le format sera Yesterday, 19 :25 :
// Appel avec TimeHelper
echo $this->Time->niceShort('2011-08-22 11:53:00');
// Aug 22nd, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::niceShort('2011-08-22 11:53:00');

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::serverOffset()
Type retourn integer
Retourne la valeur du serveur partir du GMT dans les secondes.
TimeHelper::timeAgoInWords($dateString, $options = array())
Type retourn string
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')
);

494

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// 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'

Modifi dans la version 2.2 : Loption accuracy a t ajoute.


Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toAtom($dateString, $timezone = NULL)
Type retourn string
Va retourner une chane de date au format Atom 2008-01-12T00 :00 :00Z
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::toQuarter($dateString, $range = false)
Type retourn mixed
Va retourner 1, 2, 3 ou 4 dpendant du quart de lanne sur lequel la date tombe. Si range est dfini
true, un tableau deux lments va tre retourn avec les dates de dbut et de fin au format 2008-0331 :
Usage Gnral

495

CakePHP Cookbook Documentation, Version 2.x

// Appel avec TimeHelper


echo $this->Time->toQuarter('Aug 22, 2011');
// Afficherait 3
$arr = $this->Time->toQuarter('Aug 22, 2011', true);
/*
Array
(
[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.
496

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>.
Tester Time
TimeHelper::isToday($dateString, $timezone = NULL)
TimeHelper::isThisWeek($dateString, $timezone = NULL)
TimeHelper::isThisMonth($dateString, $timezone = NULL)
TimeHelper::isThisYear($dateString, $timezone = NULL)
TimeHelper::wasYesterday($dateString, $timezone = NULL)
TimeHelper::isTomorrow($dateString, $timezone = NULL)
TimeHelper::isFuture($dateString, $timezone = NULL)
Introduit dans la version 2.4.
TimeHelper::isPast($dateString, $timezone = NULL)
Introduit dans la version 2.4.
TimeHelper::wasWithinLast($timeInterval, $dateString, $timezone = NULL)
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.
Toutes les fonctions ci-dessus retourneront true ou false quand une chane de date est pass.
wasWithinLast prend une option supplmentaire $time_interval :
// Appel avec TimeHelper
$this->Time->wasWithinLast($time_interval, $dateString);
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
CakeTime::wasWithinLast($time_interval, $dateString);

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

CakePHP Cookbook Documentation, Version 2.x

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);
}
}
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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// 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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'); ?>

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'));
}

Vous pouvez aussi attacher le behavior la vole, comme ceci


$this->Post->Behaviors->attach('Acl', array('type' => 'controlled'));

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

CakePHP Cookbook Documentation, Version 2.x

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);

Ces deux exemples retourneront la mme information de nud Acl.


Si vous avez paramtr le behavior Acl (AclBehavior) pour crer la fois les noeuds ARO et ACO, vous
devez spcifier quel type de noeud vous desirez :
$this->User->id = 1;
$noeud = $this->User->node(null, 'Aro');
$user = array('User' => array(
'id' => 1
));
$noeud = $this->User->node($user, 'Aro');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

class Post extends AppModel {


public $actsAs = array('Containable');
}

Vous pouvez aussi attacher le behavior la vole :


$this->Post->Behaviors->attach('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
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

CakePHP Cookbook Documentation, Version 2.x

[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');

Vous pouvez utiliser la magie de Containable lintrieur dun appel find() :


$this->Post->find('all', array('contain' => false));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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');

Nous pouvons nouveau utiliser la cl contain dans lappel find() :


$this->Post->find('all', array('contain' => 'Tag'));

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

CakePHP Cookbook Documentation, Version 2.x

[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
(
[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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

[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

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'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.

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
Behaviors (Comportements)

513

CakePHP Cookbook Documentation, Version 2.x

invalides cause du mlange de champs agrgs et non-agrgs, essayer de dsactiver le paramtre


autoFields :
$this->Post->Behaviors->load('Containable', array('autoFields' => false));

Utiliser Containable avec la pagination En incluant le paramtre contain dans la proprit


$paginate, la pagination sera applique la fois au find(count) et au find(all) dans le model.
Voir la section Utilisation de Containable pour plus de dtails.
Voici un exemple pour limiter les associations en paginant :
$this->paginate['User'] = array(
'contain' => array('Profile', 'Account'),
'order' => 'User.username'
);
$users = $this->paginate('User');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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
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

CakePHP Cookbook Documentation, Version 2.x

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'
)
);
}

Avec ce paramtrage, le rsultat de votre $this->Post->find() devrait ressembler quelque chose


comme cela
Array
(
[Post] => Array
(
[id] => 1
[title] => Beispiel Eintrag
[body] => lorem ipsum...
[locale] => de_de
)

516

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[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
)
)
)

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.

$this->Post->bindTranslation(array('name' => 'titleTranslation'));


$this->Post->find('all', array('recursive' => 1)); // il est ncessaire d'avoir au moins un

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

CakePHP Cookbook Documentation, Version 2.x

[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
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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Exemple B : Dans votre model :


class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title'
)
);
// Option 1) just define the property directly
public $locale = 'en_us';
// Option 2) create a simple method
public function setLanguage($locale) {
$this->locale = $locale;
}
}

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)
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

CakePHP Cookbook Documentation, Version 2.x

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
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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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,
'&nbsp;&nbsp;&nbsp;'
);

522

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

debug($data); die;
}
}

et une dfinition de model encore plus simple :


// app/Model/Category.php
class Category extends AppModel {
public $actsAs = array('Tree');
}

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// 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));

Comme on pouvait sy attendre, la structure serait modifie comme suit :


My Categories
Fun
Sport
Surfing
Skating
Friends
Gerald
Gwendolyn
Work
Reports
Annual
Status
Trips
National
International
Other Peoples Categories
Extreme fishing Moved
Suppression des donnes Le behavior Tree fournit un certain nombre de faons de grer la suppression
des donnes. Pour commencer par le plus simple exemple, disons que la catgorie des rapports nest plus
utile. Pour lenlever * et tous les enfants quil peut avoir * il suffit dappeler et supprimer comme vous le
feriez pour nimporte quel model. Par exemple, avec le code suivant :
// pseudo code du controller
$this->Category->id = 10;
$this->Category->delete();

Larbre des Catgories serait modifi comme suit :


My Categories
Fun
Sport
Surfing
Skating
Friends
Gerald
Gwendolyn
Work
Trips
National
Behaviors (Comportements)

525

CakePHP Cookbook Documentation, Version 2.x

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

// Ne retourne que les enfants directs


$directChildren = $this->Category->children(1, true); // un tableau plat avec 2 lmen

Note : Si vous voulez un tableau recursif utilisez find(threaded)


childCount($id = null, $direct = false)
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 :

526

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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

generateTreeList($conditions=null, $keyPath=null, $valuePath=null, $spacer= _,


$recursive=null)
Paramtres
$conditions Utilise les mmes conditions quun find().
$keyPath Chemin du champ utiliser pour la cl.
$valuePath Chemin du champ utiliser pour le label.
$spacer La chane utiliser devant chaque lment pour indiquer la profondeur.
$recursive Le nombre de niveaux de profondeur pour rechercher les enregistrements associs.
Cette mthode retourne des donnes similaires :ref : model-find-list, avec un prfixe en retrait pour
montrer la structure de vos donnes. Voici un exemple de ce quoi vous attendre comme retour avec
cette mthode :
$treelist = $this->Category->generateTreeList();

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

CakePHP Cookbook Documentation, Version 2.x

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

getPath($id = null, $fields = null, $recursive = null)


Le path (chemin) quand vous vous rferez des donnes hirarchiques, cest le moyen retrouver o
vous tes depuis le sommet. Par exemple le path (chemin) de la catgorie International est :
My Categories
...
Work
Trips
...
International
En utilisant lid de international, getPath retournera chacun des parents rencontrs (depuis le haut) :
$parents = $this->Category->getPath(15);
// contenu de $parents
array(
[0] => array(
'Category' => array('id'
),
[1] => array(
'Category' => array('id'
),
[2] => array(
'Category' => array('id'
),
[3] => array(
'Category' => array('id'
),
)

=> 1, 'name' => 'My Categories', ..)

=> 9, 'name' => 'Work', ..)

=> 13, 'name' => 'Trips', ..)

=> 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.

528

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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);

Le noeud Sport sera retir du haut du noeud :


My Categories
Fun
Surfing
Extreme knitting
Skating
Sport Moved
Cela dmontre le behavior par dfaut du removeFromTree de dplacement dun noeud pour ne plus avoir
de parent, et de re-parenter tous les enfants.
Si toutefois lextrait de code suivant tait utilis avec lid Sport :
$this->Node->removeFromTree($id, true);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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');

Behaviors (Comportements)

531

CakePHP Cookbook Documentation, Version 2.x

// 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"

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[10] => Array


(
[0] =>
[1] =>
[2] =>
)
[99] => Array
(
[0] =>
[1] =>
[2] =>
)

"index"
123
"missing"

"node"
163
"left greater than right"

Niveau du Noeud (Profondeur)

Introduit dans la version 2.7.


Connatre la profondeur des noeuds dun arbre peut tre utile quand vous voulez rcuprer les noeuds seulement pour un certain niveau par exemple, quand vous gnrez des menus. Vous pouvez utiliser loption
level pour spcifier le champ qui sauvegardera le niveau de chaque noeud :
public $actAs = array('Tree' => array(
'level' => 'level', // Defaults to null, i.e. no level saving
));

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

CakePHP Cookbook Documentation, Version 2.x

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'
)
);
}

Vous pouvez aussi inclure dautres options find(), comme fields :


class PostsController extends AppController {
public $components = array('Paginator');
public $paginate = array(
'fields' => array('Post.id', 'Post.created'),
'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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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'));
}

Personnalisation des requtes de pagination

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

/**
* 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

CakePHP Cookbook Documentation, Version 2.x

'group' => array('week', 'home_team_id', 'away_team_id')


)
);
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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);

Ou juste en dclarant la proprit dans la classe du controller


class PostsController {
public $paginate = array();
}

Ou en utilisant $this->Paginator->setting = array(limit => 10);


Assurez-vous davoir ajout le component Paginator dans votre tableau $components si vous voulez modifier
la proprit $settings du Component Paginator.
Lune ou lautre de ces approches rsoudra les erreurs rencontrs.

Requtes en dehors des clous

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

CakePHP Cookbook Documentation, Version 2.x

}
}

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');

Les mthodes __call et set() de FlashComponent prennent de faon optionnelle un deuxime


paramtre, un tableau doptions :
540

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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') ?>

<!-- Dans app/View/Elements/Flash/success.ctp -->


<div id="flash-<?php echo h($key) ?>" class="message-info success">
<?php echo h($message) ?>: <?php echo h($params['name']) ?>, <?php echo h($params['emai
</div>

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'));

Le code ci-dessus va utiliser lelement warning.ctp dans plugins/PluginName/View/Elements/Flash


pour afficher le message flash.
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 devrez les chapper avec h lors du formatage de
vos messages flash.
Pour plus dinformations sur le rendu de vos messages flash, consultez la section FlashHelper.
Sessions
class SessionComponent(ComponentCollection $collection, array $settings = array())
Le component session de CakePHP fournit le moyen de faire persister les donnes client entre les pages
requtes. Il agit comme une interface pour $_SESSION et offre aussi des mthodes pratiques pour de
nombreuses fonctions relatives $_SESSION.
Les sessions peuvent tre paramtres de diffrentes faons dans CakePHP. Pour plus dinformation, vous
devriez lire la documentation Session configuration

Components (Composants)

541

CakePHP Cookbook Documentation, Version 2.x

Interagir avec les donnes de Session

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');

Rcupre la valeur Green de la session. La lecture de donnes inexistante retournera null.


SessionComponent::consume($name)
Lit et supprime une valeur de Session. Cest utile quand vous voulez combiner la lecture et la suppression de valeurs en une seule opration.
SessionComponent::check($name)
Utilise pour vrifier quune variable de Session a t cre. Retourne true si la variable existe et false
dans le cas contraire.
SessionComponent::delete($name)
Supprime les donnes de Session de $name. Par ex
$this->Session->delete(Person.eyeColor) ;
Notre donne de session na plus la valeur Green ni mme lindex eyeColor attribu. Cependant, le
model Person est toujours dans la Session. Pour supprimer de la session toutes les informations de
Person, utilisez
$this->Session->delete('Person');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$this->Session->destroy();

Cration de messages de notification

SessionComponent::setFlash(string $message, string $element = default, array $params


= array(), string $key = flash)
Obsolte depuis la version 2.7.0 : Vous devez utiliser Flash pour crer des messages flash. La mthode
setFlash() sera retire dans 3.0.0.
Souvent dans les applications web, vous aurez besoin dafficher des messages de notification instantans lutilisateur aprs avoir terminer un processus ou une rception de donnes. Dans CakePHP,
ceci est appel messages flash. Vous pouvez dfinir des messages flash avec le component Session et
les afficher avec le helper session SessionHelper::flash(). Pour dfinir un message, utilisez
setFlash :
// Dans le controller.
$this->Session->setFlash('Votre travail a t sauvegard !');

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');

Dans la vue, ces messages peuvent tre ressortis et styliss diffremment :


// dans la vue.
echo $this->Session->flash('bien');
echo $this->Session->flash('mal');

Le paramtre $element vous permet de contrler quel lment (localis dans


/app/View/Elements) devra tre utilis pour rendre le message. Dans llment le message est disponible en tant que $message. Dabord nous paramtrons le flash dans notre controller :
$this->Session->setFlash('truc customiss', 'flash_custom');

Components (Composants)

543

CakePHP Cookbook Documentation, Version 2.x

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')
);

La sortie en utilisant $this->Session->flash() avec lexemple ci-dessus sera :


<div id="flashMessage" class="classe_exemple">Message Exemple</div>

Pour utiliser un lment depuis un plugin spcifiez le plugin dans le $params :


// Utilisera /app/Plugin/Comment/View/Elements/flash_no_spam.ctp
$this->Session->setFlash(
'Message!',
'flash_no_spam',
array('plugin' => 'Comment')
);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

),
'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

CakePHP Cookbook Documentation, Version 2.x

Avertissement : Dans la version 2.0 $this->Auth->login($this->request->data)


connectera lutilisateur avec les donnes postes., tandis que avec la version 1.3
$this->Auth->login($this->data) tentera didentifier lutilisateur en premier et le
connectera seulement en cas de succs.

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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 Cookbook Documentation, Version 2.x

// 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

$this->Auth->authError = "Cette erreur se prsente l'utilisateur qui tente d'accder un

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

)
)
)
)
);

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

CakePHP Cookbook Documentation, Version 2.x

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');

class User extends AppModel {


public function beforeSave($options = array()) {
// fabrique un mot de passe pour l'auth Digest.
$this->data[$this->alias]['digest_hash'] = DigestAuthenticate::password(
$this->data[$this->alias]['username'], $this->data[$this->alias]['password'], e
);
return true;
}
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

public function register() {


if ($this->User->save($this->request->data)) {
$id = $this->User->id;
$this->request->data['User'] = array_merge(
$this->request->data['User'],
array('id' => $id)
);
unset($this->request->data['User']['password']);
$this->Auth->login($this->request->data['User']);
return $this->redirect('/users/home');
}
}

Avertissement : Assurez-vous dajouter manuellement le nouvel id utilisateur au tableau pass la


mthode de login. Sinon, lid utilisateur ne sera pas disponible.
Avertissement : Assurez-vous denlever les champs de mot de passe avant de passer manuellement
les donnes dans $this->Auth->login(), sinon celles-ci seront sauvegardes non hashes dans la
Session.

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

CakePHP Cookbook Documentation, Version 2.x

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'
);

Tout comme Auth->authenticate, Auth->authorize vous aident garder un code propre, en


utilisant la cl all. Cette cl spciale vous aide dfinir les paramtres qui sont passs chaque objet
attach. La cl all est aussi expose comme AuthComponent::ALL :
// passage de paramtre en utilisant 'all'
$this->Auth->authorize = array(
AuthComponent::ALL => array('actionPath' => 'controllers/'),
'Action',
'Controller'
);

554

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

AuthComponent::allow(). En marquant les actions comme publique, le component Auth ne vrifiera


pas la connexion dun utilisateur, ni nautorisera la vrification des objets
// Permet toutes les actions. CakePHP 2.0 (dprci)
$this->Auth->allow('*');
// Permet toutes les actions. CakePHP 2.1 et plus
$this->Auth->allow();
// Ne permet que les actions view et index.
$this->Auth->allow('view', 'index');
// Ne permet que les actions view et index.
$this->Auth->allow(array('view', 'index'));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

);
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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Exiger lutilisation du SSL.


Limiter les communications croises dans le controller.
Comme tous les components, il est configur au travers de plusieurs paramtres configurables. Toutes ces
proprits peuvent tre dfinies directement ou au travers de mthodes setter du mme nom dans la partie
beforeFilter de votre controller.
En utilisant le Component Security vous obtenez automatiquement une protection CSRF 9 et une protection
contre la falsification de formulaire. Des jetons de champs cachs seront automatiquement insrs dans
les formulaires et vrifis par le component Security. En outre, une soumission par formulaire ne sera pas
accepte aprs une certaine priode dinactivit, qui est contrler par le temps csrfExpires.
Si vous utilisez la fonctionnalit de protection des formulaires par le component Security et que dautres
components traitent des donnes de formulaire dans les callbacks startup(), assurez-vous de placer le
component Security avant ces components dans le tableau $components.
Note : Quand vous utilisez le component Security vous devez utiliser le Helper Form (FormHelper) pour
crer vos formulaires. De plus, vous ne devez surcharger aucun des attributs des champs name. Le
component Security regarde certains indicateurs qui sont crs et grs par le Helper form. (spcialement
ceux crs dans create()) et end()). La modification dynamique des champs qui lui sont soumis dans
une requte POST (ex. dsactiver, effacer, crer des nouveaux champs via Javascript) est susceptible de
dclencher un black-holing (envoi dans le trou noir) de la requte. Voir les paramtres de configuration de
$validatePost ou $disabledFields.

Gestion des callbacks trou noir

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

CakePHP Cookbook Documentation, Version 2.x

Le paramtre $type peut avoir les valeurs suivantes :


auth Indique une erreur de validation de formulaire, ou une incohrence controller/action.
csrf Indique une erreur CSRF.
get Indique un problme sur la mthode de restriction HTTP.
post Indique un problme sur la mthode de restriction HTTP.
put Indique un problme sur la mthode de restriction HTTP.
delete Indique un problme sur la mthode de restriction HTTP.
secure Indique un problme sur la mthode de restriction SSL.
Restreindre les mthodes HTTP

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Prvention de la falsification de formulaire

Par dfaut le component Security SecurityComponent prvient les utilisateurs de la falsification de


formulaire dans certains cas. SecurityComponent va viter les choses suivantes :
avec le Helper Form et en traquant quels champs sont dans un formulaire. il assure le suivi des lments
dentre cachs. Toutes ces donnes sont combines et haches. Quand un formulaire est soumis, le component de scurit utilisera les donnes POST pour construire la mme structure et comparer le hachage.
Les champs inconnus ne peuvent tre ajouts au formulaire.
Les champs ne peuvent tre retirs du formulaire.
Les valeurs dans les inputs cachs ne peuvent tre modifies.
La prvention de ces types de falsification est faite de concert avec FormHelper, en recherchant les champs
qui sont dans un formulaire. Les valeurs pour les champs cachs sont aussi utilises. Toutes ces donnes
sont combines et il en ressort un hash. Quand un formulaire est soumis, SecurityComponent va utiliser les
donnes POSTes pour construire la mme structure et comparer le hash.
Note : SecurityComponent ne va pas empcher aux options slectionnes dtre ajoutes/changes. Ni ne
va empcher les options radio dtre ajoutes/changes.
property SecurityComponent::$unlockedFields
Dfinit une liste de champs de formulaire exclure de la validation POST. Les champs peuvent tre
dverrouills dans le component ou avec FormHelper::unlockField(). Les champs qui ont
t dverrouills ne sont pas requis faisant parti du POST et les champs cachs dverrouills nont
pas leur valeur vrifie.
property SecurityComponent::$validatePost
Mis false pour compltement viter la validation des requtes POST, essentiellement teindre la
validation de formulaire.
configuration CSRF (Cross site request forgery)

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

public $components = array(


'Security' => array(
'csrfUseOnce' => false
)
);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// suite du controller
}

Obtenir des informations sur une requte

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
}
}
}

Dautres mthodes de dtections du contenu des requtes :


RequestHandlerComponent::isXml()
Renvoie true si la requte actuelle accepte les rponses XML.
RequestHandlerComponent::isRss()
Renvoie true si la requte actuelle accepte les rponses RSS.
RequestHandlerComponent::isAtom()
Renvoie true si lappel actuel accepte les rponses Atom, false dans le cas contraire.
RequestHandlerComponent::isMobile()
Renvoie true si le navigateur du client correspond un tlphone portable, ou si le client accepte le
contenu WAP. Les navigateurs mobiles supports sont les suivants :
Android
AvantGo
BlackBerry
DoCoMo

Components (Composants)

567

CakePHP Cookbook Documentation, Version 2.x

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

Obtenir des informations supplmentaires sur le client

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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));

Le contenu ci-dessus crera $this->request->data un tableau des donnes dentres JSON,


sans le true supplmentaire vous obtiendrez un jeu dobjets StdClass.
Rpondre Aux Requtes

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Profiter du cache de validation HTTP

Introduit dans la version 2.1.


Le model de validation de cache HTTP est lun des processus utilis pour les passerelles de cache, aussi
connu comme reverse proxies, pour dterminer si elles peuvent servir une copie de rponse stocke au
client. Daprs ce model, vous bnficiez surtout dune meilleur bande passante, mais utilis correctement
vous pouvez aussi gagner en temps de processeur, et ainsi gagner en temps de rponse.
En activant le Component RequestHandler RequestHandlerComponent dans votre controller vous
validerez le contrle automatique effectu avant de rendre une vue. Ce contrle compare lobjet rponse
la requte originale pour dterminer si la rponse na pas t modifie depuis la dernire fois que le client a
fait sa demande.
Si la rponse est value comme non modifie, alors le processus de rendu de vues est arrt, rduisant
le temps processeur. Un no content est retourn au client, augmentant la bande passante. Le code de
rponse est dfini 304 Not Modified.
Vous pouvez mettre en retrait ce contrle automatique en paramtrant checkHttpCache false :
public $components = array(
'RequestHandler' => array(
'checkHttpCache' => false
));

Utiliser les ViewClasses personnalises

Introduit dans la version 2.3.


Quand vous utilisez JsonView/XmlView, vous aurez envie peut-tre de surcharger la serialization par dfaut
avec une classe View par dfaut, ou ajouter des classes View pour dautres types.
Vous pouvez mapper les types existants et les nouveaux types vos classes personnalises.
RequestHandlerComponent::viewClassMap($type, $viewClass)
Paramtres
$type (string|array) Le type string ou un tableau map avec le format
array(json => MyJson).
$viewClass (string) La viewClass utiliser pour le type sans View en suffixe.
Vous pouvez aussi dfinir ceci automatiquement en utilisant la configuration viewClassMap :
public $components = array(
'RequestHandler' => array(
'viewClassMap' => array(
'json' => 'ApiKit.MyJson',
'xml' => 'ApiKit.MyXml',
'csv' => 'ApiKit.Csv'
)
));

Components (Composants)

571

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

public $components = array('Cookie');


public function beforeFilter() {
parent::beforeFilter();
$this->Cookie->name = 'baker_id';
$this->Cookie->time = 3600; // ou '1 hour'
$this->Cookie->path = '/bakers/preferences/';
$this->Cookie->domain = 'example.com';
$this->Cookie->secure = true; // ex. seulement envoy si on utilise un HTTPS scuris
$this->Cookie->key = 'qSI232qs*&sXOw!adre@34SAv!@*(XSL#$%)asGb$@11~_+!@#HKis~#^';
$this->Cookie->httpOnly = true;
$this->Cookie->type('aes');
}

Ensuite, regardons comment utiliser les diffrentes mthodes du Component Cookie.


Utiliser le Component

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

CakePHP Cookbook Documentation, Version 2.x

CookieComponent::read(mixed $key = null)


Cette mthode est utilise pour lire la valeur dune variable de cookie avec le nom spcifi dans $key.
// Sortie "Larry"
echo $this->Cookie->read('name');
// Vous pouvez aussi utiliser la notation par point pour lire
echo $this->Cookie->read('User.name');
// Pour prendre les variables que vous aviez groupes en utilisant
// la notation par point comme tableau, faites quelque chose comme
$this->Cookie->read('User');
// ceci retourne quelque chose comme array('name' => 'Larry', 'role' => 'Lead')

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

La Communaut de lAnneau (Refuser : tout)


Guerriers (Autoriser :Armes, Bire, Rations pour les Elfes, Porc sal)
Aragorn
Legolas
Gimli
Magiciens (Autoriser : Porc sal, Diplomatie, Bire)
Gandalf
Hobbits (Autoriser : Bire)
Frodo
Bilbo
Merry
Pippin
Visiteurs (Autoriser : Porc sal)
Gollum
Si nous voulions utiliser les ACL pour voir si Pippin tait autoris accder la bire, nous devrions
dabord rcuprer son chemin dans larbre, lequel est Communaut->Hobbits->Pippin. Ensuite nous verrions les diffrentes permissions qui rsident chacun de ces points et nous utiliserions la plus spcifique
des permissions reliant Pippin et la bire.
ARO Node
Fellowship of the Ring
Hobbits
Pippin

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

CakePHP Cookbook Documentation, Version 2.x

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

Information sur la permission


Refuse tout
Autorise la bire
Refuse la bire

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.

Note : Ceci remplace une commande dsute et dprcie, initdb.


Vous pouvez aussi vous servir du fichier SQL que vous trouverez dans app/config/sql/db_acl.sql, mais ce
sera moins sympa.
Quand ce sera fini, vous devriez avoir trois nouvelles tables dans votre systme de base de donnes : acos,
aros et aros_acos (la table de jointure pour crer les permissions entre les deux arbres).
Note : Si vous tes curieux de connaitre la faon dont CakePHP stocke linformation de larbre dans ces
tables, tudiez larbre transversal sur la base de donnes modifie. Le component ACL utilise le comportement en arbre de CakePHP pour grer les hritages darbres. Les fichiers de model de classe pour ACL sont
compils dans un seul fichier db_acl.php.

580

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

'foreign_key' => 5144,


),
7 => array(
'alias' => 'Pippin',
'parent_id' => 3,
'model' => 'User',
'foreign_key' => 1211,
),
8 => array(
'alias' => 'Gollum',
'parent_id' => 4,
'model' => 'User',
'foreign_key' => 1337,
),
);
//Faisons une itration et crons les AROs (comme des enfants)
foreach($users 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 se trouveront ici ...
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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 = '*');

Faisons un essai dans une action de controller :


public function index() {
// Tout cela renvoi true:
$this->Acl->check('guerriers/Aragorn',
$this->Acl->check('guerriers/Aragorn',
$this->Acl->check('guerriers/Aragorn',
$this->Acl->check('guerriers/Aragorn',
$this->Acl->check('guerriers/Aragorn',

'Armes');
'Armes', 'create');
'Armes', 'read');
'Armes', 'update');
'Armes', 'delete');

// Souvenez-vous, nous pouvons utiliser la syntaxe model/cl trangre


// pour nos AROs utilisateur
$this->Acl->check(array('User' => array('id' => 2356)), 'Weapons');
// Tout cela renvoi true galement:
$result = $this->Acl->check('guerriers/Legolas', 'Armes', 'create');
$result = $this->Acl->check('guerriers/Gimli', 'Armes', 'read');

// Mais ceci retourne "false" :


$result = $this->Acl->check('guerriers/Legolas', 'Armes', 'delete');
$result = $this->Acl->check('guerriers/Gimli', '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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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.

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: ?>

Helpers (Assistants)

589

CakePHP Cookbook Documentation, Version 2.x

<?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())
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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<?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.
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

CakePHP Cookbook Documentation, Version 2.x

<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">

Ce formulaire enverra les donnes votre action add() de RecipesController (RecettesController)


. Cependant, vous pouvez utiliser la mme logique pour crer et modifier des formulaires. Le helper
Form utilise la proprit $this->request->data pour dtecter automatiquement sil faut crer
un formulaire dajout ou de modification. Si $this->request->data contient un tableau nomm
daprs le model du formulaire , et que ce tableau contient une valeur non nulle pour la cl primaire
du model, alors le FormHelper crera un formulaire de modification pour cet enregistrement prcis.
Par exemple, si on va ladresse http ://site.com/recipes/edit/5, nous pourrions avoir cela :
// Controller/RecipesController.php:
public function edit($id = null) {
if (empty($this->request->data)) {
$this->request->data = $this->Recipe->findById($id);
} else {
// La logique de sauvegarde se fera ici
}
}
// View/Recipes/edit.ctp:
// 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

592

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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">

En spcifiant file cela changera la mthode de soumission post, et ajoutera un enctype


multipart/form-data dans le tag du formulaire. Vous devez lutiliser si vous avez des demandes de
fichiers dans votre formulaire. Labsence de cet attribut enctype empchera le fonctionnement de lenvoi de fichiers.
echo $this->Form->create('User', array('type' => 'file'));

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

CakePHP Cookbook Documentation, Version 2.x

$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">

ou pointer vers un domaine extrieur :


echo $this->Form->create(null, array(
'url' => 'http://www.google.com/search',
'type' => 'get'
));

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()

594

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

Vous pouvez spcifier des paramtres dtaills en passant un tableau end() :


$options = array(
'label' => 'Update',
'div' => array(
'class' => 'glass-pill',
)
);
echo $this->Form->end($options);

Affichera :
<div class="glass-pill"><input type="submit" value="Update!" name="Update"></div>

Voir lAPI du Helper Form 12 pour plus de dtails.


Note : si vous utilisez le component scurit SecurityComponent dans votre application vous
devez toujours terminer vos formulaires avec end().
Modifi dans la version 2.5 : Le paramtre $secureAttributes a t ajout dans 2.5.
Cration dlments de Formulaire

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

CakePHP Cookbook Documentation, Version 2.x

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');
echo $this->Form->input('password');
echo $this->Form->input('approved');
echo $this->Form->input('quote');

//text
//password
//day, month, year, hour, minute,
//meridian
//textarea

echo $this->Form->end('Add');

Un exemple plus complet montrant quelques options pour le champ de date :


echo $this->Form->input('birth_dt', array(
'label' => 'Date de naissance',
'dateFormat' => 'DMY',

596

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'minYear' => date('Y') - 70,


'maxYear' => date('Y') - 18,
));

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'));

Ensuite, ajouter les lignes suivantes votre vue de formulaire :


echo $this->Form->input('group_id');

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

CakePHP Cookbook Documentation, Version 2.x

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]'
));

Options FormHelper::input() supporte un nombre important doptions. En plus de ses propres


options input() accepte des options pour les champs input gnrs, comme les attributs html. Ce qui suit
va couvrir les options spcifiques de FormHelper::input().
$options[type] Vous pouvez forcer le type dun input, remplaant lintrospection du model, en
spcifiant un type. En plus des types de champs vus dans Cration dlments de Formulaire, vous pouvez
aussi crez des fichiers, password et divers types supports par HTML5 :

598

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->input('field', array('type' => 'file'));


echo $this->Form->input('email', array('type' => 'email'));

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>

Paramtrage de plusieurs attibuts :


echo $this->Form->input('User.name', array(
'div' => array(
'id' => 'mainDiv',
'title' => 'Div Title',
'style' => 'display:block'
)
));

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>

Dsactiver le rendu de la div


echo $this->Form->input('User.name', array('div' => false)); ?>

Affichera :
<label for="UserName">Name</label>
<input name="data[User][name]" type="text" value="" id="UserName" />

Helpers (Assistants)

599

CakePHP Cookbook Documentation, Version 2.x

$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>

Alternativement, dfinissez cette cl false pour dsactiver le rendu du label :


echo $this->Form->input('User.name', array('label' => false));

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 modifier le type denveloppe de llment et sa classe, utilisez le format suivant :


$this->Form->input('Model.field', array(
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'bzzz'))
));

Pour viter que le code HTML soit automatiquement chapp dans le rendu du message derreur, dfinissez la sous-option escape false :

600

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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

CakePHP Cookbook Documentation, Version 2.x

<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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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.
$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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// ...
<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" />

Ceci peut tre dsactiv en dfinissant loption $options[hiddenField] = false :


echo $this->Form->checkbox('published', array('hiddenField' => false));

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

CakePHP Cookbook Documentation, Version 2.x

<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',
));

Les options de Datetime


$options[timeFormat]. Utilis pour spcifier le format des inputs select (menu de slection)
pour un jeu dinput en relation avec le temps. Les valeurs valides sont 12, 24, et null.
$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 :
606

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<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>

FormHelper::text(string $name, array $options)


Les autres mthodes disponibles dans lHelper Form permettent la cration dlments spcifiques de
formulaire. La plupart de ces mthodes utilisent galement un paramtre spcial $options. Toutefois,
dans ce cas, $options est utilis avant tout pour spcifier les attributs des balises HTML (comme la
valeur ou lid DOM dun lment du formulaire).
echo $this->Form->text('username', array('class' => 'users'));

Affichera :
<input name="data[User][username]" type="text" class="users" id="UserUsername" />

FormHelper::password(string $fieldName, array $options)


Cration dun champ password.
echo $this->Form->password('password');

Affichera :
<input name="data[User][password]" value="" id="UserPassword" type="password">

FormHelper::hidden(string $fieldName, array $options)


Crera un form input cach. Exemple :
echo $this->Form->hidden('id');

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

CakePHP Cookbook Documentation, Version 2.x

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>

FormHelper::checkbox(string $fieldName, array $options)


Cre un lment de formulaire checkbox. Cette mthode gnre galement un input de formulaire
cach pour forcer la soumission de donnes pour le champ spcifi.
echo $this->Form->checkbox('done');

Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />

Il est possible de modifier la valeur du checkbox en utilisant le tableau $options :


echo $this->Form->checkbox('done', array('value' => 555));

Affichera :
<input type="hidden" name="data[User][done]" value="0" id="UserDone_" />
<input type="checkbox" name="data[User][done]" value="555" id="UserDone" />

Si vous ne voulez pas que le Helper Form gnre un input cach :

608

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->checkbox('done', array('hiddenField' => false));

Affichera :
<input type="checkbox" name="data[User][done]" value="1" id="UserDone" />

FormHelper::radio(string $fieldName, array $options, array $attributes)


Cre un jeu dinputs radios.
Options
$attributes[value] pour dfinir quelle valeur sera slectionne par dfaut.
$attributes[separator] pour spcifier du HTML entre les boutons (ex <br />).
$attributes[between] spcifie quelques contenus insrer entre la lgende et le premier
argument.
$attributes[disabled] dfinit a true ou disabled dsactivera tous les boutons
radios gnrs.
$attributes[legend] Les lments Radio sont envelopps avec un legend et un fieldset
par dfaut. Dfinir $attributes[legend] false pour les retirer.
$options = array('H' => 'Homme', 'F' => 'Femme');
$attributes = array('legend' => false);
echo $this->Form->radio('genre', $options, $attributes);

Affichera :
<input
<input
<label
<input
<label

name="data[User][genre]" id="UserGenre_" value="" type="hidden">


name="data[User][genre]" id="UserGenreH" value="H" type="radio">
for="UserGenreH">Homme</label>
name="data[User][genre]" id="UserGenreF" value="F" type="radio">
for="UserGenreF">Femme</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

CakePHP Cookbook Documentation, Version 2.x

$options = array('H' => 'Homme', 'F' => 'Femme');


echo $this->Form->select('genre', $options, array('escape' => false));

$attributes[options] Cette cl vous permets de spcifier manuellement des options pour


un input select (menu de slection), ou pour un groupe radio. A moins que le type soit spcifi
radio, le Helper Form supposera que la cible est un input select (menu de slection)
echo $this->Form->select('field', array(1,2,3,4,5));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

</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 :

<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][]" value="Value 1" id="ModelField1" type="check
<label for="ModelField1">Label 1</label>
</div>
<div class="checkbox">
<input name="data[Model][field][]" value="Value 2" id="ModelField2" type="check
<label for="ModelField2">Label 2</label>
</div>
</div>

$attributes[disabled] Lors de la cration de checkboxes, cette option peut tre dfini


pour dsactiver tout ou quelques checkboxes. Pour dsactiver toutes les checkboxes, dfinissez disabled true :
$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">

Helpers (Assistants)

611

CakePHP Cookbook Documentation, Version 2.x

<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.
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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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;
}

Cre un input file :


echo $this->Form->create('User', array('type' => 'file'));
echo $this->Form->file('avatar');

Affichera :
<form enctype="multipart/form-data" method="post" action="/users/add">
<input name="data[User][avatar]" value="" id="UserAvatar" type="file">

Note : Quand vous utilisez $this->Form->file(), rappelez-vous de dfinir le type dencodage , en


dfinissant loption de type file dans $this->Form->create().

Cration des boutons et des lments submits

FormHelper::submit(string $caption, array $options)


Cre un bouton submit avec la lgende $caption. Si la $caption fournie est lURL dune image
(il contient un caractre .), le bouton submit sera rendu comme une image.
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');
13. http ://php.net/features.file-upload

Helpers (Assistants)

613

CakePHP Cookbook Documentation, Version 2.x

Affichera :
<div class="submit"><input type="image" src="/img/ok.png"></div>

FormHelper::button(string $title, array $options = array())


Cre un boutton HTML avec le titre spcifi et un type par dfaut button. Dfinir
$options[type] affichera lun des trois types de boutons possibles :
1.submit : Comme celui de la mthode $this->Form->submit- (par dfaut).
2.reset : Cre un bouton reset.
3.button : Cre un bouton standard.
echo
echo
echo
echo

$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));

FormHelper::postButton(string $title, mixed $url, array $options = array ())


Cre un tag<button> avec un <form> lentourant qui soumets travers POST.
Cette mthode cre un lment <form>. Donc nutilisez pas pas cette mthode
dans
un
formulaire
ouvert.
Utilisez
plutt
FormHelper::submit()
ou :php:meth:FormHelper::button() pour crer des boutons a lintrieur de formulaires ouvert.
FormHelper::postLink(string $title, mixed $url = null, array $options = array ())
Cre un lien HTML, mais accde lUrl en utilisant la mthode POST. Requiert que JavaScript soit
autoris dans votre navigateur.
Cette mthode cre un lment <form>. Si vous souhaitez utiliser cette mthode dans un formulaire
existant, vous devez utiliser les options inline ou block pour que le nouveau formulaire soit
affich lextrieur de son formulaire parent.
Si vous cherchez un bouton pour soumettre votre formulaire, vous devrez plutt utiliser
FormHelper::submit() instead.
Modifi dans la version 2.3.
Loption method a t ajoute.
Modifi dans la version 2.5 : Les options inline et block ont t ajoutes. Elles permettent de
mettre en tampon la balise de form gnre au lieu de la retourner avec le lien. Ceci permet dviter
les balises de form imbriques. Dfinir inline => false va ajouter la balise de form en block
de contenu postLink, si vous voulez utiliser un block personnalis vous pouvez le spcifier en
utilisant plutt loption block.
614

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Modifi dans la version 2.6 : Largument $confirmMessage a t dprcie. Utilisez la cl


confirm dans $options la place.
Cre des inputs de date et dheure (date and time inputs)

FormHelper::dateTime($fieldName, $dateFormat = DMY, $timeFormat = 12, $attributes


= array())
Cre un jeu dinputs pour la date et lheure. Les valeurs valides pour $dateformat sont DMY, MDY,
YMD ou NONE. Les valeurs valides pour $timeFormat sont 12, 24, et null.
Vous pouvez spcifier de ne pas afficher les valeurs vides en paramtrant array(empty => false)
dans les paramtres des attributs. il pr-slectionnera galement les champs a la date et heure courante.
FormHelper::year(string $fieldName, int $minYear, int $maxYear, array $attributes)
Cre un lment select(menu de slection) rempli avec les annes depuis $minYear
jusqu $maxYear. Les attributs HTML devrons tre fournis dans $attributes. Si
$attributes[empty] est false, le select ninclura pas doption empty :
echo $this->Form->annee('purchased', 2000, date('Y'));

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>

FormHelper::month(string $fieldName, array $attributes)


Cre un lment select (menu de slection) avec le nom des mois :
echo $this->Form->month('mob');

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

CakePHP Cookbook Documentation, Version 2.x

<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));

FormHelper::day(string $fieldName, array $attributes)


Cre un lment select (menu de slection) rempli avec les jours (numriques) du mois.
Pour crer une option empty avec laffichage dun texte de votre choix (ex. la premire option est
Jour), vous pouvez fournir le texte comme paramtre final comme ceci :
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>

FormHelper::hour(string $fieldName, boolean $format24Hours, array $attributes)


Cre un lment select (menu de slection) rempli avec les heures de la journe.
FormHelper::minute(string $fieldName, array $attributes)
Cre un lment select (menu de slection) rempli avec les minutes dune heure.
FormHelper::meridian(string $fieldName, array $attributes)
Cre un lment select (menu de slection) rempli avec am et pm.
Afficher et vrifier les erreurs

FormHelper::error(string $fieldName, mixed $text, array $options)


Affiche un message derreur de validation, spcifie par $texte, pour le champ donn, dans le cas o
une erreur de validation a eu lieu.
Options :
escape boolen si il faut ou non que le HTML chappe le contenu de lerreur.
wrap valeur mixte dfinissant sil faut ou pas que le message derreur soit envelopper dune div. Si
cest une chane , sera utilis comme le tag HTML utiliser.
class string Le nom de classe du message derreur.

616

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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');
}

Note : En utilisant FormHelper::input(), les erreurs sont retournes par dfaut.


FormHelper::tagIsInvalid()
Retourne false si le champ fourni dcrit par lentit courante ne contient pas derreur. Sinon retourne
le message de validation.
Configuration par dfaut pour tous les champs

Introduit dans la version 2.2.


Vous pouvez dclarer un ensemble doptions par dfaut pour input() en utilisant
FormHelper::inputDefaults(). Changer les options par dfaut vous permet de consolider
les options rptes dans un appel une unique mthode :
$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() :

echo $this->Form->input('password'); // Pas de div, pas de label avec la classe 'fancy'


echo $this->Form->input('username', array('label' => 'Username')); // a un lment label av

Travailler avec le Component Scurity

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

CakePHP Cookbook Documentation, Version 2.x

$this->Form->unlockField('User.id');

FormHelper::secure(array $fields = array())


Gnre un champ cach avec hachage sur le champ utilis dans le formulaire.
Mises jour 2.0

$selected parameter removed


Le
paramtre
$selecteda t retir de plusieurs mthodes du Helper
Form (FormHelper). Toutes les mthodes supportent dsormais un cl
$attributes[value] qui devra tre utilise en remplacement de $selected. Ce changement
simplifie les mthodes du Helper Form, en rduisant le nombre darguments, et rduit les duplications que
$selected cre. Les mthodes sont :
FormHelper : :select()
FormHelper : :dateTime()
FormHelper : :year()
FormHelper : :month()
FormHelper : :day()
FormHelper : :hour()
FormHelper : :minute()
FormHelper : :meridian()
LURL par dfaut des formulaires est laction courante
LURL par dfaut pour tous les formulaires, est dsormais lURL courante incluant passed, named, et les
paramtres de la requte (querystring parameters). Vous pouvez redfinir cette valeur par dfaut en fournissant $options[url] dans le second paramtre de $this->Form->create().
FormHelper : :hidden()
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')

618

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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 :
echo $this->Html->charset('ISO-8859-1');

Affichera :
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />

HtmlHelper::css(mixed $path, array $options = array())


Modifi dans la version 2.4.
Paramtres
$path (mixed) Soit une chane du fichier CSS lier, ou un tableau avec plusieurs
fichiers.
$options (array) Un tableau doptions ou d attributs html.
Cr un ou plusieurs lien(s) vers un feuille de style CSS. Si la cl inline est dfinie false dans les
paramtres $options, les balises de lien seront ajouts au bloc css lequel sera intgr la balise
entte du document.
Vous pouvez utiliser loption block pour contrler sur lequel des blocs llment li sera ajout. Par
dfaut il sera ajout au bloc css.
Si la cl rel dans le tableau $options est dfini pour import, la feuille de style sera importe.
Cette mthode dinclusion CSS prsume que le CSS spcifi se trouve dans le rpertoire
/app/webroot/css si un chemin ne commence par un /.
Helpers (Assistants)

619

CakePHP Cookbook Documentation, Version 2.x

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

echo $this->Html->css(Blog.common.css, array(plugin => false)) ;


Modifi dans la version 2.1 : Loption block a t ajoute. Le support de syntaxe de plugin t
ajout.
HtmlHelper::meta(string $type, string $url = null, array $options = array())
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

620

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<?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'));

Modifi dans la version 2.1 : Loption block a t ajoute.


Helpers (Assistants)

621

CakePHP Cookbook Documentation, Version 2.x

HtmlHelper::docType(string $type = xhtml-strict)


Paramtres
$type (string) Le type de doctype fabriqu.
Retourne un balise doctype (X)HTML. Fournissez le doctype en suivant la table suivante :
type
valeur rsultante
html4-strict
HTML4 Strict
html4-trans
HTML4 Transitional
html4-frame HTML4 Frameset
html5
HTML5
xhtml-strict
XHTML1 Strict
xhtml-trans
XHTML1 Transitional
xhtml-frame XHTML1 Frameset
xhtml11
XHTML1.1
echo $this->Html->docType();
// Sortie:
// <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
//
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
echo $this->Html->docType('html5');
// Sortie: <!DOCTYPE html>
echo $this->Html->docType('html4-trans');
// Sortie:
// <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
//
"http://www.w3.org/TR/html4/loose.dtd">

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;

HtmlHelper::image(string $path, array $options = array())


param string $path Chemin de limage.
param array $options Un tableau de attributs html.
Cr une balise image formate. Le chemin fournit devra tre relatif /app/webroot/img/.

622

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->image('cake_logo.png', array('alt' => 'CakePHP'));

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));

Modifi dans la version 2.1 : Loption fullBase a t ajout. Le support de syntaxe de


plugin a t ajout.
HtmlHelper::link(string $title, mixed $url = null, array $options = array())
Paramtres
$title (string) Le texte afficher comme corps du lien.
$url (mixed) Soit la chane spcifiant le chemin, ou un tableau de routing.
$options (array) Un tableau d :attributs HTML.
Mthode gnrale pour la cration de liens HTML. Utilisez les $options pour spcifier les attributs
des lments et si le $title devra ou non tre chapp.

Helpers (Assistants)

623

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->link(
'Enter',
'/pages/home',
array('class' => 'button', 'target' => '_blank')
);

Affichera :
<a href="/pages/home" class="button" target="_blank">Enter</a>

Utilisez loption full_base => true pour des URLs absolues :


echo $this->Html->link(
'Dashboard',
array(
'controller' => 'dashboards',
'action' => 'index',
'full_base' => true
)
);

Affichera :
<a href="http://www.yourdomain.com/dashboards/index">Dashboard</a>

Spcifiez $confirmMessage pour afficher une boite de dialogue de confirmation confirm()


JavaScript :
echo $this->Html->link(
'Delete',
array('controller' => 'recipes', 'action' => 'delete', 6),
array(),
"Are you sure you wish to delete this recipe?"
);

Affichera :

<a href="/recipes/delete/6" onclick="return confirm('Are you sure you wish to delete t

Les chanes de requte peuvent aussi tre cres avec link().


echo $this->Html->link('View image', array(
'controller' => 'images',
'action' => 'view',
1,
'?' => array('height' => 400, 'width' => 500))
);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<?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 &quot;howdy&quot;">
<img src="/img/recipes/6.jpg" alt="Brownies" />
</a>

Modifi dans la version 2.4 : Loption escapeTitle a t ajoute.


Modifi dans la version 2.6 : Largument $confirmMessage a t dprcie. Utilisez la cl
confirm dans $options la place.
Regardez aussi la mthode HtmlHelper::url pour plus dexemples des diffrents types dURLs.
HtmlHelper::media(string|array $path, array $options)
Helpers (Assistants)

625

CakePHP Cookbook Documentation, Version 2.x

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>

HtmlHelper::tag(string $tag, string $text, array $htmlAttributes)


Paramtres
$tag (string) Le nom de la balise cre.
626

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$text (string) Le contenu de la balise.


$options (array) Un tableau dattributs html attributs html.
Retourne des textes envelopps dans une balise spcifie. Si il ny a pas de texte spcifi alors le
contenu du <tag> sera retourn :
.. code-block:: php

< ?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>

HtmlHelper::para(string $class, string $text, array $options)


Paramtres
$class (string) Le nom de classe du paragraphe.
$text (string) Le contenu du paragraphe.
$options (array) Un tableau dattributs attributs html.
Retourne un texte envelopp dans une balise CSS <p>. Si aucun texte CSS est fourni, un simple <p>
de dmarrage est retourn. :
<?php
echo $this->Html->para(null, 'Bonjour le Monde');
?>
// Affichera
<p>Bonjour le Monde</p>

Helpers (Assistants)

627

CakePHP Cookbook Documentation, Version 2.x

HtmlHelper::script(mixed $url, mixed $options)


Paramtres
$url (mixed) Soit un simple fichier Javascript, ou un tableau de chanes pour
plusieurs fichiers.
$options (array) Un tableau dattributs attributs html.
Inclus un(des) fichier(s), prsent soit localement soit une URL distante.
Par dfaut, les tags de script sont ajouts au document inline. Si vous le surcharger en configurant
$options[inline] false, les tags de script vont plutt tre ajouts au block script que
vous pouvez afficher aileurs dans le document. Si vous souhaitez surcharger le nom du block utilis,
vous pouvez le faire en configurant $options[block].
$options[once] contrle si vous voulez ou pas inclure le script une fois par requte. Par dfaut
true.
Vous pouvez utiliser $options pour dfinir des proprits supplmentaires pour la balise script gnre.
Si un tableau de balise script est utilis, les attributs seront appliqus toutes les balises script
gnres.
Cette mthode dinclusion de fichier JavaScript suppose que les fichiers JavaScript spcifis se trouvent dans le rpertoire /app/webroot/js.
echo $this->Html->script('scripts');

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');

Vous pouvez aussi lier une URL dun dpt distant :


echo $this->Html->script('http://code.jquery.com/jquery.min.js');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

$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>
</li>
<li>Spanish</li>
<li>German</li>
</ul>
</li>
</ul>

HtmlHelper::tableHeaders(array $names, array $trOptions = null, array $thOptions =


null)
Paramtres
$names (array) Un tableau de chane pour crer les enttes de tableau.
$trOptions (array) Un tableau d attributs HTML pour le <tr>.
$thOptions (array) Un tableau d attributs HTML pour llment <th>.
Cr une ligne de cellule den-tte placer dans la balise <table>.
echo $this->Html->tableHeaders(array('Date', 'Title', 'Active'));

// Affichera
<tr>
<th>Date</th>
<th>Title</th>
<th>Active</th>
</tr>

630

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

HtmlHelper::tableCells(array $data, array $oddTrOptions = null, array $evenTrOptions =


null, $useCount = false, $continueOddEven = true)
Paramtres
$data (array) Un tableau deux dimensions avec les donnes pour les lignes.
$oddTrOptions (array) Un tableau d attributs HTML pour les <tr> impairs.
$evenTrOptions (array) Un tableau d attributs HTML pour les <tr> pairs.
$useCount (boolean) Ajoute la classe column-$i.
$continueOddEven (boolean) Si false, utilisera une variable $count nonstatique, ainsi le compteur impair/pair est remis zro juste pour cet appel.
Cr des cellules de table, en assignant aux lignes des attributs <tr> diffrents pour les lignes paires
et les lignes impaires. Entoure une simple table de cellule dans un array() pour des attributs <td>
spcifiques.
echo $this->Html->tableCells(array(
array('Jul 7th, 2007', 'Best Brownies', 'Yes'),
array('Jun 21st, 2007', 'Smart Cookies', 'Yes'),
array('Aug 1st, 2006', 'Anti-Java Cake', 'No'),
));

Sortie :
Helpers (Assistants)

631

CakePHP Cookbook Documentation, Version 2.x

<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')
);

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>

HtmlHelper::url(mixed $url = NULL, boolean $full = false)


Paramtres
$url (mixed) Un tableau de routing.
$full (mixed) Soit un boolen sil faut ou pas que la base du chemin soit incluse
ou un tableau doptions pour le router Router::url().
Retourne une URL pointant vers une combinaison controller et action. Si $url est vide, cela retourne
la REQUEST_URI, sinon cela gnre la combinaison dune URL pour le controller et dune action.
Si full est true, la base complte de lURL sera ajoute en amont du rsultat :
echo $this->Html->url(array(
"controller" => "posts",
"action" => "view",
"bar"
));
// Restituera
/posts/view/bar

Voici quelques exemples supplmentaires :


URL avec des paramtres nomms :

632

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->url(array(
"controller" => "posts",
"action" => "view",
"foo" => "bar"
));
// Restituera
/posts/view/foo:bar

URL avec une extension :


echo $this->Html->url(array(
"controller" => "posts",
"action" => "list",
"ext" => "rss"
));
// Restituera
/posts/list.rss

URL (commenant par /) avec la base complte dURL ajoute :


echo $this->Html->url('/posts', true);
// Restituera
http://somedomain.com/posts

URL avec des paramtres GET et une ancre nomme :


<?php echo $this->Html->url(array(
"controller" => "posts",
"action" => "search",
"?" => array("foo" => "bar"),
"#" => "first"));
// Restituera
/posts/search?foo=bar#first

Pour plus dinformation voir Router : :url 14 dans l API.


HtmlHelper::useTag(string $tag)
Retourne un bloc existant format de balise $tag :
$this->Html->useTag(
'form',
'http://example.com',
array('method' => 'post', 'class' => 'myform')
);

Output :
<form action="http://example.com" method="post" class="myform">
14. http ://api.cakephp.org/2.4/class-Router.html#_url

Helpers (Assistants)

633

CakePHP Cookbook Documentation, Version 2.x

Changer la restitution des balises avec le Helper Html

HtmlHelper::loadConfig(mixed $configFile, string $path = null)


Les jeux de balises pour le Helper Html HtmlHelper sont conformes au standard XHTML, toutefois
si vous avez besoin de gnrer du HTML pour les standards HTML5 vous aurez besoin de crer et de
charger un nouveau fichier de configuration de balise contenant les balises que vous aimeriez utiliser.
Pour changer les balises utilises, crez un fichier app/Config/html5_tags.php contenant :
$config = array('tags' => array(
'css' => '<link rel="%s" href="%s" %s>',
'style' => '<style%s>%s</style>',
'charset' => '<meta charset="%s">',
'javascriptblock' => '<script%s>%s</script>',
'javascriptstart' => '<script>',
'javascriptlink' => '<script src="%s"%s></script>',
// ...
));

Vous
pouvez
alors
charger
ces
balises
$this->Html->loadConfig(html5_tags);.

dfinis

en

appelant

Cration dun chemin de navigation avec le Helper Html

HtmlHelper::getCrumbs(string $separator = &raquo ;, string|array|bool $startText =


false)
CakePHP inclut la possibilit de crer automatiquement un chemin de navigation (fil dAriane) dans
votre application. Pour mettre cela en service, ajouter cela dans votre template de layout :
echo $this->Html->getCrumbs(' > ', 'Home');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Avertissement : Assurez-vous de dclarer le Helper Js et son moteur en haut du tableau $helpers


dans votre controller.
Le moteur JavaScript slctionn peut disparatre (remplac par celui par dfaut) de lobjet JsHelper dans
votre helper, si vous oubliez de faire cela et vous obtiendrez du code qui ne correspond pas votre librairie
JavaScript.
Cration dun moteur Javascript

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

'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
});

JsHelper::request($url, $options = array())


Gnre un morceau de code Javascript pour crer une requte XmlHttpRequest ou AJAX.
Options de lvnement
complete - Callback lancer si complt.
success - Callback lancer en cas de succs.
before - Callback lancer linitialisation de la requte.
error - Callback lancer en cas derreur de requte.
Options
method - La mthode pour fabriquer la requte avec GET dans plus de librairies.
async - Sil faut ou pas utiliser une requte asynchrone.
data - Donnes additionnelles envoyer.
update - LID du Dom id mettre jour avec le contenu de la requte.
type - Le Type des donnes de la rponse.json et html sont supports. Par dfaut html pour la
plupart des librairies.
evalScripts - sil faut ou pas valuer la balise <script>.
dataExpression -Si la clef data doit tre traite comme un callback. Utile pour fournir
$options[data] comme une autre expression Javascript.
Exemple dutilisation :
$this->Js->event(
'click',
$this->Js->request(
array('action' => 'foo', 'param1'),
array('async' => true, 'update' => '#element')
)
);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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
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

CakePHP Cookbook Documentation, Version 2.x

$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$("#element").slider({
change:onChange,
max:10,
min:0,
orientation:"vertical",
stop:onComplete,
value:2
});

JsHelper::effect($name, $options = array())


Cr un effet basique. Par dfaut cette mthode nest pas bufferise et retourne ses rsultats.
noms des effets supports
Les effets suivants sont supports par tous les moteurs JS :
show - rvle un lment.
hide - dissimule un lment.
fadeIn - Fade in un lment.
fadeOut - Fade out un lment.
slideIn - Slide un lment in.
slideOut - Slide un lment out.
Options
speed - Vitesse laquelle lanimation devrait se produire. Les valeurs acceptes sont slow, fast.
Tous les effets nutilisent pas loption speed.
Exemple dutilisation
Si vous utilisez le moteur jQuery :
$this->Js->get('#element');
$result = $this->Js->effect('fadeIn');
// $result contient $("#foo").fadeIn();

JsHelper::event($type, $content, $options = array())


Attache un vnement la slection courante. $type peut tre un vnement DOM normal ou un type
dvnement personnalis si votre librairie les supporte. $content devrait contenir les fonctions du
body pour le callback. Les Callbacks seront envelopps avec la fonction function (event) {
... } moins quils ne soient dsactivs avec $options.
Options
wrap - Si vous souhaitez que le callback soit envelopp dans une fonction anonyme. (par dfaut
true)
stop - Si vous souhaitez que lvnement sarrte. (par dfaut true)
Exemple dutilisation :
$this->Js->get('#some-link');
$this->Js->event('click', $this->Js->alert('saperlipopette!'));

Si vous employiez la librairie jQuery, vous devriez avoir le code suivant :


$('#some-link').bind('click', function (event) {
alert(saperlipopette!');
return false;
});

Helpers (Assistants)

643

CakePHP Cookbook Documentation, Version 2.x

Vous pouvez retirer le return false; en passant loption stop false :


$this->Js->get('#some-link');
$this->Js->event(
'click',
$this->Js->alert('saperlipopette!'),
array('stop' => false)
);

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"});');

Lutilisation du moteur jQuery aurait cr le Javascript suivant :


$('div.message').each(function () { $(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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

JsHelper::submit($caption = null, $options = array())


Cr un bouton submit qui permet les formulaires de soumission XmlHttpRequest. Les options peuvent inclure soit celles de FormHelper::submit() et JsBaseEngine : :request(), JsBaseEngine : :event() ;
La soumission a travers un formulaire avec cette mthode, ne permet pas lenvoi de fichiers. Les
fichiers ne se transferts pas travers XmlHttpRequest et requirent un iframe, ou dautres paramtrages plus spcialiss qui sont hors de porte de cet helper.
Options
confirm - Message de confirmation affich avant lenvoi de la requte. Lutilisation de confirm ,
ne remplace pas les mthodes de callback before dans le XmlHttpRequest gnr.
buffer - Dsactive le buffering et retourne une balise script en plus du lien.
wrapCallbacks - Mis false pour dsactiver lenveloppement automatique des callbacks.
Exemple dutilisation :
echo $this->Js->submit('Save', array('update' => '#content'));

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
));

Montre comment vous pouvez combiner les options de FormHelper::submit() et Helper


Js::request() lutilisation des submits.
JsHelper::link($title, $url = null, $options = array())
Cr un lment ancre HTML qui a un vnement clic rattach. Les options peuvent inclure
celle pour HtmlHelper::link() et Helper Js::request(), Helper Js::event(),
$options est un tableau dattribut attributs html qui sont ajouts llment ancre gnr. Si une
option ne fait pas parti des attributs standard de $htmlAttributes elle sera passe Helper
Js::request() comme une option. Si une Id nest pas fournie, une valeur alatoire sera cre
pour chacun des liens gnrs.
Options
confirm - Gnre une boite de dialogue de confirmation avant lenvoi de lvnement.
id - utilise une id personnalise .
htmlAttributes - attributs HTML non standard supplmentaires. Les attributs standards sont
class, id, rel, title, escape, onblur et onfocus.
buffer - Dsactive le buffering et retourne une balise script en plus du lien.
Exemple dutilisation :
echo $this->Js->link(
'Page 2',
array('page' => 2),
array('update' => '#content')
);

Helpers (Assistants)

645

CakePHP Cookbook Documentation, Version 2.x

Va cr un lien pointant vers /page:2 et mettre jour #content avec la rponse.


Vous pouvez utiliser les options de htmlAttributes pour ajouter des attributs personnaliss.
echo $this->Js->link('Page 2', array('page' => 2), array(
'update' => '#content',
'htmlAttributes' => array('other' => 'value')
));
// Cr le HTML suivant
<a href="/posts/index/page:2" other="value">Page 2</a>

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

$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.

// appel par NumberHelper


$this->Number->addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals'

// appel par CakeNumber


App::uses('CakeNumber', 'Utility');
CakeNumber::addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals' =>

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

array(
'wholeSymbol'
'wholePosition'
'fractionSymbol'
'fractionPosition'
'zero'
'places'
'thousands'
'decimals'
'negative'
'escape'
'fractionExponent'
)

=>
=>
=>
=>
=>
=>
=>
=>
=>
=>
=>

'',
'before',
false,
'after',
0,
2,
',',
'.',
'()',
true,
2

NumberHelper::precision(mixed $number, int $precision = 3)


Paramtres
$number (float) La valeur convertir
$precision (integer) Le nombre de dcimal afficher
Cette mthode affiche un nombre avec le montant de prcision spcifi (place de la dcimal). Elle
arrondira afin de maintenir le niveau de prcision dfini.
// appel avec NumberHelper
echo $this->Number->precision(456.91873645, 2 );
// Sortie
456.92
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::precision(456.91873645, 2 );

NumberHelper::toPercentage(mixed $number, int $precision = 2, array $options = array())


Paramtres
$number (float) La valeur convertir.
$precision (integer) Le nombre de dcimal afficher.
$options (array) Options, voir ci-dessous.
OpDescription
tion
multiBoolen pour indiquer si la valeur doit tre multiplie par 100. Utile pour les
ply
pourcentages avec dcimal.
Comme precision(), cette mthode formate un nombre selon la prcision fournie (o les nombres sont
arrondis pour parvenir ce degr de prcision). Cette mthode exprime aussi le nombre en tant que
pourcentage et prfixe la sortie avec un signe de pourcent.
// appel avec NumberHelper. Sortie: 45.69%
echo $this->Number->toPercentage(45.691873645);
// appel avec CakeNumber. Sortie: 45.69%
App::uses('CakeNumber', 'Utility');

Helpers (Assistants)

651

CakePHP Cookbook Documentation, Version 2.x

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

NumberHelper::format(mixed $number, mixed $options=false)


Cette mthode vous donne beaucoup plus de contrle sur le formatage des nombres pour lutilisation
dans vos vues (et est utilise en tant que mthode principale par la plupart des autres mthodes de
NumberHelper). Lutilisation de cette mthode pourrait ressembler cela :
// appel avec NumberHelper
$this->Number->format($number, $options);
// appel avec CakeNumber
CakeNumber::format($number, $options);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'

NumberHelper::formatDelta(mixed $number, mixed $options=array())


Cette mthode affiche les diffrences en valeur comme un nombre sign :
// appel avec NumberHelper
$this->Number->formatDelta($number, $options);
// appel avec CakeNumber
CakeNumber::formatDelta($number, $options);

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

CakePHP Cookbook Documentation, Version 2.x

// 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'

Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.


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

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().

654

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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));

PaginatorHelper::sortDir(string $model = null, mixed $options = array())


rcupre la direction courante du tri du jeu denregistrement.
PaginatorHelper::sortKey(string $model = null, mixed $options = array())
rcupre la cl courante selon laquelle le jeu denregistrement est tri.

Helpers (Assistants)

655

CakePHP Cookbook Documentation, Version 2.x

Cration des liens de page numrots

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

Si il ny avait pas de page prcdente vous obtenez :


<span class="prev disabled"><< previous</span>

Vous pouvez changer la balise enveloppante en utilisant loption tag


echo $this->Paginator->prev(__('previous'), array('tag' => 'li'));

Sortie :
<li class="prev">
<a rel="prev" href="/posts/index/page:1/sort:title/order:desc">
previous
</a>
</li>

Vous pouvez aussi dsactiver la balise enroulante :


echo $this->Paginator->prev(__('previous'), array('tag' => false));

Output :

Helpers (Assistants)

657

CakePHP Cookbook Documentation, Version 2.x

<a class="prev" rel="prev"


href="/posts/index/page:1/sort:title/order:desc">
previous
</a>

Modifi dans la version 2.3 : Pour les mthodes : PaginatorHelper::prev() et


PaginatorHelper::next(), il est maintenant possible de dfinir loption tag false pour
dsactiver le wrapper. Les nouvelles options disabledTag ont t ajoutes.
Si vous laissez vide $disabledOptions, le paramtre $options sera utilis. Vous pouvez enregistrer
dautres saisies si les deux groupes doptions sont les mmes.
PaginatorHelper::next($title = Next >>, $options = array(), $disabledTitle = null, $disabledOptions = array())
Cette mthode est identique a prev() avec quelques exceptions. il cr le lien pointant vers la page
suivante au lieu de la prcdente. elle utilise aussi next comme valeur dattribut rel au lieu de prev.
PaginatorHelper::first($first = << first, $options = array())
Retourne une premire ou un nombre pour les premires pages. Si une chane est fournie, alors un
lien vers la premire page avec le texte fourni sera cr :
echo $this->Paginator->first('< first');

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::hasNext(string $model = null)


Retourne true si le rsultat fourni nest pas sur la dernire page.
658

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

PaginatorHelper::hasPrev(string $model = null)


Retourne true si le rsultat fourni nest pas sur la premire page.
PaginatorHelper::hasPage(string $model = null, integer $page = 1)
Retourne true si lensemble de rsultats fourni a le numro de page fourni par $page.
Cration dun compteur de page

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}'
);

En dfinissant format range donnerait en sortie 1 - 3 of 13 :


echo $this->Paginator->counter(array(
'format' => 'range'
));

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

CakePHP Cookbook Documentation, Version 2.x

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 :
$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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>

Les liens en retour de la mthode sort() du PaginatorHelper permettent au utilisateurs de cliquer


sur les enttes de table pour faire basculer lordre de tri des donnes dun champ donn.
Il est aussi possible de trier une colonne base sur des associations :
<table>
<tr>
<th><?php echo $this->Paginator->sort('titre', 'Titre'); ?></th>
<th><?php echo $this->Paginator->sort('Auteur.nom', 'Auteur'); ?></th>
</tr>
<?php foreach ($data as $recette): ?>
<tr>
<td><?php echo h($recette['Recette']['titre']); ?> </td>
15. http ://api.cakephp.org/2.4/class-PaginatorHelper.html

Helpers (Assistants)

661

CakePHP Cookbook Documentation, Version 2.x

<td><?php echo h($recette['Auteur']['nom']); ?> </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'));
// 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

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'));

Si cr dans la vue de /posts/index,


/posts/index/page :5/sort :title/direction :desc.

cela

crerait

un

lien

pointant

vers

PaginatorHelper::url($options = array(), $asArray = false, $model = null)


Paramtres
$options (array) Tableau doptions Pagination/URL. Comme utilis dans les
mthodes options() ou link().

662

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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
)
*/

PaginatorHelper::param(string $key, string $model = null)


Rcupre le paramtre de pagination spcifique partir de lensemble de rsultats pour le model
donn :
debug($this->Paginator->param('count'));
/*
(int)43
*/

Introduit dans la version 2.4 : La mthode param() a t ajoute dans 2.4.


PaginatorHelper::meta(array $options = array())
Gnre le meta-links pour un rsultat pagin :

Helpers (Assistants)

663

CakePHP Cookbook Documentation, Version 2.x

echo $this->Paginator->meta(); // Example output for page 5


/*
<link href="/?page=4" rel="prev" /><link href="/?page=6" rel="next" />
*/

Vous pouvez galement ajouter la gnration de la fcontion meta un block nomm :


$this->Paginator->meta(array('block' => true));

Si true est envoy, le block meta est utilis.


Introduit dans la version 2.6 : La mthode meta() a t ajoute dans 2.6.
RSS
class RssHelper(View $view, array $settings = array())
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');

664

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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.

API de Rss Helper

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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 :
echo $this->Session->flash();

Ce qui est au-dessus sortira un message simple, avec le HTML suivant :


<div id="flashMessage" class="message">
Vos trucs on t sauvegards.
</div>

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

CakePHP Cookbook Documentation, Version 2.x

Quand le message sort, vous pouvez choisir llment utilis pour afficher ce message :
// dans un layout.
echo $this->Session->flash('flash', array('element' => 'failure'));

Ceci utilise View/Elements/failure.ctp pour rendre le message. Le message texte sera


disponible dans une variable $message dans llment.
A lintrieur du fichier lment dchec, il y aura quelque chose comme ceci :
<div class="flash flash-failure">
<?php echo $message ?>
</div>

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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);

Output :
<p>Pour plus d\'information<br />
selon nos clbres ptes et desserts.<p>
<p>contact info@example.com</p>

Introduit dans la version 2.4.


TextHelper::highlight(string $haystack, string $needle, array $options = array())
Helpers (Assistants)

671

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'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 :
array(
'ellipsis' => '...',
'exact' => true
)

Introduit dans la version 2.3.


Exemple :

Helpers (Assistants)

673

CakePHP Cookbook Documentation, Version 2.x

$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

TextHelper::excerpt(string $haystack, string $needle, integer $radius=100, string $ending=...)


Paramtres
$haystack (string) La chane chercher.
$needle (string) La chane to excerpt around.
$radius (int) Le nombre de caractres de chaque ct de $needle que vous
souhaitez inclure.
$ending (string) Le Texte ajouter/prfixer au dbut ou la fin du rsultat.
Extrait un excerpt de $haystack surrounding the $needle avec un nombre de caractres de
chaque ct dtermin par $radius, et prefix/suffix with $ending. Cette mthode est spcialement pratique pour les rsultats recherchs. La chane requte ou les mots cls peuvent tre montrs
dans le document rsultant.
// appel avec TextHelper
echo $this->Text->excerpt($lastParagraph, 'method', 50, '...');
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::excerpt($lastParagraph, 'method', 50, '...');

Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...

674

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

TextHelper::toList(array $list, $and=and)


Paramtres
$list (array) Tableau dlments combiner dans une list sentence.
$and (string) Le mot utilis pour le dernier join.
Cre une liste spare avec des virgules, o les deux derniers items sont joins avec and.
// appel avec TextHelper
echo $this->Text->toList($colors);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::toList($colors);

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

CakePHP Cookbook Documentation, Version 2.x

);
// 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'));

Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset


utilis dans 2.1 et suivants.
TimeHelper::convertSpecifiers($format, $time = NULL)
Type retourn string
Convertit une chane de caractres reprsentant le format pour la fonction strftime et retourne un
format Windows safe et i18n aware.
TimeHelper::dayAsSql($dateString, $field_name, $timezone = NULL)
Type retourn string
Cre une chane de caractres dans le mme format que dayAsSql mais ncessite seulement un unique
objet date :
// Appel avec TimeHelper
echo $this->Time->dayAsSql('Aug 22, 2011', 'modified');
// (modified >= '2011-08-22 00:00:00') AND
// (modified <= '2011-08-22 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::dayAsSql('Aug 22, 2011', 'modified');

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.

676

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

TimeHelper::daysAsSql($begin, $end, $fieldName, $userOffset = NULL)


Type retourn string
Retourne une chane de caractres dans le format ($field_name >= 2008-01-21 00 :00 :00) AND
($field_name <= 2008-01-25 23 :59 :59). Cest pratique si vous avez besoin de chercher des enregistrements entre deux dates incluses :
// Appel avec TimeHelper
echo $this->Time->daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');
// (created >= '2011-08-22 00:00:00') AND
// (created <= '2011-08-25 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');

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

CakePHP Cookbook Documentation, Version 2.x

$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 17 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');

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::gmt($dateString = NULL)
Type retourn integer
Va retourner la date en un nombre dfini sur Greenwich Mean Time (GMT).
// Appel avec TimeHelper
echo $this->Time->gmt('Aug 22, 2011');
// 1313971200
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::gmt('Aug 22, 2011');

TimeHelper::i18nFormat($date, $format = NULL, $invalid = false, $timezone = NULL)


Type retourn string
Retourne une chane de date formate, tant donn soit un timestamp UNIX soit une chane de date
valide strtotime(). Il prend en compte le format de la date par dfaut pour le langage courant si un
fichier LC_TIME est utilis. Pour plus dinfos sur le fichier LC_TIME, allez voir ici
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
TimeHelper::nice($dateString = NULL, $timezone = NULL, $format = null)
Type retourn string
Prend une chane de date et la sort au format Tue, Jan 1st 2008, 19 :25 ou avec le param optionnel
$format :
17. http ://us.php.net/manual/en/function.date.php

678

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// Appel avec TimeHelper


echo $this->Time->nice('2011-08-22 11:53:00');
// Mon, Aug 22nd 2011, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::nice('2011-08-22 11:53:00');

TimeHelper::niceShort($dateString = NULL, $timezone = NULL)


Type retourn string
Prend une chane de date et la sort au format Jan 1st 2008, 19 :25. Si lobjet date est today, le format
sera Today, 19 :25. Si lobjet date est yesterday, le format sera Yesterday, 19 :25 :
// Appel avec TimeHelper
echo $this->Time->niceShort('2011-08-22 11:53:00');
// Aug 22nd, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::niceShort('2011-08-22 11:53:00');

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::serverOffset()
Type retourn integer
Retourne la valeur du serveur partir du GMT dans les secondes.
TimeHelper::timeAgoInWords($dateString, $options = array())
Type retourn string
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')
);

Helpers (Assistants)

679

CakePHP Cookbook Documentation, Version 2.x

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'

Modifi dans la version 2.2 : Loption accuracy a t ajoute.


Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toAtom($dateString, $timezone = NULL)
Type retourn string
Va retourner une chane de date au format Atom 2008-01-12T00 :00 :00Z
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::toQuarter($dateString, $range = false)
Type retourn mixed
Va retourner 1, 2, 3 ou 4 dpendant du quart de lanne sur lequel la date tombe. Si range est dfini
true, un tableau deux lments va tre retourn avec les dates de dbut et de fin au format 2008-0331 :
// Appel avec TimeHelper
echo $this->Time->toQuarter('Aug 22, 2011');
// Afficherait 3
$arr = $this->Time->toQuarter('Aug 22, 2011', true);
/*
Array

680

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

(
[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

CakePHP Cookbook Documentation, Version 2.x

Tester Time

TimeHelper::isToday($dateString, $timezone = NULL)


TimeHelper::isThisWeek($dateString, $timezone = NULL)
TimeHelper::isThisMonth($dateString, $timezone = NULL)
TimeHelper::isThisYear($dateString, $timezone = NULL)
TimeHelper::wasYesterday($dateString, $timezone = NULL)
TimeHelper::isTomorrow($dateString, $timezone = NULL)
TimeHelper::isFuture($dateString, $timezone = NULL)
Introduit dans la version 2.4.
TimeHelper::isPast($dateString, $timezone = NULL)
Introduit dans la version 2.4.
TimeHelper::wasWithinLast($timeInterval, $dateString, $timezone = NULL)
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.
Toutes les fonctions ci-dessus retourneront true ou false quand une chane de date est pass.
wasWithinLast prend une option supplmentaire $time_interval :
// Appel avec TimeHelper
$this->Time->wasWithinLast($time_interval, $dateString);
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
CakeTime::wasWithinLast($time_interval, $dateString);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Configuration de la classe Cache

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$plugin/Lib/Cache/Engine/MonMoteurDeCachePerso.php faisant parti dun plugin. Les


configurations de cache venant dun plugin doivent utiliser la notation par points de plugin.
Cache::config('custom', array(
'engine' => 'CachePack.MyCustomCache',
// ...
));

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

CakePHP Cookbook Documentation, Version 2.x

Incrmente un nombre dans la cl et retourne la valeur incrmente


CacheEngine::gc()
Non requise, mais utilise pour faire du nettoyage quand les ressources expirent. Le moteur FileEngine
utilise cela pour effacer les fichiers qui contiennent des contenus expirs.
CacheEngine::add($key, $value)
Dfinit une valeur dans le cache si elle nexiste pas dj. Devrait utiliser une vrification et une dfinition atomique quand cela est possible.
Introduit dans la version 2.8 : La mthode add a t ajoute dans 2.8.0.
Utilisation du Cache pour stocker le rsultat des requtes les plus courantes

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 {

public function newest() {


$result = Cache::read('newest_posts', 'longterm');
if ($result === false) {
$result = $this->find('all', array('order' => 'Post.updated DESC', 'limit' => 1
Cache::write('newest_posts', $result, 'longterm');
}
return $result;
}
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Utilisation du Cache pour stocker les compteurs

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.

Utilisation des groupes

Introduit dans la version 2.2.


Parfois vous voudrez marquer plusieurs entres de cache comme appartenant un mme groupe ou un
namespace. Cest une exigence courante pour invalider des grosses quantits de cls alors que quelques
changements dinformations sont partags pour toutes les entres dans un mme groupe. Cela est possible
en dclarant les groupes dans la configuration de cache :
Cache::config('site_home', array(
'engine' => 'Redis',
'duration' => '+999 days',
'groups' => array('comment', 'post')
));

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

CakePHP Cookbook Documentation, Version 2.x

}
}

Introduit dans la version 2.4.


Cache::groupConfigs() peut tre utilise pour rcuprer les correspondances entre le groupe et les
configurations, par ex : en ayant le mme groupe :
// Model/Post.php
/**
* Une variation de l\'exemple prcdent qui nettoie toutes les
* configurations de Cache ayant le mme groupe
*/
public function afterSave($created, $options = array()) {
if ($created) {
$configs = Cache::groupConfigs('post');
foreach ($configs['post'] as $config) {
Cache::clearGroup('post', $config);
}
}
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

}
// gnration des donnes cloud
// ...
// stockage des donne en cache
Cache::write('cloud', $cloud);
return $cloud;

static Cache::write($key, $value, $config = default)


Cache : :write() va crire $value dans le cache. Vous pouvez lire ou effacer cette valeur plus
tard en vous y rfrant avec $key.. Vous pouvez spcifier une configuration optionnelle
pour stocker le cache. Si il ny a pas de $config spcifie cest la configuration par
dfaut qui sera applique. Cache : :write() peut stocker nimporte quel type dobjet et elle
est idale pour stocker les rsultats des finds de vos models.
if (($posts = Cache::read('posts')) === false) {
$posts = $this->Post->find('all');
Cache::write('posts', $posts);
}

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

CakePHP Cookbook Documentation, Version 2.x

static Cache::add($key, $value, $config = default)


Ajoute des donnes au cache, mais seulement si la cl nexiste pas dj. Dans le cas o cette donne
existe, cette mthode va retourner false. Lorsque cest possible, les donnes sont vrifies et dfinies
de faon atomique.
Introduit dans la version 2.8 : La mthode add a t ajoute dans 2.8.0.
static Cache::clear($check, $config = default)
Dtruit toutes les valeurs en cache pour une configuration de cache. Dans les moteurs comme Apc,
Memcache et Wincache le prfixe de configuration de cache est utilis pour enlever les entres de
cache. Assurez-vous que les diffrentes configurations de cache ont un prfixe diffrent.
Cache::clearGroup($group, $config = default)
Retourne Bolen true en cas de succs.
Supprime toutes les cls du cache appartenant au mme groupe.
static Cache::gc($config)
La Garbage (Poubelle) collecte les entres dans la configuration du cache. Utilise principalement par
FileEngine. Elle doit tre mise en uvre par nimporte quel moteur de cache qui requiert des victions
manuelles de donnes de cache.
static Cache::groupConfigs($group = null)
Retourne Tableau de groupes et leurs noms de configuration lis.
Rcupre les noms de groupe pour configurer la correspondance.
static Cache::remember($key, $callable, $config = default)
Fournit une manire facile pour faire la lecture travers la mise en cache. Si la cl cache existe, elle
sera retourne. Si la cl nexiste pas, la callable sera invoque et les rsultats stocks dans le cache au
niveau de la cl fournie.
Par exemple, vous voulez souvent mettre en cache les rsultats de requte. Vous pouvez utiliser
remember() pour faciliter ceci. En supposant que vous utilisez PHP5.3 ou suprieur :
class Articles extends AppModel {
function all() {
$model = $this;
return Cache::remember('all_articles', function() use ($model){
return $model->find('all');
});
}
}

Introduit dans la version 2.5 : remember() a t ajoute dans 2.5.


CakeEmail
class CakeEmail(mixed $config = null)
CakeEmail est une nouvelle classe pour envoyer des emails. Avec cette classe, vous pouvez envoyer des
emails de nimporte quel endroit de votre application. En plus dutiliser le EmailComponent partir de vos
controllers, vous pouvez aussi envoyer des mails partir des Shells et des Models.

690

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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
);
}

La configuration ci-dessus va activer la communication STARTTLS pour les messages emails.


Introduit dans la version 2.3 : Le support pour le delivery TLS a t ajout dans 2.3.
Configurations La cls de configuration suivantes sont utilises :
from : Email ou un tableau demmeteur. Regardez CakeEmail::from().
sender : Email ou un tableau dmetteur rel. Regardez CakeEmail::sender().
to : Email ou un tableau de destination. Regardez CakeEmail::to().
cc : Email ou un tableau de copy carbon. Regardez CakeEmail::cc().
bcc : Email ou un tableau de copy carbon blind. Regardez CakeEmail::bcc().
replyTo : Email ou un tableau de repondre cet e-mail. Regardez CakeEmail::replyTo().
readReceipt : Adresse Email ou un tableau dadresses pour recevoir un rcepiss de lecture. Regardez CakeEmail::readReceipt().
returnPath : Adresse Email ou un tableau des adresses retourner si vous avez une erreur. Regardez CakeEmail::returnPath().
messageId : ID du Message de le-mail. Regardez CakeEmail::messageId().
subject : Sujet du message. Regardez CakeEmail::subject().
message : Contenu du message. Ne dfinissez pas ce champ si vous utilisez un contenu rendu.
headers : Headers inclure. Regardez CakeEmail::setHeaders().
viewRender : Si vous utilisez un contenu rendu, dfinissez le nom de classe de la vue. Regardez
CakeEmail::viewRender().
template : Si vous utilisez un contenu rendu, dfinissez le nom du template. Regardez
CakeEmail::template().
theme : Theme utilis pour le rendu du template. Voir CakeEmail::theme().
layout : Si vous utilisez un contenu rendu, dfinissez le layout rendre. Si vous voulez rendre un
template sans layout, dfinissez ce champ null. Regardez CakeEmail::template().

Utilitaires

693

CakePHP Cookbook Documentation, Version 2.x

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();

Ce qui est au-dessus utilise app/View/Emails/html/welcome.ctp pour la vue, et


app/View/Layouts/Emails/html/fancy.ctp pour le layout. Vous pouvez aussi envoyer
des messages email templat multipart :
$Email = new CakeEmail();
$Email->template('welcome', 'fancy')
->emailFormat('both')
->to('bob@example.com')
->from('app@domain.com')
->send();

Ceci utiliserait les fichiers de vue suivants :


app/View/Emails/text/welcome.ctp
694

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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));

Dans votre email template, vous pouvez utiliser ceux-ci avec :


<p>Ici est votre valeur: <b><?php echo $value; ?></b></p>

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

CakePHP Cookbook Documentation, Version 2.x

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

4.2. Vous pouvez utiliser loption contentDisposition pour dsactiver le


header Content-Disposition pour une pice jointe. Cest utile pour lenvoi dinvitations ical des clients utilisant outlook.
4.3 Au lieu de loption file, vous pouvez fournir les contenus de fichier en chane
en utilisant loption data. Cela vous permet dattacher les fichiers sans avoir besoin de chemins de fichier vers eux.
Modifi dans la version 2.3 : Loption contentDisposition a t ajoute.
Modifi dans la version 2.4 : Loption data a t ajoute.
Utiliser les transports Les Transports sont des classes destines envoyer lemail selon certain protocoles
ou mthodes. CakePHP supporte les transports Mail (par dfaut), Debug et SMTP.
Pour configurer votre mthode, vous devez utiliser la mthode CakeEmail::transport() ou avoir le
transport dans votre configuration.
Crer des Transports personnaliss Vous pouvez crer vos transports personnaliss pour intgrer avec
dautres systmes email (comme SwiftMailer). Pour crer votre transport, crez tout dabord le fichier
app/Lib/Network/Email/ExampleTransport.php (o Exemple est le nom de votre transport).
Pour commencer, votre fichier devrait ressembler cela :
App::uses('AbstractTransport', 'Network/Email');
class ExempleTransport extends AbstractTransport {
public function send(CakeEmail $Email) {
// magique l'intrieur!
}
}

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Faciliter les rgles de validation des adresses


CakeEmail::emailPattern($pattern = null)
Si vous avez des problmes de validation lors de lenvoi vers des adresses non conformes, vous pouvez
faciliter le patron utilis pour valider les adresses email. Cest parfois ncessaire quand il sagit de certains
ISP Japonais.
$email = new CakeEmail(default) ;
// Relax le patron demail, ainsi vous pouvez envoyer // vers des adresses non conformes $email>emailPattern($newPattern) ;
Introduit dans la version 2.4.
Envoyer des messages rapidement

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 :

CakeEmail::deliver('you@example.com', 'Subject', 'Message', array('from' => 'me@example.com

Cette mthode va envoyer un email you@example.com 24 , partir de me@example.com 25 avec le sujet


Subject et le contenu Message.
Le retour de deliver() est une instance de CakeEmail avec lensemble des configurations. Si vous ne
voulez pas envoyer lemail maintenant, et souhaitez configurer quelques trucs avant denvoyer, vous pouvez
passer le 5me paramtre false.
Le 3me paramtre est le contenu du message ou un tableau avec les variables (quand on utilise le contenu
rendu).
Le 4me paramtre peut tre un tableau avec les configurations ou une chane de caractres avec le nom de
configuration dans EmailConfig.
Si vous voulez, vous pouvez passer les to, subject et message null et faire toutes les configurations dans le
4me paramtre (en tableau ou en utilisant EmailConfig). Vrifiez la liste des configurations pour voir
toutes les configs acceptes.
Envoyer des emails depuis CLI

Modifi dans la version 2.2 : La mthode domain() a t ajoute dans 2.2


Quand vous envoyez des emails travers un script CLI (Shells, Tasks, ...), vous devez dfinir manuellement
le nom de domaine que CakeEmail doit utiliser. Il sera utilis comme nom dhte pour lid du message
(puisque il ny a pas de nom dhte dans un environnement CLI) :
24. you@example.com
25. me@example.com

Utilitaires

697

CakePHP Cookbook Documentation, Version 2.x

$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

Assurez vous que les classes sont charges en utilisant App::uses() :


<?php
App::uses('Folder', 'Utility');
App::uses('File', 'Utility');

Ensuite nous pouvons configurer une nouvelle instance de dossier :


<?php
$dir = new Folder('/path/to/folder');

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<?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

$element peut aussi tre un tableau :


$path = Folder::addPathElement('/a/path/for', array('testing', 'another'));
// $path gal /a/path/for/testing/another

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'));

Folder::copy(array|string $options = array())


Type retourn boolean

Utilitaires

699

CakePHP Cookbook Documentation, Version 2.x

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
}

Folder::delete(string $path = null)


Type retourn boolean
Efface de faon rcursive les rpertoires si le systme le permet :

700

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

<?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

CakePHP Cookbook Documentation, Version 2.x

[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/

$result = $Folder->inPath(WWW_ROOT . 'img' . DS, true);


// $result = true, /var/www/example/app/webroot/ est dans /var/www/example/app/webroot

static Folder::isAbsolute(string $path)


Type retourn boolean
Retourne true si le $path donn est un chemin absolu.
static Folder::isSlashTerm(string $path)
Type retourn boolean
Retourne true si le $path donn finit par un slash (par exemple. se termine-par-un-slash) :
<?php
$result = Folder::isSlashTerm('/my/test/path');
// $result = false
$result = Folder::isSlashTerm('/my/test/path/');
// $result = true

static Folder::isWindowsPath(string $path)


Type retourn boolean
Retourne true si le $path donn est un chemin Windows.
Folder::messages()
Type retourn array
Rcupre les messages de la dernire mthode.
Folder::move(array $options)
Type retourn boolean
Dplace le rpertoire de faon rcursive.

702

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

static Folder::normalizePath(string $path)


Type retourn string
Retourne un ensemble correct de slashes pour un $path donn. (\ pour les chemins Windows et /
pour les autres chemins.)
Folder::pwd()
Type retourn string
Retourne le chemin courant.
Folder::read(boolean $sort = true, array|boolean $exceptions = false, boolean $fullPath =
false)
Type retourn mixed
Paramtres
$sort (boolean) Si true, triera les rsultats.
$exceptions (mixed) Un tableau de noms de fichiers et de dossiers ignorer. Si
true ou . cette mthode va ignorer les fichiers cachs ou les fichiers commenant
par ..
$fullPath (boolean) Si true, va retourner les rsultats en utilisant des chemins
absolus.
Retourne un tableau du contenu du rpertoire courant. Le tableau retourn contient deux soustableaux : Un des repertoires et un des fichiers :
<?php
$dir = new Folder(WWW_ROOT);
$files = $dir->read(true, array('files', 'index.php'));
/*
Array
(
[0] => Array // dossiers
(
[0] => css
[1] => img
[2] => js
)
[1] => Array // fichiers
(
[0] => .htaccess
[1] => favicon.ico
[2] => test.php
)
)
*/

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

CakePHP Cookbook Documentation, Version 2.x

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

class File(string $path, boolean $create = false, integer $mode = 755)


<?php
// Cre un nouveau fichier avec les permissions 0644
$file = new File('/path/to/file.php', true, 0644);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Type retourn boolean


Supprime le Fichier.
File::executable()
Type retourn boolean
Retourne true si le Fichier est executable.
File::exists()
Type retourn boolean
Retourne true si le Fichier existe.
File::ext()
Type retourn string
Retourne lextension du Fichier.
File::Folder()
Type retourn Folder
Retourne le dossier courant.
File::group()
Type retourn integer|false
Retourne le groupe du Fichier.
File::info()
Type retourn array
Retourne linfo du Fichier.
Modifi dans la version 2.1 : File::info() inclut maintenant les informations filesize & mimetype.
File::lastAccess()
Type retourn integer|false
Retourne le dernier temps daccs.
File::lastChange()
Type retourn integer|false
Retourne le dernier temps modifi.
File::md5(integer|boolean $maxsize = 5)
Type retourn string
Rcupre la MD5 Checksum du fichier avec la vrification prcdente du Filesize.
File::name()
Type retourn string
Retourne le nom du Fichier sans lextension.
File::offset(integer|boolean $offset = false, integer $seek = 0)
Type retourn mixed
Utilitaires

705

CakePHP Cookbook Documentation, Version 2.x

Dfinit ou rcupre loffset pour le fichier ouvert.


File::open(string $mode = r, boolean $force = false)
Type retourn boolean
Ouvre le fichier courant avec un $mode donn.
File::owner()
Type retourn integer
Retourne le propritaire du Fichier.
File::perms()
Type retourn string
Retourne le chmod (permissions) du Fichier.
static File::prepare(string $data, boolean $forceWindows = false)
Type retourn string
Prpare une chane de caractres ascii pour lcriture. Convertit les lignes de fin en un terminator
correct pour la plateforme courante. Si cest Windows rn sera utilis, toutes les autres plateformes
utiliseront n
File::pwd()
Type retourn string
Retourne un chemin complet du Fichier.
File::read(string $bytes = false, string $mode = rb, boolean $force = false)
Type retourn string|boolean
Retourne les contenus du Fichier en chane de caractre ou retourne false en cas dchec.
File::readable()
Type retourn boolean
Retourne true si le Fichier est lisible.
File::safe(string $name = null, string $ext = null)
Type retourn string
Rend le nom de fichier bon pour la sauvegarde.
File::size()
Type retourn integer
Retourne le Filesize.
File::writable()
Type retourn boolean
Retourne si le Fichier est ouvert en criture.
File::write(string $data, string $mode = w, boolean$force = false)
Type retourn boolean
Ecrit le $data donn dans le Fichier.
706

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Introduit dans la version 2.1 : File::mime().


File::mime()
Type retourn mixed
Rcupre le mimetype du Fichier, retourne false en cas dchec.
File::replaceText($search, $replace)
Type retourn boolean
Remplace le texte dans un fichier. Retourne false en cas dchec et true en cas de succs.
Introduit dans la version 2.5 : File::replaceText()
Hash
class Hash
Introduit dans la version 2.2.
La gestion du tableau, si elle est bien faite, peut tre un outil trs puissant et utile pour construire du code
plus intelligent et plus optimis. CakePHP offre un ensemble dutilitaires statiques trs utile dans la classe
Hash qui vous permet de faire justement cela.
La classe Hash de CakePHP peut tre appele partir de nimporte quel model ou controller de la mme
faon que pour un appel Inflector Exemple : Hash::combine().
Syntaxe de chemin Hash

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

Reprsente une cl numrique. Va matcher toute chane ou cl numrique.


Reprsente une chane. Va matcher toute valeur de chane y compris les valeurs de ch
numrique.
Matche les cls avec exactement la mme valeur keys with the exact same value.

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

CakePHP Cookbook Documentation, Version 2.x

Les Types dAttribut Correspondants

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,...);

static Hash::insert(array $data, $path, $values = null)


Type retourn array
Insre $data dans un tableau tel que dfini dans $path :
$a = array(
'pages' => array('name' => 'page')
);
$result = Hash::insert($a, 'files', array('name' => 'files'));
// $result ressemble maintenant :
Array
(
[pages] => Array
(
[name] => page
)
[files] => Array

708

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

(
[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

CakePHP Cookbook Documentation, Version 2.x

'name' => 'Mariano Iglesias'


)
)
),
array(
'User' => array(
'id' => 14,
'group_id' => 2,
'Data' => array(
'user' => 'phpnut',
'name' => 'Larry E. Masters'
)
)
),
);
$result = Hash::combine($a, '{n}.User.id');
/* $result ressemble maintenant :
Array
(
[2] =>
[14] =>
)
*/
$result = Hash::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
)
)
/
*
$result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name');
/* $result ressemble maintenant :
Array
(
[2] => Mariano Iglesias
[14] => Larry E. Masters
)
*/
$result = Hash::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
/* $result ressemble maintenant :

710

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Array
(
[1] => Array
(
[2] => Array
(
[user]
[name]
)
)
[2] => Array
(
[14] => Array
(
[user]
[name]
)
)
)

=> mariano.iglesias
=> Mariano Iglesias

=> phpnut
=> Larry E. Masters

*/

$result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');


/* $result ressemble maintenant :
Array
(
[1] => Array
(
[2] => Mariano Iglesias
)
[2] => Array
(
[14] => 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

CakePHP Cookbook Documentation, Version 2.x

(
[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
)
*/

static Hash::format(array $data, array $paths, $format)


Type retourn array
Retourne une srie de valeurs extraites dun tableau, format avec un format de chane de caractres :
$data = array(
array(
'Person' => array(
'first_name' => 'Nate',
'last_name' => 'Abele',
'city' => 'Boston',
'state' => 'MA',
'something' => '42'
)
),
array(
'Person' => array(
'first_name' => 'Larry',
'last_name' => 'Masters',
'city' => 'Boondock',
'state' => 'TN',
'something' => '{0}'
)
),
array(
'Person' => array(
'first_name' => 'Garrett',
'last_name' => 'Woodworth',
'city' => 'Venice Beach',
'state' => 'CA',
'something' => '{1}'
)
)
);

712

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$res = Hash::format($data, array('{n}.Person.first_name', '{n}.Person.something'), '%2


/*
Array
(
[0] => 42, Nate
[1] => 0, Larry
[2] => 0, Garrett
)
*/

$res = Hash::format($data, array('{n}.Person.first_name', '{n}.Person.something'), '%1


/*
Array
(
[0] => Nate, 42
[1] => Larry, 0
[2] => Garrett, 0
)
*/

static Hash::contains(array $data, array $needle)


Type retourn boolean
Dtermine si un Hash ou un tableau contient les cls et valeurs exactes dun autre :
$a = array(
0 => array('name'
1 => array('name'
);
$b = array(
0 => array('name'
1 => array('name'
2 => array('name'
'a' => 'b'
);

=> 'main'),
=> 'about')

=> 'main'),
=> 'about'),
=> 'contact'),

$result = Hash::contains($a, $a);


// true
$result = Hash::contains($a, $b);
// false
$result = Hash::contains($b, $a);
// true

static Hash::check(array $data, string $path = null)


rtype boolean
Vrifie si un chemin particulier est dfini dans un tableau :
$set = array(
'My Index 1' => array('First' => 'The first item')
);
$result = Hash::check($set, 'My Index 1.First');
// $result == True

Utilitaires

713

CakePHP Cookbook Documentation, Version 2.x

$result = Hash::check($set, 'My Index 1');


// $result == True
$set = array(
'My Index 1' => array('First' =>
array('Second' =>
array('Third' =>
array('Fourth' => 'Heavy. Nesting.'))))
);
$result = Hash::check($set, 'My Index 1.First.Second');
// $result == True
$result = Hash::check($set, 'My Index 1.First.Second.Third');
// $result == True
$result = Hash::check($set, 'My Index 1.First.Second.Third.Fourth');
// $result == True
$result = Hash::check($set, 'My Index 1.First.Seconds.Third.Fourth');
// $result == False

static Hash::filter(array $data, $callback = array(Hash, filter))


Type retourn array
Filtre les lments vides en dehors du tableau, en excluant 0. Vous pouvez aussi fournir un $callback
personnalis pour filtrer les lments de tableau. Votre callback devrait retourner false pour retirer
les lments du tableau rsultant :
$data = array(
'0',
false,
true,
0,
array('one thing', 'I can tell you', 'is you got to be', false)
);
$res = Hash::filter($data);
/* $data ressemble maintenant :
Array (
[0] => 0
[2] => true
[3] => 0
[4] => Array
(
[0] => one thing
[1] => I can tell you
[2] => is you got to be
)
)
*/

static Hash::flatten(array $data, string $separator = .)


Type retourn array
714

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Rduit un tableau multi-dimensionnel en un tableau une seule dimension :


$arr = array(
array(
'Post' => array('id' => '1', 'title' => 'First Post'),
'Author' => array('id' => '1', 'user' => 'Kyle'),
),
array(
'Post' => array('id' => '2', 'title' => 'Second Post'),
'Author' => array('id' => '3', 'user' => 'Crystal'),
),
);
$res = Hash::flatten($arr);
/* $res ressemble maintenant :
Array (
[0.Post.id] => 1
[0.Post.title] => First Post
[0.Author.id] => 1
[0.Author.user] => Kyle
[1.Post.id] => 2
[1.Post.title] => Second Post
[1.Author.id] => 3
[1.Author.user] => Crystal
)
*/

static Hash::expand(array $data, string $separator = .)


Type retourn array
Dveloppe un tableau qui a dj t aplatie avec Hash::flatten() :
$data = array(
'0.Post.id' => 1,
'0.Post.title' => First Post,
'0.Author.id' => 1,
'0.Author.user' => Kyle,
'1.Post.id' => 2,
'1.Post.title' => Second Post,
'1.Author.id' => 3,
'1.Author.user' => Crystal,
);
$res = Hash::expand($data);
/* $res ressemble maintenant :
array(
array(
'Post' => array('id' => '1', 'title' => 'First Post'),
'Author' => array('id' => '1', 'user' => 'Kyle'),
),
array(
'Post' => array('id' => '2', 'title' => 'Second Post'),
'Author' => array('id' => '3', 'user' => 'Crystal'),
),
);
*/

Utilitaires

715

CakePHP Cookbook Documentation, Version 2.x

static Hash::merge(array $data, array $merge[, array $n ])


Type retourn array
Cette fonction peut tre vue comme un hybride entre le array_merge
array_merge_recursive de PHP. La diffrence entre les deux est que si une
tableau contient un autre tableau, alors la fonction se comporte de faon rcursive (pas
array_merge) mais ne le fait pas pour les cls contenant les chanes de caractres (pas
array_merge_recursive).

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
)
*/

static Hash::numeric(array $data)


716

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Type retourn boolean


Vrifie pour voir si toutes les valeurs dans le tableau sont numriques :
$data = array('one');
$res = Hash::numeric(array_keys($data));
// $res est true
$data = array(1 => 'one');
$res = Hash::numeric($data);
// $res est false

static Hash::dimensions(array $data)


Type retourn integer
Compte les dimensions dun tableau. Cette mthode va seulement considrer la dimension du premier
lment dans le tableau :
$data = array('one', '2', 'three');
$result = Hash::dimensions($data);
// $result == 1
$data = array('1' => '1.1', '2', '3');
$result = Hash::dimensions($data);
// $result == 1
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1'));
$result = Hash::dimensions($data);
// $result == 2
$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Hash::dimensions($data);
// $result == 1

$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => array('3.1.1'
$result = Hash::dimensions($data);
// $result == 2

static Hash::maxDimensions(array $data)


Similaire dimensions(), cependant cette mthode retourne le nombre le plus profond de dimensions de tout lment dans le tableau :
$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Hash::maxDimensions($data, true);
// $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

static Hash::map(array $data, $path, $function)


Cre un nouveau tableau, en extrayant $path, et mappe $function travers les rsultats. Vous pouvez
utiliser les deux, expression et le matching dlments avec cette mthode :

Utilitaires

717

CakePHP Cookbook Documentation, Version 2.x

//appel de la fonction noop $this->noop() sur chaque element de $data


$result = Hash::map($data, "{n}", array($this, 'noop'));
function noop($array) {
//fait des trucs au tableau et retourne les rsultats
return $array;
}

static Hash::reduce(array $data, $path, $function)


Cre une valeur unique, en extrayant $path, et en rduisant les rsultats extraits avec $function. Vous
pouvez utiliser les deux, expression et le matching dlments avec cette mthode.
static Hash::apply(array $data, $path, $function)
Appliquer un callback un ensemble de valeurs extraites en utilisant $function. La fonction va
rcuprer les valeurs extraites en premier argument.
static Hash::sort(array $data, $path, $dir, $type = regular)
Type retourn array
Trie un tableau selon nimporte quelle valeur, dtermin par une Syntaxe de chemin Hash. Seuls les
lments de type expression sont supports par cette mthode :
$a = array(
0 => array('Person' => array('name' => 'Jeff')),
1 => array('Shirt' => array('color' => 'black'))
);
$result = Hash::sort($a, '{n}.Person.name', 'asc');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[Shirt] => Array
(
[color] => black
)
)
[1] => Array
(
[Person] => Array
(
[name] => Jeff
)
)
)
*/

$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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')

$result = Hash::diff($a, $b);


/* $result ressemble maintenant :
Array
(
[2] => Array
(
[name] => contact
)
)
/
*

static Hash::mergeDiff(array $data, array $compare)


Type retourn array
Cette fonction fusionne les deux tableaux et pousse les diffrences dans les donnes la fin du tableau
rsultant.
Exemple 1

$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

CakePHP Cookbook Documentation, Version 2.x

$array1 = array("a" => "b", 1 => 20938, "c" => "string");


$array2 = array("b" => "b", 3 => 238, "c" => "string", array("extra_field"));
$res = Hash::mergeDiff($array1, $array2);
/* $res ressemble maintenant :
Array
(
[a] => b
[1] => 20938
[c] => string
[b] => b
[3] => 238
[4] => Array
(
[0] => extra_field
)
)
*/

static Hash::normalize(array $data, $assoc = true)


Type retourn array
Normalise un tableau. Si $assoc est true, le tableau rsultant sera normalis en un tableau associatif. Les cls numriques avec les valeurs, seront convertis en cls de type chane avec des valeurs
null. Normaliser un tableau, facilite lutilisation des rsultats avec Hash::merge() :
$a = array('Tree', 'CounterCache',
'Upload' => array(
'folder' => 'products',
'fields' => array('image_1_id', 'image_2_id')
)
);
$result = Hash::normalize($a);
/* $result ressemble maintenant :
Array
(
[Tree] => null
[CounterCache] => null
[Upload] => Array
(
[folder] => products
[fields] => Array
(
[0] => image_1_id
[1] => image_2_id
)
)
)
*/
$b = array(
'Cacheable' => array('enabled' => false),
'Limit',
'Bindable',

720

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'Validator',
'Transactional'
);
$result = Hash::normalize($b);
/* $result ressemble maintenant :
Array
(
[Cacheable] => Array
(
[enabled] => false
)
[Limit] => null
[Bindable] => null
[Validator] => null
[Transactional] => null
)
*/

static Hash::nest(array $data, array $options = array())


Prend un ensemble de tableau aplati, et cre une structure de donnes imbrique ou chane. Utilis
par des mthodes comme Model::find(threaded).
Options :
children Le nom de la cl utiliser dans lensemble de rsultat pour les enfants. Par dfaut
children.
idPath Le chemin vers une cl qui identifie chaque entre. Doit tre compatible avec
Hash::extract(). Par dfaut {n}.$alias.id
parentPath Le chemin vers une cl qui identifie le parent de chaque entre. Doit tre compatible
avec Hash::extract(). Par dfaut {n}.$alias.parent_id.
root Lid du rsultat le plus dsir.
Exemple :
$data = array(
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
);

=>
=>
=>
=>
=>
=>
=>
=>
=>
=>

array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'
array('id'

=>
=>
=>
=>
=>
=>
=>
=>
=>
=>

1, 'parent_id' => null)),


2, 'parent_id' => 1)),
3, 'parent_id' => 1)),
4, 'parent_id' => 1)),
5, 'parent_id' => 1)),
6, 'parent_id' => null)),
7, 'parent_id' => 6)),
8, 'parent_id' => 6)),
9, 'parent_id' => 6)),
10, 'parent_id' => 6))

$result = Hash::nest($data, array('root' => 6));


/* $result ressemble maintenant :
array(
(int) 0 => array(
'ModelName' => array(
'id' => (int) 6,
'parent_id' => null

Utilitaires

721

CakePHP Cookbook Documentation, Version 2.x

),
'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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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'));

HttpSocket::post($uri, $data, $request)


La mthode post fait une simple requte HTTP POST retournant les rsultats.
Les paramtres pour la mthode post sont presque les mmes que pour la mthode get, $uri est
ladresse web o la requte a t faite ; $query est la donne poster, que ce soit en chane, ou en
un tableau de cls et de valeurs :
App::uses('HttpSocket', 'Network/Http');
$HttpSocket = new HttpSocket();
// donne en chane
$results = $HttpSocket->post(
'http://example.com/add',
'name=test&type=user'
);
// donne en tableau
$data = array('name' => 'test', 'type' => 'user');
$results = $HttpSocket->post('http://example.com/add', $data);

HttpSocket::put($uri, $data, $request)


La mthode put fait une simple requte HTTP PUT retournant les rsultats.
Les paramtres pour la mthode put est la mme que pour la mthode post().
HttpSocket::delete($uri, $query, $request)
La mthode delete fait une requte simple HTTP DELETE retournant les rsultats.
Les paramtres pour la mthode delete sont les mmes que pour la mthode get(). Le paramtre
$query peut soit tre une chane, soit un tableau darguments dune recherche sous forme de chane
pour la requte.
HttpSocket::patch($uri, $data, $request)
La mthode patch fait une simple requte HTTP PATCH retournant les rsultats.
Les paramtres pour la mthode patch sont les mmes que pour la mthode post().
Introduit dans la version 2.4.
HttpSocket::request($request)
La mthode request de base qui est appele partir de tous les wrappers (get, post, put, delete).
Retourne les rsultats de la requte.
$request est un tableau cl avec des options diverses. Voici le format et les configurations par dfaut :

Utilitaires

723

CakePHP Cookbook Documentation, Version 2.x

public $request = array(


'method' => 'GET',
'uri' => array(
'scheme' => 'http',
'host' => null,
'port' => 80,
'user' => null,
'pass' => null,
'path' => null,
'query' => null,
'fragment' => null
),
'auth' => array(
'method' => 'Basic',
'user' => null,
'pass' => null
),
'version' => '1.1',
'body' => '',
'line' => null,
'header' => array(
'Connection' => 'close',
'User-Agent' => 'CakePHP'
),
'raw' => null,
'redirect' => false,
'cookies' => array()
);

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;

HttpResponse a les attributs suivants :


26. http ://php.net/manual/en/class.arrayaccess.php
27. http ://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring

724

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

body retourne le corps de la rponse HTTP (normalement le HTML).


headers retourne un tableau avec les headers.
cookies retourne un tableau avec les nouveaux cookies (les cookies des autres requtes ne sont pas
stocks ici).
httpVersion retourne une chane avec la version de HTTP ( partir de la premire ligne dans la
rponse).
code retourne linteger avec le code HTTP.
reasonPhrase retourne la chane avec la rponse du code HTTP.
raw retourne la rponse non change du serveur.
HttpResponse expose aussi les mthodes suivantes :
body() retourne le corps.
isOk() retourne si le code est 200 ;
isRedirect() retourne si le code est 301, 302, 303 or 307 et la localisation du header est dfinie.
getHeader() vous permet de rcuprer les headers, voir la prochaine section.
Obtenir des headers partir dune rponse Suivant les autres places dans le coeur, HttpSocket ne
change pas le cas des headers. RFC 2616 28 indique que les headers sont insensibles la casse, et HttpSocket
prserve les valeurs que lhte distant envoie :
HTTP/1.1 200 OK
Date: Mon, 16 Apr 2007 04:14:16 GMT
server: CakeHttp Server
content-tyPe: text/html

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

Vous pouvez rcuprer les headers ci-dessus en appelant :


// $response est une instance de HttpResponse
// rcupre le header Content-Type.
$response->getHeader('Content-Type');
// Rcupre la date
$response->getHeader('date');

Les headers peuvent tre rcuprs case-insensitively.


Grer automatiquement une rponse de redirection Quand la rponse a un code de statut de redirection
valide (voir HttpResponse::isRedirect), une requte supplmentaire peut tre automatiquement
fate selon le header Location reu :
28. http ://tools.ietf.org/html/rfc2616.html

Utilitaires

725

CakePHP Cookbook Documentation, Version 2.x

<?php
App::uses('HttpSocket', 'Network/Http');

$HttpSocket = new HttpSocket();


$response = $HttpSocket->get('http://example.com/redirecting_url', array(), array('redirect

Loption redirect peut prendre les valeurs suivantes.


true : toutes les rponses de redirection vont entraner une nouvelle requte consquente.
integer : La valeur dfinie est le nombre maximum de redirections autorises (aprs lavoir atteint, la
valeur de redirect est considere comme false)
false (par dfaut) : aucune requte consquente ne sera fired.
La $response retourne sera la dernire, selon les paramtres.
Grer les certificats SSL Quand vous faites des requtes vers des services en SSL, HttpSocket va sattendre valider le certificat SSL en utilisant la validation peer. Si le certificat choue la validation peer ou
ne correspond pas au nom dhte quon souhaite accder, la connexion va chouer, et une exception va tre
lance. Par dfaut HttpSocket va utiliser le fichier dautorit du certificat mozilla pour vrifier les certificats
SSL. Vous pouvez utiliser les options suivantes pour configurer la faon dont les certificats sont grs :
ssl_verify_peer Dfini false pour dsactiver la vrification SSL. Ce nest pas recommand.
ssl_verify_host Dfini false si vous souhaitez ignorer les erreurs de correspondance du nom
dhte.
ssl_allow_self_signed Dfini true pour activer les certificats que lon accepte soi-mme. Cela
ncessite que ssl_verify_peer soit activ.
ssl_cafile Dfini au chemin absolu du fichier de lAutorit de Certification que vous souhaitez
utiliser pour vrifier les certificats SSL.
Ces options sont fournies dans les arguments du constructeur :
$socket = new HttpSocket(array(
'ssl_allow_self_signed' => true
));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Avant votre requte, vous devrez changer la proprit responseClass :


App::uses('HttpSocket', 'Network/Http');
$http = new HttpSocket();
$http->responseClass = 'YourResponse';

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

CakePHP Cookbook Documentation, Version 2.x

*
* @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');

La mthode authentication() va tre appele pour ajouter aux headers de la requte.


Utiliser un HttpSocket avec un proxy En tant que configuration de auth, vous pouvez configurer une
authentification de proxy. Vous pouvez crer votre mthode personnalise pour authentifier le proxy dans la
mme classe dauthentification. Par exemple :
class YourMethodAuthentication {

/**
* 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
}
}

Note : Pour utiliser un proxy, vous devez appeler HttpSocket::configProxy() semblable


HttpSocket::configAuth().

728

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Input : apple pure


Output : apple_puree
static Inflector::reset
Remet lInflector son tat initial, utile pour les tests.
static Inflector::rules($type, $rules, $reset = false)
Dfinit de nouvelles rgles dinflection et de translitration utiliser pour Inflector. Regardez Configuration de Inflection pour plus dinformations.
Internationalisation & Localisation
Lune des meilleurs faons pour que votre application ait une audience plus large est de grer plusieurs
langues. Cela peut souvent se rvler tre une tche gigantesque, mais les fonctionnalits dinternationalisation et de localisation dans CakePHP rendront cela plus facile.
Dabord il est important de comprendre quelques terminologies. Internationalisation se rfre a la possibilit
qua une application dtre localise. Le terme localisation se rfre ladaptation qua une application de
rpondre aux besoins dune langue (ou culture) spcifique (par ex : un locale). Linternationalisation et
la localisation sont souvent abrges en respectivement i18n et l10n ; 18 et 10 sont le nombre de caractres
entre le premier et le dernier caractre.
Internationaliser Votre Application

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

/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

Et pour les autres langues par rapport celle par dfaut :


/app/Plugin/DebugKit/Locale/eng/LC_MESSAGES/debug_kit.po (English)
/app/Plugin/DebugKit/Locale/fra/LC_MESSAGES/debug_kit.po (French)
/app/Plugin/DebugKit/Locale/por/LC_MESSAGES/debug_kit.po (Portuguese)

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);

Dfini false par dfaut.


Introduit dans la version 2.6.
35. https ://github.com/cakephp/localized

732

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Localisation dans CakePHP

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

CakePHP Cookbook Documentation, Version 2.x

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'
)
)
)
}

Ce qui va faire lappel interne suivant :


__d('validation', 'Username devrait tre entre %d et %d caractres', array(2, 10));

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

(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

CakePHP Cookbook Documentation, Version 2.x

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.

Journalisation des Erreurs et des Exception

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

Vous pouvez interroger le flux configurs avec CakeLog::configured(). Le retour de


configured() est un tableau de tous les flux actuellement configurs. Vous pouvez rejeter des flux en
utilisant CakeLog::drop(). Une fois que le flux dun log t rejet il ne recevra plus de messages.
Utilisation de la classe par dfaut FileLog

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Introduit dans la version 2.4.


Dans les environnements de production, il est fortement recommand que vous configuriez votre systme
pour utiliser syslog plutt que le logger de fichiers. Cela va fonctionner bien mieux que ceux crits et sera
fait (presque) dune manire non-blocking et le logger de votre systme dexploitation peut tre configur
sparment pour faire des rotations de fichier, pr-lancer les critures ou utiliser un stockage compltement
diffrent pour vos logs.
Utiliser syslog est peu prs comme utiliser le moteur par dfaut FileLog, vous devez juste spcifier Syslog
comme moteur utiliser pour la journalisation. Le bout de configuration suivant va remplacer le logger par
dfaut avec syslog, ceci va tre fait dans le fichier bootstrap.php :
CakeLog::config('default', array(
'engine' => 'Syslog'
));

Utilitaires

737

CakePHP Cookbook Documentation, Version 2.x

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

Introduit dans la version 2.2.


Souvent, vous voudrez configurer diffrents comportements de journalisation pour diffrents sous-systmes
ou parties de votre application. Prenez lexemple dun magasin e-commerce. Vous voudrez probablement
grer la journalisation pour les commandes et les paiements diffremment des autres oprations de journalisation moins critiques.

738

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

static CakeLog::write($level, $message, $scope = array())


crit un message dans tous les loggers configurs. $log indique le type de message cr. $message est
le message de lentre de log en cours dcriture.
Modifi dans la version 2.2 : $scope a t ajout.
Introduit dans la version 2.2 : Log levels et scopes
static CakeLog::levels
Appelle cette mthode sans arguments, ex : CakeLog::levels() pour obtenir un niveau de configuration actuel.
Pour ajouter les niveaux supplmentaires user0 et user1 aux niveaux de log par dfaut, utilisez :
CakeLog::levels(array('user0', 'user1'));
// ou
CakeLog::levels(array('user0', 'user1'), true);

Calling CakeLog::levels() va entraner :


array(
0 => 'emergency',
1 => 'alert',
// ...
8 => 'user0',
9 => 'user1',
);

Pour dfinir/remplcaer une configuration existante, passez un tableau avec le second argument dfini
false :
CakeLog::levels(array('user0', 'user1'), false);

Calling CakeLog::levels() va entraner :


array(
0 => 'user0',
1 => 'user1',
);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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');

public function afterLogin() {


App::uses('CakeNumber', 'Utility');
$storageUsed = $this->Auth->user('storage_used');
if ($storageUsed > 5000000) {
// notify users of quota
$this->Session->setFlash(__('You are using %s storage', CakeNumber::toReadableS

Utilitaires

741

CakePHP Cookbook Documentation, Version 2.x

}
}
}

Introduit dans la version 2.1 : CakeNumber a t refondu partir de NumberHelper.


Toutes ces fonctions retournent le nombre format ; Elles naffichent pas automatiqement la sortie dans la
vue.
CakeNumber::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 :

742

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.

// appel par NumberHelper


$this->Number->addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals'

// appel par CakeNumber


App::uses('CakeNumber', 'Utility');
CakeNumber::addFormat('BRL', array('before' => 'R$', 'thousands' => '.', 'decimals' =>

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

CakeNumber::precision(mixed $number, int $precision = 3)


Paramtres
744

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$number (float) La valeur convertir


$precision (integer) Le nombre de dcimal afficher
Cette mthode affiche un nombre avec le montant de prcision spcifi (place de la dcimal). Elle
arrondira afin de maintenir le niveau de prcision dfini.
// appel avec NumberHelper
echo $this->Number->precision(456.91873645, 2 );
// Sortie
456.92
// appel avec CakeNumber
App::uses('CakeNumber', 'Utility');
echo CakeNumber::precision(456.91873645, 2 );

CakeNumber::toPercentage(mixed $number, int $precision = 2, array $options = array())


Paramtres
$number (float) La valeur convertir.
$precision (integer) Le nombre de dcimal afficher.
$options (array) Options, voir ci-dessous.
OpDescription
tion
multiBoolen pour indiquer si la valeur doit tre multiplie par 100. Utile pour les
ply
pourcentages avec dcimal.
Comme precision(), cette mthode formate un nombre selon la prcision fournie (o les nombres sont
arrondis pour parvenir ce degr de prcision). Cette mthode exprime aussi le nombre en tant que
pourcentage et prfixe la sortie avec un signe de pourcent.
// appel avec NumberHelper. Sortie: 45.69%
echo $this->Number->toPercentage(45.691873645);
// appel avec CakeNumber. Sortie: 45.69%
App::uses('CakeNumber', 'Utility');
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.
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

CakePHP Cookbook Documentation, Version 2.x

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

CakeNumber::format(mixed $number, mixed $options=false)


Cette mthode vous donne beaucoup plus de contrle sur le formatage des nombres pour lutilisation
dans vos vues (et est utilise en tant que mthode principale par la plupart des autres mthodes de
NumberHelper). Lutilisation de cette mthode pourrait ressembler cela :
// appel avec NumberHelper
$this->Number->format($number, $options);
// appel avec CakeNumber
CakeNumber::format($number, $options);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

));
// 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'

CakeNumber::formatDelta(mixed $number, mixed $options=array())


Cette mthode affiche les diffrences en valeur comme un nombre sign :
// appel avec NumberHelper
$this->Number->formatDelta($number, $options);
// appel avec CakeNumber
CakeNumber::formatDelta($number, $options);

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'

Introduit dans la version 2.3 : Cette mthode a t ajoute dans 2.3.

Utilitaires

747

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP gre lchappement de pour tous les paramtres de Model::find() et Model::save().


Dans le rare cas o vous avez besoin de construire le SQL la main, en utilisant lentre utilisateur, vous
devriez utiliser Requtes Prpares.
Security
class Security
La librairie security 40 gre les mesures basiques de scurit telles que les mthodes fournies pour le hashage
et les donnes chiffres.
39. http ://php.net/filter
40. http ://api.cakephp.org/2.4/class-Security.html

748

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

LAPI de Security

static Security::cipher($text, $key)


Type retourn string
Chiffre/Dchiffre un texte selon la cl donne :
// Chiffre votre mot de passe secret avec my_key
$secret = Security::cipher('hello world', 'my_key');
// Plus tard, dchiffrez votre mot de passe secret
$nosecret = Security::cipher($secret, 'my_key');

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 :

// Chiffre quelques donnes.


$encrypted = Security::rijndael('a secret', Configure::read('Security.key'), 'encrypt'

// Plus tard, le dchiffre.


$decrypted = Security::rijndael($encrypted, Configure::read('Security.key'), 'decrypt'

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

CakePHP Cookbook Documentation, Version 2.x

// En supposant que la cl est stocke quelque part, elle peut tre


// rutilise pour le dchiffrement plus tard.
$key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA';
$result = Security::encrypt($value, $key);

Les valeurs chiffrs peuvent tre dchiffres en utilisant Security::decrypt().


Introduit dans la version 2.5.
static Security::decrypt($cipher, $key, $hmacSalt = null)
Paramtres
$cipher (string) Le ciphertext dchiffrer.
$key (string) La cl 256 bit/32 byte utiliser pour une cl cipher.
$hmacSalt (string) Le sel utiliser pour un processus HMAC. Laissez null pour
utiliser Security.salt.
Dchiffre une valeur chiffre au pralable. Les paramtres $key et $hmacSalt doivent correspondre aux valeurs utilises pour chiffrer ou alors le dchiffrement sera un chec. Un exemple dutilisation
serait :
// En supposant que la cl est stocke quelque part, elle peut tre
// rutilise pour le dchiffrement plus tard.
$key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA';
$cipher = $user['User']['secrets'];
$result = Security::decrypt($cipher, $key);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

$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' =>
);
*/

'Jeff'), 'Friend' => array(array('name' => 'Nate


'Tracy'),'Friend' => array(array('name' => 'Lind
'Adam'),'Friend' => array(array('name' => 'Bob')
'asc');

'Adam'),'Friend' => array(array('name' => 'Bob')


'Jeff'), 'Friend' => array(array('name' => 'Nate
'Tracy'),'Friend' => array(array('name' => 'Lind

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.

static Set::apply($path, $array, $callback, $options = array())


Type retourn mixed
Appliquer un callback aux lments dun tableau extrait par un chemin Set : :extract compatible :
$data = array(
array('Movie' => array('id' => 1, 'title' => 'movie 3', 'rating' => 5)),
array('Movie' => array('id' => 1, 'title' => 'movie 1', 'rating' => 1)),
array('Movie' => array('id' => 1, 'title' => 'movie 2', 'rating' => 3)),
);
$result = Set::apply('/Movie/rating', $data, 'array_sum');
// rsultat gal 9

$result = Set::apply('/Movie/title', $data, 'strtoupper', array('type' => 'map'));


// rsultat gal array('MOVIE 3', 'MOVIE 1', 'MOVIE 2')
// $options sont: - type : peut tre 'pass' uses call_user_func_array(), 'map' uses ar

static Set::check($data, $path = null)


Type retourn boolean/array
Vrifie si un chemin particulier est dfini dans un tableau. Si $path est vide, $data va tre retourne
au lieu dune valeur bolenne :
$set = array(
'My Index 1' => array('First' => 'The first item')
);
$result = Set::check($set, 'My Index 1.First');

752

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// $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

static Set::classicExtract($data, $path = null)


Type retourn mixed
Rcupre une valeur dun tableau ou dun objet qui est contenu dans un chemin donn en utilisant un
tableau en une syntaxe de tableau, par ex :
{n}.Person.{[a-z]+} - {n} reprsente une cl numrique, Person reprsente une chane littrale.
{[a-z]+} (par ex : toute chane littrale ferme par des accolades en plus de {n} et {s}) est interpret
comme une expressoin rgulire.
Exemple 1
$a = array(
array('Article' => array('id' => 1, 'title' => 'Article 1')),
array('Article' => array('id' => 2, 'title' => 'Article 2')),
array('Article' => array('id' => 3, 'title' => 'Article 3'))
);
$result = Set::classicExtract($a, '{n}.Article.id');
/* $result ressemble maintenant :
Array
(
[0] => 1
[1] => 2
[2] => 3
)
*/
$result = Set::classicExtract($a, '{n}.Article.title');
/* $result ressemble maintenant :
Array
(
[0] => Article 1
[1] => Article 2
[2] => Article 3
)

Utilitaires

753

CakePHP Cookbook Documentation, Version 2.x

*/
$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[fruites] => fruit


)
[test] => Array
(
[0] => jippi
)
[dot.test] => Array
(
[0] => jippi
)
)
/
*
$result = Set::classicExtract($a,'{\d+}.{\w+}.name');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[pages] => page
)
[1] => Array
(
[fruites] => fruit
)
)
/
*
$result = Set::classicExtract($a,'{n}.{\w+}.name');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[pages] => page
)
[1] => Array
(
[fruites] => fruit
)
)
/
*
$result = Set::classicExtract($a,'{s}.{\d+}.name');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[0] => jippi
)
[1] => Array
(
[0] => jippi
)
)

Utilitaires

755

CakePHP Cookbook Documentation, Version 2.x

*/
$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

)
)
*/

static Set::combine($data, $path1 = null, $path2 = null, $groupPath = null)


Type retourn array
Cre un tableau associatif utilisant un $path1 comme chemin build en cl, et en option $path2 comme
chemin pour obtenir les valeurs. Si $path2 nest pas spcifi, toutes les valeurs seront initialises null
(utile pour Set : :merge). Vous pouvez en option grouper les valeurs par ce qui est obtenu quand on
suit le chemin spcifi dans $groupPath.
$result = Set::combine(array(), '{n}.User.id', '{n}.User.Data');
// $result == array();
$result = Set::combine('', '{n}.User.id', '{n}.User.Data');
// $result == array();
$a = array(
array(
'User' => array(
'id' => 2,
'group_id' => 1,
'Data' => array(
'user' => 'mariano.iglesias',
'name' => 'Mariano Iglesias'
)
)
),
array(
'User' => array(
'id' => 14,
'group_id' => 2,
'Data' => array(
'user' => 'phpnut',
'name' => 'Larry E. Masters'
)
)
),
array(
'User' => array(
'id' => 25,
'group_id' => 1,
'Data' => array(
'user' => 'gwoo',
'name' => 'The Gwoo'
)
)
)
);
$result = Set::combine($a, '{n}.User.id');
/* $result ressemble maintenant :
Array

Utilitaires

757

CakePHP Cookbook Documentation, Version 2.x

(
[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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[1] => Array


(
[2] => Array
(
[user]
[name]
)
[25] => Array
(
[user]
[name]
)
)
[2] => Array
(
[14] => Array
(
[user]
[name]
)
)

=> 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
)
)
/
*

$result = Set::combine($a, '{n}.User.id', array('{0}: {1}', '{n}.User.Data.user', '{n}


/* $result ressemble maintenant :
Array
(
[1] => Array
(
[2] => mariano.iglesias: Mariano Iglesias
[25] => gwoo: The Gwoo
)
[2] => Array
(
[14] => phpnut: Larry E. Masters
)

Utilitaires

759

CakePHP Cookbook Documentation, Version 2.x

)
*/

$result = Set::combine($a, array('{0}: {1}', '{n}.User.Data.user', '{n}.User.Data.name


/* $result ressemble maintenant :
Array
(
[mariano.iglesias: Mariano Iglesias] => 2
[phpnut: Larry E. Masters] => 14
[gwoo: The Gwoo] => 25
)
*/

$result = Set::combine($a, array('{1}: {0}', '{n}.User.Data.user', '{n}.User.Data.name


/* $result ressemble maintenant :
Array
(
[Mariano Iglesias: mariano.iglesias] => 2
[Larry E. Masters: phpnut] => 14
[The Gwoo: gwoo] => 25
)
*/

$result = Set::combine($a, array('%1$s: %2$d', '{n}.User.Data.user', '{n}.User.id'), '


/* $result ressemble maintenant :
Array
(
[mariano.iglesias: 2] => Mariano Iglesias
[phpnut: 14] => Larry E. Masters
[gwoo: 25] => The Gwoo
)
*/

$result = Set::combine($a, array('%2$d: %1$s', '{n}.User.Data.user', '{n}.User.id'), '


/* $result ressemble maintenant :
Array
(
[2: mariano.iglesias] => Mariano Iglesias
[14: phpnut] => Larry E. Masters
[25: gwoo] => The Gwoo
)
*/

static Set::contains($val1, $val2 = null)


Type retourn boolean
Detrmine si un Set ou un tableau contient les cls exactes et les valeurs dun autre :
$a = array(
0 => array('name' => 'main'),
1 => array('name' => 'about')
);
$b = array(

760

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

0 => array('name' => 'main'),


1 => array('name' => 'about'),
2 => array('name' => 'contact'),
'a' => 'b'
);
$result = Set::contains($a, $a);
// True
$result = Set::contains($a, $b);
// False
$result = Set::contains($b, $a);
// True

static Set::countDim($array = null, $all = false, $count = 0)


Type retourn integer
Compte les dimensions dun tableau. Si $all est dfini false (qui est la valeur par dfaut) il va
seulement considrer la dimension du premier lment dans le tableau :
$data = array('one', '2', 'three');
$result = Set::countDim($data);
// $result == 1
$data = array('1' => '1.1', '2', '3');
$result = Set::countDim($data);
// $result == 1
$data = array('1' => array('1.1' => '1.1.1'), '2', '3' => array('3.1' => '3.1.1'));
$result = Set::countDim($data);
// $result == 2
$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Set::countDim($data);
// $result == 1
$data = array('1' => '1.1', '2', '3' => array('3.1' => '3.1.1'));
$result = Set::countDim($data, true);
// $result == 2

$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

CakePHP Cookbook Documentation, Version 2.x

// $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

static Set::diff($val1, $val2 = null)


Type retourn array
Compute la diffrence entre un Set et un tableau, deux Sets, ou 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')

$result = Set::diff($a, $b);


/* $result ressemble maintenant :
Array
(
[2] => Array
(
[name] => contact
)
)
*/
$result = Set::diff($a, array());
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[name] => main
)
[1] => Array
(
[name] => about
)
)
*/
$result = Set::diff(array(), $b);
/* $result ressemble maintenant :

762

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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
)
)
*/

static Set::enum($select, $list=null)


Type retourn string
La mthode enum fonctionne bien quand on utilise les lments HTML select. Elle retourne une
valeur dun tableau list si la cl existe.
Si un $list spar par des virgules est pass dans les tableaux sont numriques avec la cl allant de 0
$list = no, yes traduirait $list = array(0 => no, 1 => yes) ;
Si un tableau est utilis, les cls peuvent tre des chanes exemple : array(no => 0,yes => 1) ;
$list par dfaut 0 = no 1 = yes si param nest pas pass :
$res = Set::enum(1, 'one, two');
// $res est 'two'
$res = Set::enum('no', array('no' => 0, 'yes' => 1));
// $res est 0
$res = Set::enum('first', array('first' => 'one', 'second' => 'two'));
// $res est 'one'

static Set::extract($path, $data=null, $options=array())


Utilitaires

763

CakePHP Cookbook Documentation, Version 2.x

Type retourn mixed


Set : :extract utilise la syntaxe basique XPath 2.0 pour retourner les sous-ensembles de vos donnes
partir dun fin ou dun find all. Cette fonction vous permet de rcuprer vos donnes rapidement sans
avoir boucler travers des tableaux multi-dimensionnels ou de traverser travers les structures en
arbre.
Note : Si $path ne contient pas un /, lappel sera dlgu Set::classicExtract()
// Utilisation habituelle:
$users = $this->User->find("all");
$results = Set::extract('/User/id', $users);
// results retourne:
// array(1,2,3,4,5,...);

Les slecteurs implments actuellement :


Selector
Note
/User/id
Similaire au {n}.User.id classique
/User[2]/name
Slectionne le nom du deuxime User
/User[id<2]
Slectionne tous les Users avec un id < 2
/User[id>2][<5]
Slectionne tous les Users avec un id > 2 mais 5
/Post/Comment[author_name=john]/../name
Slectionne le nom de tous les Posts qui ont au moins un Comment crit
par john
/Posts[title]
Slectionne tous les Posts qui ont une cl title
/Comment/.[1]
Slectionne les contenus du premier contenu
/Comment/.[ :last]
Slectionne le dernier comment
/Comment/.[ :first]
Slectionne le premier comment
/ComSlectionne tous les comments qui ont un texte correspondant au regex
ment[text=/cakephp/i] /cakephp/i
/Comment/@*
Slectionne les noms de cl de tous les comments. Actuellement seuls les
chemins absolus commanant par un unique / sont supports. Merci de
reporter tout bug si vous en trouvez. Les suggestions pour des
fonctionnalits supplmentaires sont bienvenues additional features are
welcome.
Pour en apprendre plus sur Set : :extract() rfrez vous la fonction testExtract() dans
/lib/Cake/Test/Case/Utility/SetTest.php.
static Set::filter($var)
Type retourn array
Filtre les lments vide dun tableau route, en excluant 0 :

$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[0] => one thing


[1] => I can tell you
[2] => is you got to be
)
)
*/

static Set::flatten($data, $separator=.)


Type retourn array
Transforme un tableau multi-dimensional en un tableau dimension unique :
$arr = array(
array(
'Post' => array('id' => '1', 'title' => 'First Post'),
'Author' => array('id' => '1', 'user' => 'Kyle'),
),
array(
'Post' => array('id' => '2', 'title' => 'Second Post'),
'Author' => array('id' => '3', 'user' => 'Crystal'),
),
);
$res = Set::flatten($arr);
/* $res ressemble maintenant :
Array (
[0.Post.id] => 1
[0.Post.title] => First Post
[0.Author.id] => 1
[0.Author.user] => Kyle
[1.Post.id] => 2
[1.Post.title] => Second Post
[1.Author.id] => 3
[1.Author.user] => Crystal
)
*/

static Set::format($data, $format, $keys)


Type retourn array
Retourne une srie de valeurs extraites dun tableau, format en un format de chane :

$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

$res = Set::format($data, '{1}, {0}', array('{n}.Person.first_name', '{n}.Person.last_


/*
Array
(
[0] => Abele, Nate
[1] => Masters, Larry
[2] => Woodworth, Garrett
)

Utilitaires

765

CakePHP Cookbook Documentation, Version 2.x

*/

$res = Set::format($data, '{0}, {1}', array('{n}.Person.city', '{n}.Person.state'));


/*
Array
(
[0] => Boston, MA
[1] => Boondock, TN
[2] => Venice Beach, CA
)
*/
$res = Set::format($data, '{{0}, {1}}', array('{n}.Person.city', '{n}.Person.state'));
/*
Array
(
[0] => {Boston, MA}
[1] => {Boondock, TN}
[2] => {Venice Beach, CA}
)
*/
$res = Set::format($data, '{%2$d, %1$s}', array('{n}.Person.something', '{n}.Person.so
/*
Array
(
[0] => {42, 42}
[1] => {0, {0}}
[2] => {0, {1}}
)
*/
$res = Set::format($data, '%2$d, %1$s', array('{n}.Person.first_name', '{n}.Person.som
/*
Array
(
[0] => 42, Nate
[1] => 0, Larry
[2] => 0, Garrett
)
*/
$res = Set::format($data, '%1$s, %2$d', array('{n}.Person.first_name', '{n}.Person.som
/*
Array
(
[0] => Nate, 42
[1] => Larry, 0
[2] => Garrett, 0
)
*/

static Set::insert($list, $path, $data = null)


Type retourn array
Insre $data dans un tableau comme dfini dans $path.

766

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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

CakePHP Cookbook Documentation, Version 2.x

[vars] => Array


(
[title] => page title
)
)
)
)
*/

static Set::map($class = stdClass, $tmp = stdClass)


Type retourn object
Cette mthode Mappe le contenu de lobjet Set en un objet hirarchis et maintient les cls numriques
en tableaux dobjets.
Basiquement, la fonction map transforme le tableau ditems en classe dobjets initialise. Par dfaut
il transforme un tableau en un Objet stdClass, cependant vous pouvez mapper les valeurs en un type
de classe. Exemple : Set : :map($array_of_values, nameOfYourClass) ; :
$data = array(
array(
"IndexedPage" => array(
"id" => 1,
"url" => 'http://blah.com/',
'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
'get_vars' => '',
'redirect' => '',
'created' => "1195055503",
'updated' => "1195055503",
)
),
array(
"IndexedPage" => array(
"id" => 2,
"url" => 'http://blah.com/',
'hash' => '68a9f053b19526d08e36c6a9ad150737933816a5',
'get_vars' => '',
'redirect' => '',
'created' => "1195055503",
'updated' => "1195055503",
),
)
);
$mapped = Set::map($data);
/* $mapped ressemble maintenant :
Array
(
[0] => stdClass Object
(
[_name_] => IndexedPage
[id] => 1
[url] => http://blah.com/

768

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

[hash] => 68a9f053b19526d08e36c6a9ad150737933816a5


[get_vars] =>
[redirect] =>
[created] => 1195055503
[updated] => 1195055503
)
[1] => stdClass Object
(
[_name_] => IndexedPage
[id] => 2
[url] => http://blah.com/
[hash] => 68a9f053b19526d08e36c6a9ad150737933816a5
[get_vars] =>
[redirect] =>
[created] => 1195055503
[updated] => 1195055503
)
)
*/

Utilisation de Set : :map() avec une classe personnalise en second paramtre :


class MyClass {
public function sayHi() {
echo 'Hi!';
}
}
$mapped = Set::map($data, 'MyClass');
//Maintenant vous pouvez accder toutes les proprits comme dans
//l'exemple ci-dessus, mais aussi vous pouvez appeler les mthodes
//MyClass
$mapped->[0]->sayHi();

static Set::matches($conditions, $data=array(), $i = null, $length=null)


Type retourn boolean
Set : :matches peut tre utilis pour voir si un item unique ou un xpath donn admet certaines conditions.
$a = array(
array('Article' => array('id' => 1, 'title' => 'Article 1')),
array('Article' => array('id' => 2, 'title' => 'Article 2')),
array('Article' => array('id' => 3, 'title' => 'Article 3')));
$res=Set::matches(array('id>2'), $a[1]['Article']);
// retourne false
$res=Set::matches(array('id>=2'), $a[1]['Article']);
// retourne true
$res=Set::matches(array('id>=3'), $a[1]['Article']);
// retourne false
$res=Set::matches(array('id<=2'), $a[1]['Article']);

Utilitaires

769

CakePHP Cookbook Documentation, Version 2.x

// 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

static Set::merge($arr1, $arr2=null)


Type retourn array
Cette fonction peut tre imagine comme un hybride entre array_merge et array_merge_recursive
de PHP. La diffrence entre les deux est que si une cl de tableau contient un autre tableau alors
la fonction se comporte de faon rcursive (pas comme array_merge) mais le ne fait pas pour les
cls contenant des chanes (pas comme array_merge_recursive). Regardez le test unitaire pour plus
dinformations.
Note : Cette fonction va fonctionner avec un montant illimit darguments et de paramtres nontableaux typecasts dans des tableaux.
$arry1 = 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".',
)
);
$arry2 = 4;
$arry3 = array(0 => "test array", "cats" => "dogs", "people" => 1267);
$arry4 = array("cats" => "felines", "dog" => "angry");
$res = Set::merge($arry1, $arry2, $arry3, $arry4);

770

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

/* $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] => Retire toutes les lignes qui disent "Unpaid".
)
[2] => 4
[3] => test array
[cats] => felines
[people] => 1267
[dog] => angry
)
*/

static Set::normalize($list, $assoc = true, $sep = , , $trim = true)


Type retourn array
Normalise une liste de chane ou de tableau.
$a = array('Tree', 'CounterCache',
'Upload' => array(
'folder' => 'products',
'fields' => array('image_1_id', 'image_2_id', 'image_3_id', 'image_4_id',
$b = array('Cacheable' => array('enabled' => false),
'Limit',
'Bindable',
'Validator',
'Transactional');
$result = Set::normalize($a);
/* $result ressemble maintenant :
Array
(
[Tree] =>
[CounterCache] =>
[Upload] => Array
(
[folder] => products
[fields] => Array
(
[0] => image_1_id
[1] => image_2_id
[2] => image_3_id

Utilitaires

771

CakePHP Cookbook Documentation, Version 2.x

[3] => image_4_id


[4] => image_5_id
)
)
)
*/
$result = Set::normalize($b);
/* $result ressemble maintenant :
Array
(
[Cacheable] => Array
(
[enabled] =>
)
[Limit] =>
[Bindable] =>
[Validator] =>
[Transactional] =>
)
/
*
$result = Set::merge($a, $b); // Fusionne maintenant les deux et normalize
/* $result ressemble maintenant :
Array
(
[0] => Tree
[1] => CounterCache
[Upload] => Array
(
[folder] => products
[fields] => Array
(
[0] => image_1_id
[1] => image_2_id
[2] => image_3_id
[3] => image_4_id
[4] => image_5_id
)
)
[Cacheable] => Array
(
[enabled] =>
)
[2] => Limit
[3] => Bindable
[4] => Validator
[5] => Transactional
)
*/
$result = Set::normalize(Set::merge($a, $b));
/* $result ressemble maintenant :
Array

772

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

(
[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

CakePHP Cookbook Documentation, Version 2.x

// $res est true


$data = array(0);
$res = Set::numeric($data);
// $res est true
$data = array('one', 'two', 'three', 'four', 'five');
$res = Set::numeric(array_keys($data));
// $res est true
$data = array(1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
$res = Set::numeric(array_keys($data));
// $res est true
$data = array('1' => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five');
$res = Set::numeric(array_keys($data));
// $res est true
$data = array('one', 2 => 'two', 3 => 'three', 4 => 'four', 'a' => 'five');
$res = Set::numeric(array_keys($data));
// $res est false

static Set::pushDiff($array1, $array2)


Type retourn array
Cette fonction fusionne deux tableaux et pousse les diffrences dans array2 la fin du tableau rsultant.
Exemple 1

$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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$array1 = array("a" => "b", 1 => 20938, "c" => "string");


$array2 = array("b" => "b", 3 => 238, "c" => "string", array("extra_field"));
$res = Set::pushDiff($array1, $array2);
/* $res ressemble maintenant :
Array
(
[a] => b
[1] => 20938
[c] => string
[b] => b
[3] => 238
[4] => Array
(
[0] => extra_field
)
)
*/

static Set::remove($list, $path = null)


Type retourn array
Retire un lment dun Set ou dun tableau selon ce qui est dfini par $path :
$a = array(
'pages'
'files'
);

=> array('name' => 'page'),


=> array('name' => 'files')

$result = Set::remove($a, 'files');


/* $result ressemble maintenant :
Array
(
[pages] => Array
(
[name] => page
)
)
*/

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

CakePHP Cookbook Documentation, Version 2.x

array('id' => 1, 'title' => 'Premier Comment'),


array('id' => 2, 'title' => 'Deuxime Comment')
),
'Tag' => array(
array('id' => 1, 'title' => 'Premier Tag'),
array('id' => 2, 'title' => 'Deuxime Tag')
),
);
$map = Set::map($a); // Change $a dans une classe object
/* $map ressemble maintenant :
stdClass Object
(
[_name_] => Post
[id] => 1
[title] => Premier Post
[Comment] => Array
(
[0] => stdClass Object
(
[id] => 1
[title] => Premier Comment
)
[1] => stdClass Object
(
[id] => 2
[title] => Deuxime Comment
)
)
[Tag] => Array
(
[0] => stdClass Object
(
[id] => 1
[title] => Premier Tag
)
[1] => stdClass Object
(
[id] => 2
[title] => Deuxime Tag
)
)
)
*/
$result = Set::reverse($map);
/* $result ressemble maintenant :
Array
(
[Post] => Array
(
[id] => 1
[title] => Premier Post
[Comment] => Array

776

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

(
[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
)
*/

static Set::sort($data, $path, $dir)


Type retourn array
Trie un tableau selon toute valeur, dtermin par un chemin Set-compatible :
$a = array(
0 => array('Person' => array('name' => 'Jeff')),
1 => array('Shirt' => array('color' => 'black'))
);
$result = Set::sort($a, '{n}.Person.name', 'asc');
/* $result ressemble maintenant :
Array
(
[0] => Array
(
[Shirt] => Array

Utilitaires

777

CakePHP Cookbook Documentation, Version 2.x

(
[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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

)
*/
$a = array(
array(7,6,4),
array(3,4,5),
array(3,2,1),
);

static Set::apply($path, $array, $callback, $options = array())


Type retourn mixed
Applique un callback aux lments dun tableau extait par un chemin compatible Set : :extract :
$data = array(
array('Movie' => array('id' => 1, 'title' => 'movie 3', 'rating' => 5)),
array('Movie' => array('id' => 1, 'title' => 'movie 1', 'rating' => 1)),
array('Movie' => array('id' => 1, 'title' => 'movie 2', 'rating' => 3)),
);
$result = Set::apply('/Movie/rating', $data, 'array_sum');
// rsultat gal 9

$result = Set::apply('/Movie/title', $data, 'strtoupper', array('type' => 'map'));


// rsultat gal array('MOVIE 3', 'MOVIE 1', 'MOVIE 2')
// $options sont: - type : peut tre 'pass' utilise call_user_func_array(), 'map' util

static Set::nest($data, $options = array())


Type retourn array
Prend un tableau plat et retourne un tableau imbriqu :
$data
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'
array('ModelName'

= array(
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'
=> array('id'

=>
=>
=>
=>
=>
=>
=>
=>
=>
=>

1, 'parent_id' => null)),


2, 'parent_id' => 1)),
3, 'parent_id' => 1)),
4, 'parent_id' => 1)),
5, 'parent_id' => 1)),
6, 'parent_id' => null)),
7, 'parent_id' => 6)),
8, 'parent_id' => 6)),
9, 'parent_id' => 6)),
10, 'parent_id' => 6))

);
$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

CakePHP Cookbook Documentation, Version 2.x

(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()
)

)
)
)
*/

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

static CakeText::tokenize($data, $separator = , , $leftBound = (, $rightBound = ))


Tokenizes une chane en utilisant $separator, en ignorant toute instance de $separator qui
apparait entre $leftBound et $rightBound.
Cette mthode peut tre utile quand on spare les donnes en formatage rgulier comme les listes de
tag :
$data = "cakephp 'great framework' php";
$result = CakeText::tokenize($data, ' ', "'", "'");
// le rsultat contient
array('cakephp', "'great framework'", 'php');

static CakeText::insert($string, $data, $options = array())


La mthode insre est utilise pour crer des chanes templates et pour permettre les remplacements
de cl/valeur :

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."

static CakeText::cleanInsert($string, $options = array())


Nettoie une chane formate CakeText::insert avec $options donne qui dpend de la cl
clean dans $options. La mthode par dfaut utilise est le texte mais html est aussi disponible.
Le but de cette fonction est de remplacer tous les espaces blancs et les balises non ncessaires autour
des placeholders qui ne sont pas remplacs par Set : :insert.
Vous pouvez utiliser les options suivantes dans le tableau options :
$options = array(
'clean' => array(
'method' => 'text', // ou html
),
'before' => '',
42. http ://tools.ietf.org/html/rfc4122.html

Utilitaires

781

CakePHP Cookbook Documentation, Version 2.x

'after' => ''


);

static CakeText::wrap($text, $options = array())


Entoure un block de texte pour un ensemble de largeur, et indente aussi les blocks. Peut entourer
intelligemment le texte ainsi les mots ne sont pas sliced across lines :
$text = 'Ceci est la chanson qui ne stoppe jamais.';
$result = CakeText::wrap($text, 22);
// retourne
Ceci est la chanson
qui ne stoppe jamais.

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Highlights $needle in $haystack <span class="highlight">using</span>


the $options['format'] string specified or a default string.

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

CakePHP Cookbook Documentation, Version 2.x

CakeText::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
)

Introduit dans la version 2.3.


Exemple :
$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

CakeText::excerpt(string $haystack, string $needle, integer $radius=100, string $ending=...)


Paramtres
$haystack (string) La chane chercher.
$needle (string) La chane to excerpt around.
784

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$radius (int) Le nombre de caractres de chaque ct de $needle que vous


souhaitez inclure.
$ending (string) Le Texte ajouter/prfixer au dbut ou la fin du rsultat.
Extrait un excerpt de $haystack surrounding the $needle avec un nombre de caractres de
chaque ct dtermin par $radius, et prefix/suffix with $ending. Cette mthode est spcialement pratique pour les rsultats recherchs. La chane requte ou les mots cls peuvent tre montrs
dans le document rsultant.
// appel avec TextHelper
echo $this->Text->excerpt($lastParagraph, 'method', 50, '...');
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::excerpt($lastParagraph, 'method', 50, '...');

Sortie :
... par $radius, et prefix/suffix avec $ending. Cette mthode est
spcialement pratique pour les rsultats de recherche. La requte...

CakeText::toList(array $list, $and=and)


Paramtres
$list (array) Tableau dlments combiner dans une list sentence.
$and (string) Le mot utilis pour le dernier join.
Cre une liste spare avec des virgules, o les deux derniers items sont joins avec and.
// appel avec TextHelper
echo $this->Text->toList($colors);
// appel avec CakeText
App::uses('CakeText', 'Utility');
echo CakeText::toList($colors);

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

CakePHP Cookbook Documentation, Version 2.x

$this->Session->setFlash(__('Happy birthday you...'));


}
}
}

Introduit dans la version 2.1 : CakeTime a t cr partir de TimeHelper.


Formatage

CakeTime::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'));

Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset


utilis dans 2.1 et suivants.
CakeTime::convertSpecifiers($format, $time = NULL)
Type retourn string
Convertit une chane de caractres reprsentant le format pour la fonction strftime et retourne un
format Windows safe et i18n aware.
CakeTime::dayAsSql($dateString, $field_name, $timezone = NULL)
Type retourn string
Cre une chane de caractres dans le mme format que dayAsSql mais ncessite seulement un unique
objet date :
// Appel avec TimeHelper
echo $this->Time->dayAsSql('Aug 22, 2011', 'modified');
// (modified >= '2011-08-22 00:00:00') AND
// (modified <= '2011-08-22 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::dayAsSql('Aug 22, 2011', 'modified');

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::daysAsSql($begin, $end, $fieldName, $userOffset = NULL)
786

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Type retourn string


Retourne une chane de caractres dans le format ($field_name >= 2008-01-21 00 :00 :00) AND
($field_name <= 2008-01-25 23 :59 :59). Cest pratique si vous avez besoin de chercher des enregistrements entre deux dates incluses :
// Appel avec TimeHelper
echo $this->Time->daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');
// (created >= '2011-08-22 00:00:00') AND
// (created <= '2011-08-25 23:59:59')
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::daysAsSql('Aug 22, 2011', 'Aug 25, 2011', 'created');

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

CakePHP Cookbook Documentation, Version 2.x

CakeTime::fromString($dateString, $timezone = NULL)


Type retourn string
Prend une chane et utilise strtotime 44 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');

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::gmt($dateString = NULL)
Type retourn integer
Va retourner la date en un nombre dfini sur Greenwich Mean Time (GMT).
// Appel avec TimeHelper
echo $this->Time->gmt('Aug 22, 2011');
// 1313971200
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::gmt('Aug 22, 2011');

CakeTime::i18nFormat($date, $format = NULL, $invalid = false, $timezone = NULL)


Type retourn string
Retourne une chane de date formate, tant donn soit un timestamp UNIX soit une chane de date
valide strtotime(). Il prend en compte le format de la date par dfaut pour le langage courant si un
fichier LC_TIME est utilis. Pour plus dinfos sur le fichier LC_TIME, allez voir ici
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
CakeTime::nice($dateString = NULL, $timezone = NULL, $format = null)
Type retourn string
Prend une chane de date et la sort au format Tue, Jan 1st 2008, 19 :25 ou avec le param optionnel
$format :
44. http ://us.php.net/manual/en/function.date.php

788

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

// Appel avec TimeHelper


echo $this->Time->nice('2011-08-22 11:53:00');
// Mon, Aug 22nd 2011, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::nice('2011-08-22 11:53:00');

CakeTime::niceShort($dateString = NULL, $timezone = NULL)


Type retourn string
Prend une chane de date et la sort au format Jan 1st 2008, 19 :25. Si lobjet date est today, le format
sera Today, 19 :25. Si lobjet date est yesterday, le format sera Yesterday, 19 :25 :
// Appel avec TimeHelper
echo $this->Time->niceShort('2011-08-22 11:53:00');
// Aug 22nd, 11:53
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
echo CakeTime::niceShort('2011-08-22 11:53:00');

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::serverOffset()
Type retourn integer
Retourne la valeur du serveur partir du GMT dans les secondes.
CakeTime::timeAgoInWords($dateString, $options = array())
Type retourn string
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')
);

Utilitaires

789

CakePHP Cookbook Documentation, Version 2.x

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'

Modifi dans la version 2.2 : Loption accuracy a t ajoute.


Introduit dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
CakeTime::toAtom($dateString, $timezone = NULL)
Type retourn string
Va retourner une chane de date au format Atom 2008-01-12T00 :00 :00Z
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::toQuarter($dateString, $range = false)
Type retourn mixed
Va retourner 1, 2, 3 ou 4 dpendant du quart de lanne sur lequel la date tombe. Si range est dfini
true, un tableau deux lments va tre retourn avec les dates de dbut et de fin au format 2008-0331 :
// Appel avec TimeHelper
echo $this->Time->toQuarter('Aug 22, 2011');
// Afficherait 3
$arr = $this->Time->toQuarter('Aug 22, 2011', true);
/*
Array

790

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

(
[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

CakePHP Cookbook Documentation, Version 2.x

Tester Time

CakeTime::isToday($dateString, $timezone = NULL)


CakeTime::isThisWeek($dateString, $timezone = NULL)
CakeTime::isThisMonth($dateString, $timezone = NULL)
CakeTime::isThisYear($dateString, $timezone = NULL)
CakeTime::wasYesterday($dateString, $timezone = NULL)
CakeTime::isTomorrow($dateString, $timezone = NULL)
CakeTime::isFuture($dateString, $timezone = NULL)
Introduit dans la version 2.4.
CakeTime::isPast($dateString, $timezone = NULL)
Introduit dans la version 2.4.
CakeTime::wasWithinLast($timeInterval, $dateString, $timezone = NULL)
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.
Toutes les fonctions ci-dessus retourneront true ou false quand une chane de date est pass.
wasWithinLast prend une option supplmentaire $time_interval :
// Appel avec TimeHelper
$this->Time->wasWithinLast($time_interval, $dateString);
// Appel avec CakeTime
App::uses('CakeTime', 'Utility');
CakeTime::wasWithinLast($time_interval, $dateString);

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Importer les donnes vers la classe Xml

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

// Nouvelle mthode en utilisant DOMDocument


$xml = Xml::build('http://bakery.cakephp.org/articles.rss', array('return' => 'domdocument'
// $xml est maintenant une instance de DOMDocument

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');

Vous pouvez aussi construire des objets Xml en utilisant un tableau :


$data = array(
'post' => array(
'id' => 1,
'title' => 'Best post',

Utilitaires

793

CakePHP Cookbook Documentation, Version 2.x

'body' => ' ... '


)
);
$xml = Xml::build($data);

Si votre entre est invalide, la classe Xml enverra une Exception :


$xmlString = 'What is XML?'
try {
$xmlObject = Xml::build($xmlString); // Ici enverra une Exception
} catch (XmlException $e) {
throw new InternalErrorException();
}

Note : DOMDocument 47 et SimpleXML 48 implement different APIs. Assurez vous dutiliser les bonnes
mthodes sur lobjet que vous requtez partir dun Xml.

Transformer une chane de caractres XML en tableau

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));

Si votre XML est invalide, cela enverra une Exception.


Transformer un tableau en une chane de caractres XML

// 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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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();

Le contenu de $xmlString sera :


<?xml version="1.0"?>
<project id="1">Valeur du projet<name>Nom du projet, en tag</name></project>

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

CakePHP Cookbook Documentation, Version 2.x

$newArray = array(
'projets' => array(
'projet' => array(
array(
'id' => 1,
'industry'
),
array(
'id' => 2,
'industry'
)
)
)
);

'title' => 'Projet 1',


=> array('id' => 1, 'name' => 'Industry 1')

'title' => 'Projet 2',


=> array('id' => 2, 'name' => 'Industry 2')

Les deux engendreront le XML ci-dessous :


<?xml version="1.0"?>
<projets>
<projet>
<id>1</id>
<title>Projet 1</title>
<industry>
<id>1</id>
<name>Industry 1</name>
</industry>
</projet>
<projet>
<id>2</id>
<title>Projet 2</title>
<industry>
<id>2</id>
<name>Industry 2</name>
</industry>
</projet>
</projets>

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

'tag' => array(


'xmlns:pref' => 'http://cakephp.org',
'pref:item' => array(
'item 1',
'item 2'
)
)
)
);
$xml2 = Xml::fromArray($xmlArray);

La valeur de $xml1 et $xml2 sera, respectivement :


<?xml version="1.0"?>
<root xmlns="http://cakephp.org"><child>value</child>

<?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

CakePHP Cookbook Documentation, Version 2.x

static Xml::build($input, $options = array())


Initialisez SimpleXMLElement ou DOMDocument partir dune chane de caractre XML donne,
dun chemin de fichier, dune URL ou dun tableau.
Construire du XML partir dune chane de caractres :
$xml = Xml::build('<example>text</example>');

Construire du XML partir dune chane de caractres (sortie DOMDocument) :


$xml = Xml::build('<example>text</example>', array('return' => 'domdocument'));

Construire du XML partir dun chemin de fichier :


$xml = Xml::build('/path/to/an/xml/file.xml');

Construire partir dune URL distante :


$xml = Xml::build('http://example.com/example.xml');

Construire partir dun tableau :


$value = array(
'tags' => array(
'tag' => array(
array(
'id' => '1',
'name' => 'defect'
),
array(
'id' => '2',
'name' => 'enhancement'
)
)
)
);
$xml = Xml::build($value);

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 7. Librairies du Coeur

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.

Comment Installer des Plugins


Il y a quatre moyens dinstaller un plugin CakePHP :
Par lintermdiaire de Composer
Manuellement
Par sous-module Git
Par clonage Git
Mais noubliez pas dActiver les Plugins aprs-ceci.

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

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Activer les Plugins


Les plugins ncessitent dtre chargs manuellement dans app/Config/bootstrap.php.
Vous pouvez au choix les charger un par un ou bien tous en une seule fois :
CakePlugin::loadAll(); // Charge tous les plugins d'un coup
CakePlugin::load('ContactManager'); // Charge un seul plugin

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.

Comment Utiliser des Plugins


Avant dutiliser un plugin, vous devez avant tout linstaller et lactiver. Voir Comment Installer des Plugins.

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.

Comment Utiliser des Plugins

801

CakePHP Cookbook Documentation, Version 2.x

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.

Aller plus loin avec le bootstrapping


Si vous souhaitez charger plus dun fichier bootstrap pour un plugin, vous pouvez spcifier un tableau de
fichiers avec la cl de configuration bootstrap :
CakePlugin::loadAll(array(
'Blog' => array(
'bootstrap' => array(
'config1',
'config2'
)
)
));

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

CakePHP Cookbook Documentation, Version 2.x

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);

Comment Crer des Plugins


En exemple de travail partir de la section Comment Utiliser des Plugins, commenons par crer le plugin
ContactManager rfrenc ci-dessus. Pour commencer, nous allons dfinir la structure basique du rpertoire.
Cela devrait ressembler ceci :
/app
/Plugin
/ContactManager
/Controller
/Component
/Model
/Behavior
/View
/Helper
/Layouts

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 {
}

Comment Crer des Plugins

803

CakePHP Cookbook Documentation, Version 2.x

// /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() {
//...
}
}

Note : Ce controller tend AppController du plugin (appel ContactManagerAppController) plutt que


lAppController de lapplication parente.
Notez aussi comment le nom du model est prfix avec le nom du plugin. Cest ncessaire pour faire la
diffrence entre les models dans les plugins et les models dans lapplication principale.
804

Chapitre 8. Plugins

CakePHP Cookbook Documentation, Version 2.x

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 :

Comment Crer des Plugins

805

CakePHP Cookbook Documentation, Version 2.x

// /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.

Redfinition des vues de plugin partir de lintrieur de votre application


Vous pouvez redfinir toutes les vues du plugin partir de lintrieur de votre app en utilisant des chemins
spciaux. Si vous avez un plugin appel ContactManager, vous pouvez redfinir les fichiers de vue du
plugin avec une logique de vue de lapplication plus spcifique, en crant des fichiers en utilisant le template
suivant app/View/Plugin/[Plugin]/[Controller]/[view].ctp. Pour le controller Contacts, vous pouvez faire
le fichier suivant :
/app/View/Plugin/ContactManager/Contacts/index.ctp

Crer ce fichier vous permettra de redfinir /app/Plugin/ContactManager/View/Contacts/index.ctp.

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

Lier aux plugins


Fates prcder simplement /nom_plugin/ pour le dbut dune requte pour un asset dans ce plugin, et cela
fonctionnera comme si lasset tait dans le webroot de votre application.
Par
exemple,
lier
le
/contact_manager/js/some_file.js
app/Plugin/ContactManager/webroot/js/some_file.js.

806

servira

lasset

Chapitre 8. Plugins

CakePHP Cookbook Documentation, Version 2.x

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"); ?>

Components, Helpers et Behaviors


Un plugin peut avoir des Components, Helpers et Behaviors tout comme une application CakePHP classique.
Vous pouvez soit crer des plugins qui sont composs seulement de Components, Helpers ou Behaviors
ce qui peut tre une bonne faon de construire des Components rutilisables qui peuvent tre facilement
dplacs dans tout projet.
Construire ces components est exactement la mme chose que de les construire lintrieur dune application habituelle, avec aucune convention spciale de nommage.
Faire rfrence avec votre component, depuis lintrieur ou lextrieur de votre plugin ncessite seulement
que vous prfixiez le nom du plugin avant le nom du component. Par exemple :
// Component dfini dans le plugin 'ContactManager'
class ExampleComponent extends Component {
}
// dans vos controllers:
public $components = array('ContactManager.Example');

La mme technique sapplique aux Helpers et aux Behaviors.


Note : la cration de Helpers, vous verrez que AppHelper nest pas automatiquement disponible. Vous
pouvez dclarer les ressources dont vous avez besoin avec les uses :
// Dclarez le use de AppHelper pour le Helper de votre Plugin
App::uses('AppHelper', 'View/Helper');

Etendez votre Plugin


Cet exemple est un bon dbut pour un plugin, mais il y a beaucoup plus faire. En rgle gnral, tout ce que
vous pouvez faire avec votre application, vous pouvez le faire lintrieur dun plugin la place.
Continuez, incluez certaines librairies tierces dans Vendor, ajoutez de nouveaux shells la console de cake,
et noubliez pas de crer des cas de test ainsi les utilisateurs de votre plugin peuvent automatiquement tester
les fonctionnalits de votre plugin !
Dans notre exemple ContactManager, nous pourrions crer des actions add/remove/edit/delete dans le ContactsController, intgrer la validation dans le model Contact, et intgrer la fonctionnalit laquelle on pourrait sattendre quand on gre ses contacts. A vous de dcider ce quil faut intgrer dans vos plugins. Noubliez juste pas de partager votre code avec la communaut afin que tout le monde puisse bnficier de votre
component gnial et rutilisable !
Comment Crer des Plugins

807

CakePHP Cookbook Documentation, Version 2.x

Astuces pour les Plugins


Une fois quun plugin a t install dans /app/Plugin/, vous pouvez y accder lURL
/nom_plugin/nom_controller/action. Dans notre exemple de plugin ContactManager, nous accdons notre
ContactsController ladresse /contact_manager/contacts.
Quelques astuces de fin lorsque vous travaillez avec les plugins dans vos applications CakePHP :
Si vous navez pas un [Plugin]AppController et [Plugin]AppModel, vous aurez des erreurs de type get
missing Controller lorsque vous essayez daccder un controller dun plugin.
Vous pouvez dfinir vos propres layouts pour les plugins, dans le dossier
app/Plugin/[Plugin]/View/Layouts. Sinon, les plugins utiliseront les layouts du dossier /app/View/Layouts
par dfaut.
Vous
pouvez
tablir
une
communication
inter-plugin
en
utilisant
$this->requestAction(/plugin_name/controller_name/action); dans vos
controllers.
Si vous utilisez requestAction, assurez-vous que les noms des controllers et des models sont aussi uniques
que possibles. Sinon, vous aurez des erreurs PHP de type redefined class ....
Quand vous ajoutez des routes avec des extensions votre plugin, assurez-vous dutilisez
Router::setExtensions() pour ne pas devoir surcharger le routing de lapplication.

Publiez votre Plugin


Vous pouvez ajouter votre plugin sur plugins.cakephp.org 3 ou le proposer la liste awesome-cakephp 4 .
Aussi, vous pouvez crer un fichier composer.json et publier votre plugin sur packagist.org 5 . De cette faon,
il peut tre facilement utilis avec Composer.
Choisissez un nom de package avec une smantique qui a du sens. Il devra idalement tre prfix avec la
dpendance, dans ce cas cakephp comme le framework. Le nom de vendor sera habituellement votre nom
dutilisateur sous GitHub. Nutilisez pas le namespace CakePHP (cakephp) puisquil est reserv aux plugins
appartenant CakePHP. La convention est dutiliser les lettres en minuscule et les tirets en sparateur.
Donc si vous crez un plugin Logging avec votre compte GitHub FooBar, un bon nom serait
foo-bar/cakephp-logging. Et le plugin Localized appartenant CakePHP peut tre trouv dans
cakephp/localized.

3. http ://plugins.cakephp.org
4. https ://github.com/FriendsOfCake/awesome-cakephp
5. https ://packagist.org/

808

Chapitre 8. Plugins

CHAPITRE 9

Shells, Tasks & Outils de Console

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

CakePHP Cookbook Documentation, Version 2.x

$ 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]

To run a command, type 'cake shell_name [args]'


To get help on a specific command, type 'cake shell_name help'

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

Ajouter cake votre systme path


Si vous tes sur un systme *nix (linux, MacOSX), les tapes suivantes vous permettront de rendre cake
executable dans votre systme path.
1. Localisez o se trouve votre installation de CakePHP et le cake excutable. Par exemple
/Users/mark/cakephp/lib/Cake/Console/cake
2. Modifiez votre fichier .bashrc ou .bash_profile dans votre rpertoire home, et ajoutez ce qui
suit :
export PATH="$PATH:/Users/mark/cakephp/lib/Cake/Console"

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;

6. Cliquez Ok et cake devrait fonctionner partout.

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

CakePHP Cookbook Documentation, Version 2.x

Console/cake hello

Vous devriez voir la sortie suivante :


Welcome to CakePHP v2.0.0 Console
--------------------------------------------------------------App : app
Path: /Users/markstory/Sites/cake_dev/app/
--------------------------------------------------------------Hello world.

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.

Utiliser les Models dans vos shells


Vous avez souvent besoin daccder la logique mtier de votre application dans les utilitaires de shell.
CakePHP rend cela super facile. En configurant une proprit $uses, vous pouvez dfinir un tableau de
models auxquels vous voulez accder dans votre shell. Les models dfinis sont chargs en proprits attaches votre shell, juste comme un controller obtient les models qui lui sont attachs :

812

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

class UserShell extends AppShell {


public $uses = array('User');
public function show() {
$user = $this->User->findByUsername($this->args[0]);
$this->out(print_r($user, true));
}
}

Le shell ci-dessus rcuprera un utilisateur par son username et affichera linformation stocke dans la base
de donnes.

Les tches Shell


Il y aura des fois o quand vous construirez des applications plus pousses via la console, vous voudrez
composer des fonctionnalits dans des classes rutilisables qui peuvent tre partages travers plusieurs
shells. Les tches vous permettent dextraire des commandes dans des classes. Par exemple, bake est fait
entirement de tches. Vous dfinissez les tches dun shell en utilisant la proprit $tasks :
class UserShell extends AppShell {
public $tasks = array('Template');
}

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 :

Les tches Shell

813

CakePHP Cookbook Documentation, Version 2.x

$ cake sea sound

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.

Chargement la vole des tches avec TaskCollection


Vous pouvez charger les tches la vole en utilisant lobjet Task Collection. Vous pouvez charger les tches
qui ne sont pas dclares dans $tasks de cette faon :
$Project = $this->Tasks->load('Project');

Chargera et retournera une instance ProjectTask. Vous pouvez charger les tches partir des plugins en
utilisant :
$ProgressBar = $this->Tasks->load('ProgressBar.ProgressBar');

Invoquer dautres shells partir de votre shell


Les Shells nont plus directement accs ShellDispatcher, travers $this->Dispatch. Il y a cependant beaucoup de cas o vous voulez invoquer un shell partir dun autre. Shell : :dispatchShell() vous donne la
possibilit dappeler dautres shells en fournissant le argv pour le shell sub. Vous pouvez fournir des arguments et des options soit en variables args ou en chanes de caractres :
// En chanes de caractre
$this->dispatchShell('schema create Blog --plugin Blog');
// En tableau
$this->dispatchShell('schema', 'create',

'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.

Niveaux de sortie de la Console


Les Shells ont souvent besoin de diffrents niveaux de verbosit. Quand vous lancez une tche cron, la
plupart des sorties ne sont pas ncessaires. Et il y a des fois o vous ntes pas interesss dans tout ce
quun shell a dire. Vous pouvez utiliser des niveaux de sortie pour signaler la sortie de faon approprie.
Lutilisateur du shell peut ensuite dcider pour quel niveau de dtail ils sont interesss en configurant le bon
flag quand on appelle le shell. Shell::out() supporte 3 types de sortie par dfaut.
QUIET - Seulement des informations importantes doivent tre marques pour une paisible.
NORMAL - Le niveau par dfaut, et un usage normal
814

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

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 :
*
*
*
*
*

``error`` Messages d'Erreur. Texte rouge soulign.


``warning`` Messages d'avertissement. Texte jaune.
``info`` Messages d'informations. Texte cyan.
``comment`` Texte supplmentaire. Texte bleu.
``question`` Texte qui est une question, ajout automatiquement par shell.

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

CakePHP Cookbook Documentation, Version 2.x

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.

Configurer les options et gnrer de laide


class ConsoleOptionParser
Le parsing doption de la Console dans CakePHP a toujours t un peu diffrent par rapport aux autres
consoles en ligne de commande. Dans 2.0, ConsoleOptionParser aide fournir un parser doption et
dargument plus familier en ligne de commande.
OptionParsers vous permet daccomplir deux buts en mme temps. Premirement, il vous permet de dfinir
les options et arguments, sparant la validation basique des entres et votre code. Deuximement, il vous
permet de fournir de la documentation, qui est utilise pour bien gnrer le fichier daide format.
La console du framework rcupre votre parser doption du shell en appelant
$this->getOptionParser(). Surcharger cette mthode vous permet de configurer lOptionParser pour faire correspondre les entres attendues de votre shell. Vous pouvez aussi configurer les
parsers doption des sous-commandes, ce qui vous permet davoir des parsers doption diffrents pour
les sous-commandes et les tches. ConsoleOptionParser implmente une interface courant et inclut les
mthodes pour configurer facilement les multiple options/arguments en une fois.
public function getOptionParser() {
$parser = parent::getOptionParser();
//configure parser

816

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

return $parser;
}

Configurer un option parser avec linterface courante


Toutes les mthodes utilises pour configurer le parser peuvent tre chaines, vous permettant de dfinir
lintgralit des options du parser en une unique srie dappel de mthodes :
public function getOptionParser() {
$parser = parent::getOptionParser();
$parser->addArgument('type', array(
'help' => 'Either a full path or type of class.'
))->addArgument('className', array(
'help' => 'A CakePHP core class name (e.g: Component, HtmlHelper).'
))->addOption('method', array(
'short' => 'm',
'help' => __('The specific method you want help on.')
))->description(__('Lookup doc block comments for classes in CakePHP.'));
return $parser;
}

Les mthodes autorisant le chainage sont :


description()
epilog()
command()
addArgument()
addArguments()
addOption()
addOptions()
addSubcommand()
addSubcommands()
ConsoleOptionParser::description($text = null)
Rcupre ou dfinit la description pour le parser doption. La description affiche en haut largument et
linformation doption. En passant soit un tableau, soit une chane, vous pouvez dfinir la valeur de la
description. Appeler sans arguments va retourner la valeur actuelle :
// Dfinit plusieurs lignes en une fois
$parser->description(array('line one', 'line two'));
// Lit la valeur actuelle
$parser->description()

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 :

Configurer les options et gnrer de laide

817

CakePHP Cookbook Documentation, Version 2.x

// Dfinit plusieurs lignes en une fois


$parser->epilog(array('line one', 'line two'));
// Lit la valeur actuelle
$parser->epilog()

Ajouter des arguments


ConsoleOptionParser::addArgument($name, $params = array())
Les arguments de position sont frquemment utiliss dans les outils en ligne de commande, et
ConsoleOptionParser vous permet de dfinir les arguments de position ainsi que de les rendre obligatoires. Vous pouvez ajouter des arguments un la fois avec $parser->addArgument(); ou plusieurs
la fois avec $parser->addArguments(); :
$parser->addArgument('model', array('help' => 'The model to bake'));

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.

Validation des arguments


Lors de la cration darguments de position, vous pouvez utiliser le flag required, pour indiquer quun
argument doit tre prsent quand un shell est appel. De plus, vous pouvez utiliser choices pour forcer un
argument pour quil soit une liste de choix valides :

818

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

$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.

Ajouter des Options


ConsoleOptionParser::addOption($name, $options = array())
Les options ou les flags sont aussi frquemment utiliss avec les outils de ligne de commande.
ConsoleOptionParser supporte la cration doptions avec les deux verbose et short aliases, fournissant les valeurs par dfaut et crant des switches en bolen. Les options sont cres avec soit
$parser->addOption(), soit $parser->addOptions().
$parser->addOption('connection', array(
'short' => 'c'
'help' => 'connection',
'default' => 'default'
));

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.

Configurer les options et gnrer de laide

819

CakePHP Cookbook Documentation, Version 2.x

$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.

Validation des options


Les options peuvent tre fournies avec un ensemble de choix un peu comme les arguments de position
peuvent ltre. Quand une option a dfini les choix, ceux-ci sont les seuls choix valides pour une option.
Toutes les autres valeurs vont lancer une InvalidArgumentException :
$parser->addOption('accept', array(
'help' => 'What version to accept.',
'choices' => array('working', 'theirs', 'mine')
));

Utiliser les options bolennes


Les options peuvent tre dfinies en options bolennes, qui sont utiles quand vous avez besoin de crer
des options de flag. Comme les options par dfaut, les options bolennes les incluent toujours dans les
paramtres parss. Quand les flags sont prsents, ils sont dfinis true, quand ils sont absents false :
$parser->addOption('verbose', array(
'help' => 'Enable verbose output.',
'boolean' => true
));

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.

Ajouter des sous-commandes


ConsoleOptionParser::addSubcommand($name, $options = array())

820

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

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.

Construire un ConsoleOptionParser partir dun tableau


ConsoleOptionParser::buildFromArray($spec)
Comme mentionn prcdemment, lors de la cration de parsers doption de la sous-commande, vous pouvez
dfinir le parser spec en tableau pour cette mthode. Ceci peut faciliter la construction de parsers de souscommande, puisque tout est un tableau :
$parser->addSubcommand('check', array(
'help' => __('Check the permissions between an ACO and ARO.'),
'parser' => 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'))
)
)
));

Configurer les options et gnrer de laide

821

CakePHP Cookbook Documentation, Version 2.x

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'))
)
));
}

Obtenir de laide dans les shells


Avec lajout de ConsoleOptionParser, rcuprer laide des shells est faite dune faon cohrente et uniforme.
En utilisant loption --help ou -h, vous pouvez voir laide pour tout shell du coeur, et tout shell qui
implmente un ConsoleOptionParser :
cake bake --help
cake bake -h

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

Cela vous ramnera laide spcifique pour la tche model de bake.

Obtenir de laide en XML


Lorsque vous ralisez des outils dautomatisation ou de dveloppement qui ont besoin dinteragir avec
les shells de CakePHP, il est apprciable dobtenir de laide dans un format parsable par une machine.
ConsoleOptionParser peut fournir de laide au format XML en dfinissant un argument supplmentaire :
cake bake --help xml
cake bake -h xml

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

<?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>

Routing dans shells / CLI


Dans linterface en ligne de commande (CLI), spcialement dans vos shells et tasks, env(HTTP_HOST)
et les autres variables denvironnement spcifique votre navigateur ne sont pas dfinis.
Si vous gnrez des rapports ou envoyez des emails qui utilisent Router::url(), ceux-ci vont conRouting dans shells / CLI

823

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

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');

La validation de la slection est sensible la casse.


Shell::initialize()
Initialize le constructeur du shell pour les sous-classes, permet la configuration de tches avant lexecution du shell.
Shell::loadTasks()
Charge les tches dfines dans public Shell::$tasks.
Shell::nl($multiplier = 1)
Paramtres
$multiplier (int) Nombre de fois que la squence de ligne doit tre rpte.
API de Shell

825

CakePHP Cookbook Documentation, Version 2.x

Sort un certain nombre de squences de nouvelles lignes.


Shell::out($message = null, $newlines = 1, $level = Shell : :NORMAL)
Paramtres
$message (string) Le message afficher.
$newlines (integer) Le nombre de nouvelles lignes qui suivent le message.
$level (integer) Le Niveaux de sortie de la Console le plus haut que ce message
doit afficher.
La mthode primaire pour la gnration de la sortie de lutilisateur. En utilisant les niveaux, vous pouvez utiliser la faon dont un shell est verbose. out() vous permet aussi dutiliser les tags de formatage
de couleur, ce qui permettra la sortie colore sur les systmes qui le supportent. Il y a plusieurs styles
intgres pour la coloration de texte, et vous pouvez dfinir les vtres.
error Messages dErreur.
warning Messages davertissement.
info Messages dinformation.
comment Texte supplmentaire.
question Texte Magenta utilis pour les prompts de lutilisateur.
En formattant les messages avec des balises de style, vous pouvez afficher une sortie stylise :
$this->out('<warning>This will remove data from the filesystems.</warning>');

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

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();

Crer des Helpers


Bien que CakePHP contienne quelques shell helpers, vous pouvez en crer plus dans votre application ou
vos plugins. Par exemple nous allons crer un helper simple pour gnrer des en-ttes sympas. Tout dabord
crez le fichier app/Console/Helper/HeadingHelper.php et mettez ce qui suit dedans :
<?php
App::uses("BaseShellHelper", "Console/Helper");
class HeadingHelper extends BaseShellHelper
{
public function output($args)
{
$args += array('', '#', 3);

Plus de sujets

827

CakePHP Cookbook Documentation, Version 2.x

$marker = str_repeat($args[1], $args[2]);


$this->_consoleOutput->out($marker . ' ' . $args[0] . ' ' . $marker);
}
}

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

$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();

xecuter des Shells en tche cron (cronjob)


Une chose habituelle faire avec un shell, cest de lexcuter par une tche cron pour nettoyer la base de
donnes une fois de temps en temps ou pour envoyer des newsletters :
#
#
#
#
#
#
#
#
#

*/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)

Vous pouvez avoir plus dinfos ici : http ://en.wikipedia.org/wiki/Cron

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

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

opts=$(${cake} Completion fuzzy "${COMP_WORDS[@]:1}")


COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
if [[ $COMPREPLY = "" ]] ; then
COMPREPLY=( $(compgen -df -- ${cur}) )
return 0
fi
return 0;
}

Plus de sujets

831

CakePHP Cookbook Documentation, Version 2.x

complete -F _cake cake Console/cake

Gnration de code avec Bake


La console Bake de CakePHP est un autre outil permettant de raliser son application rapidement. La console
Bake peut crer chacun des ingrdients basiques de CakePHP : models, vues et controllers. Et nous ne
parlons pas seulement des squelettes de classes : Bake peut crer une application fonctionnelle complte en
seulement quelques minutes. En ralit, Bake est une tape naturelle suivre une fois quune application a
t prototype.
Suivant la configuration de votre installation, vous devrez peut tre donner les droits dexcution au script
bash cake ou lappeler avec la commande ./cake bake. La console cake est excute en utilisant le CLI PHP
(Interface de Ligne de Commande). Si vous avez des problmes en excutant ce script, vrifiez que le CLI
PHP est install et quil a les modules adquats autoriss (ex : MySQL). Certains utilisateurs peuvent aussi
rencontrer des problmes si la base de donne host est localhost et devront essayer 127.0.0.1 la place.
Cela peut causer des soucis avec le CLI PHP.
En excutant Bake la premire fois, vous serez invit crer un fichier de configuration de la base de
donnes, si vous nen avez pas cr un auparavant.
Aprs que vous avez cr un fichier de configuration de la base de donnes, excuter Bake vous prsentera
les options suivantes
--------------------------------------------------------------App : app
Path: /path-to/project/app (Chemin: /chemin/vers/app/du/projet)
--------------------------------------------------------------Interactive Bake Shell
--------------------------------------------------------------[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[F]ixture
[T]est case
[Q]uit
What would you like to Bake? (D/M/V/C/P/F/T/Q)
>

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

$ cake bake plugin plugin_name


$ cake bake all

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

1. Aller dans le dossier : lib/Cake/Console/Templates/default/views.


2. Remarquez les 4 fichiers ici.
3. Copiez les dans le dossier : app/Console/Templates/[themename]/views.
4. Faire les changements pour la sortie HTML pour contrler la faon dont bake fabrique vos vues.
La partie du chemin [themename] est le nom du thme de bake que vous crez. Les noms des thmes de
Bake doivent tre uniques, donc nutilisez pas default.
Pour baker des projets personnaliss

1. Allez dans : lib/Cake/Console/Templates/skel


2. Trouvez-y la base des fichiers dapplication.
3. Copiez les dans votre : app/Console/Templates/skel
4. Fates des changements vers la sortie HTML pour contrler la faon dont bake va construire vos
vues.
5. Passez le paramtre de squelette du chemin la tche du projet.
cake bake project --skel Console/Templates/skel

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

CakePHP Cookbook Documentation, Version 2.x

Amlioration de Bake dans la version 1.3


Dans CakePHP 1.3, bake a connu une rvision importante, avec le rajout de fonctionnalits et amliorations.
Deux nouvelles tches (FixtureTask et TestTask) sont accessibles partir du menu principal de bake.
Une troisime tche (TemplateTask) a t rajoute pour lutilisation dans vos shells.
Toutes ces diffrentes tches de bake vous permettent maintenant dutiliser dautres connexions de bake
que le default. Utilisez le paramtre -connection.
Le support de Plugin a t fortement amlior. Vous pouvez maintenant utiliser --plugin
NomDuPlugin ou Plugin.class.
Les Questions ont t clarifies, et sont plus facilement comprhensibles.
Les validations multiples sur les models ont t ajoutes.
Les associations des models sur eux-mmes utilisant parent_id sont maintenant dtectes. Par exemple, si votre model est appel Thread, une association ParentThread et ChildThread sera cre.
Fixtures et Tests peuvent tre cuits sparment.
Les Tests Cuits incluent autant de fixtures connues, ainsi que la dtection des plugins (La dtection
plugin ne fonctionne pas avec PHP4).
Ainsi, avec cette liste de fonctionnalits, nous allons prendre le temps de regarder certaines nouvelles commandes, certains nouveaux paramtres et les fonctionnalits mises jour.
Nouveaux FixtureTask, TestTask et TemplateTask.
Fixture et le test baking taient un peu ardus dans le pass. Vous pouviez seulement gnrer des tests quand
vous bakiez des classes, et les fixtures pouvaient seulement tre gnres quand on bakait les models. Cela
faisait que lajout ultrieur de tests vos applications ou mme la rgnration de fixtures avec de nouveaux schmas taient difficiles. Dans 1.3, nous avons spar Fixture et la fabrication des Tests en tches
diffrentes. Cela vous permet de les relancer et de regnrer des tests et fixtures nimporte quel moment
dans votre processus de dveloppement.
En plus dtre reconstructibles nimporte quel moment, les tests cuits sont maintenant capable de trouver
autant de fixtures que possible. Dans le pass, tester impliquait souvent de se battre travers de nombreuses
erreurs Manque la table. Avec une dtection des fixtures plus pousse, nous esprons rendre le test plus
simple plus accessible.
Les cas de test gnrent aussi des mthodes squelettes de test pour chaque mthode publique non hrite
dans vos classes. Vous enlevant une tape supplmentaire.
TemplateTask est une tche en arrire plan, et elle gre la gnration des fichiers partir de templates.
Dans les versions prcdentes de CakePHP les vues cuites taient bases sur des templates, mais tout le reste
du code ne ltait pas. Avec 1.3, presque tout le contenu dans les fichiers gnrs par bake sont contrls par
les templates et la TemplateTask.
FixtureTask ne gnre plus seulement les fixtures avec les donnes factices mais en utilisant les options
interactives ou loption -records vous pouvez activer la gnration de fixture en utilisant les donnes live.
Nouvelle commande bake De nouvelles commandes ont t ajoutes pour rendre le baking plus facile et
plus rapide. Les bakings des controllers, Models et Vues ont tous la fonctionnalit de sous-commande all,
qui construit tout en une fois et reconstruit rapidement et facilement.
cake bake model all

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

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.

Gestion des Schmas et migrations


Le shell Schema permet de crer des objets, des dumps sql et de crer et restaurer des vues instantanes de
votre base de donnes.
Gnrer et utiliser les fichiers Schema
Un fichier de gnration de schma vous permet de facilement transporter un schma de base de donnes
agnostique. Vous pouvez gnrer un fichier de schma de votre base de donnes en utilisant :

Plus de sujets

835

CakePHP Cookbook Documentation, Version 2.x

$ Console/cake schema generate

Cela gnrera un fichier schema.php dans votre dossier app/Config/Schema.


Note : Le shell schema nutilise que les tables pour lesquelles des models sont dfinis. Pour forcer le shell
considrer toutes les tables, vous devez ajouter loption -f votre ligne de commande.
Pour reconstruire plus tard votre schma de base de donnes partir dun fichier schema.php prcdemment
ralis, lancez
$ Console/cake schema create

Cela va supprimer et crer les tables en se basant sur le contenu de schema.php.


Les fichiers de schma peuvent aussi tre utiliss pour gnrer des dumps sql. Pour gnrer un fichier sql
comprenant les dfinitions CREATE TABLE, lancez :
$ Console/cake schema dump --write filename.sql

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

}
}
}

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.
}

Ecrire un Schema CakePHP la main


La classe CakeSchema est la classe de base pour tous les schmas de base de donnes. Chaque classe schema
est capable de gnrer un ensemble de tables. La classe de console shell schema SchemaShell dans le
rpertoire lib/Cake/Console/Command interprte la ligne de commande, et la classe schema de base
peut lire la base de donnes, ou gnrer la table de la base de donnes.
CakeSchema peut maintenant localiser, lire et crire les fichiers schema pour les plugins. SchemaShell
permet aussi cette fonctionnalit.
CakeSchema supporte aussi tableParameters. Les paramtres de Table sont les informations non spcifiques aux colonnes de la table comme collation, charset, comments, et le type de moteur de la table.
Chaque Dbo implmente le tableParameters quils supportent.
Exemple

Voici un exemple complet partir de la classe acl

Plus de sujets

837

CakePHP Cookbook Documentation, Version 2.x

/**
* 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),

=> 'id', 'unique' => 1))

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

'key' => 'primary'


),

key La cl primary dfinit lindex de cl primaire.


null Est-ce que le champ peut tre null ?
default Quel est la valeur par dfaut du champ ?
limit La limit du type de champ.
length Quelle est la longueur du champ ?
type Un des types suivants
integer
date
time
datetime
timestamp
boolean
biginteger
float
string
text
binary
La cl de Table indexes
Le nom de cl indexes est mise dans le tableau de table plutt que dans celui dun nom de champ.
column Cest soit un nom de colonne unique, soit un tableau de colonnes.
par exemple Unique
'indexes' => array(
'PRIMARY' => array(
'column' => 'id',
'unique' => 1
)
)

par exemple Multiple


'indexes' => array(
'AB_KEY' => array(
'column' => array(
'a_id',
'b_id'),
'unique' => 1
)
)

unique Si lindex est unique, dfinissez ceci 1, sinon 0.

Plus de sujets

839

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

$ Console/cake schema generate

Vous aurez alors les choix suivants


Generating Schema... (Gnration du Schema)
Schema file exists. (Le fichier schema existe)
[O]verwrite (Ecraser)
[S]napshot (Vue instantane)
[Q]uit
(Quitter)
Would you like to do? (o/s/q) (Que voulez vous faire?)

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)

Rcuprer les derniers changements

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

CakePHP Cookbook Documentation, Version 2.x

$ git pull
$ Console/cake schema create
$ Console/cake schema update

Toutes ces oprations peuvent tre fates en mode sans criture.


Revenir en arrire

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

Ceci vous proposera les choix suivants :

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

./Console/cake i18n extract

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

Vous pouvez gnrer un fichier POT pour un plugin spcifique en faisant :


./Console/cake i18n extract --plugin <Plugin>

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

Exclure les fichiers

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

Eviter lcrasement des avertissements pour les fichiers POT existants

Introduit dans la version 2.2.


En ajoutant --overwrite, le script de shell ne va plus vous avertir si un fichier POT existe dj et va
craser par dfaut :
./Console/cake i18n extract --overwrite

Plus de sujets

843

CakePHP Cookbook Documentation, Version 2.x

Extraire les messages des librairies du coeur de CakePHP

Introduit dans la version 2.2.


Par dfaut, le script de shell dextraction va vous demander si vous souhaitez extraire les messages utiliss dans les librairies du coeur de CakePHP. Dfinissez --extract-core yes ou no pour dfinir le
comportement par dfaut.
./Console/cake i18n extract --extract-core yes
ou
./Console/cake i18n extract --extract-core no

Crer les tables utilises par TranslateBehavior


Le shell i18n peut aussi tre utilis pour initialiser les tables par dfaut utilises par
TranslateBehavior :
./Console/cake i18n initdb

Cela va crer la table i18n utilise par le behavior Translate.

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

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

Crer et supprimer les noeuds


You pouvez utiliser les sous-commandes de cration et de suppression pour crer et supprimer des noeuds :
./Console/cake acl create aco controllers Posts
./Console/cake acl create aco Posts index

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

Pour crer un noeud aro pour le Groupe dont lid est = 1.


Accorder et refuser laccs
Utilisez la commande daccs pour accorder les permssions ACL. Une fois excute, lARO spcifi (et ses
enfants, si il en a) aura un accs AUTORIS laction ACO spcifi (et les enfants de lACO, si il y en a) :
./Console/cake acl grant Group.1 controllers/Posts

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

La sortie sera soit success(succs), soit not allowed (non autoris).


Voir larbre de noeuds
La commande view permet de voir les arbres des ARO et des ACO. Le paramtre optionnel node permet
de retourner seulement une portion de larbre demand :
./Console/cake acl view

Plus de sujets

845

CakePHP Cookbook Documentation, Version 2.x

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.

Mise jour shell


La mise jour shell va faire quasiment tout le boulot pour mettre jour vos applications cakePHP de la
version 1.3 2.0.
Pour lancer la mise jour :
./Console/cake upgrade all

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

Pour mettre jour vos Plugins, lancer la commande :


./Console/cake upgrade all --plugin YourPluginName

Il est aussi possible de lancer chaque mise jour individuellement. Pour voir toutes les tapes possibles,
lancez la commande :
./Console/cake upgrade --help

Ou allez voir les docs de lAPI 4 pour plus dinformations :


Mise jour de votre App
Vous trouverez ici un guide pour vous aider mettre jour votre application CakePHP 1.3 vers cakePHP
2.x en utilisant le shell upgrade. La structure de dossiers de votre application 1.3 ressemble cela :
monsiteweb/
app/
cake/
plugins/
vendors/
.htaccess
index.php

<- Votre App


<- Version de CakePHP 1.3

4. http ://api.cakephp.org/2.4/class-UpgradeShell.html

846

Chapitre 9. Shells, Tasks & Outils de Console

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

848

Chapitre 9. Shells, Tasks & Outils de Console

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.

Configuration de la Base de Donnes


CakePHP sattend trouver les dtails de configuration de la base de donnes dans le fichier
app/Config/database.php. Un exemple de fichier de configuration de base de donnes peut tre
trouv dans app/Config/database.php.default. Une configuration basique complte devrait
ressembler quelque chose comme cela :
class DATABASE_CONFIG
public $default =
'datasource'
'persistent'
'host'
'login'
'password'
'database'
'prefix'
);
}

{
array(
=> 'Database/Mysql',
=> false,
=> 'localhost',
=> 'cakephpuser',
=> 'c4k3roxx!',
=> 'my_cakephp_project',
=> ''

849

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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.

Chemins de Classe Supplmentaires


Il est occasionnellement utile dtre capable de partager des classes MVC entre des applications sur le
mme systme. Si vous souhaitez le mme controller dans les deux applications, vous pouvez utiliser le
bootstrap.php de CakePHP pour amener ces classes supplmentaires dans la vue.
En utilisant App::build() dans bootstrap.php nous pouvons dfinir des chemins supplmentaires o
CakePHP va recherchez les classes :
App::build(array(
'Model' => array(
'/path/to/models',
'/next/path/to/models'
),
'Model/Behavior' => array(
'/path/to/behaviors',
'/next/path/to/behaviors'
),
'Model/Datasource' => array(
'/path/to/datasources',
'/next/path/to/datasources'
),
'Model/Datasource/Database' => array(
'/path/to/databases',
'/next/path/to/database'
),
'Model/Datasource/Session' => array(
'/path/to/sessions',
'/next/path/to/sessions'
),
'Controller' => array(
'/path/to/controllers',
'/next/path/to/controllers'
),
'Controller/Component' => array(
'/path/to/components',
'/next/path/to/components'
),
'Controller/Component/Auth' => array(
'/path/to/auths',
'/next/path/to/auths'
),
'Controller/Component/Acl' => array(
'/path/to/acls',
'/next/path/to/acls'

Configuration

851

CakePHP Cookbook Documentation, Version 2.x

),
'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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Configuration du Coeur de CakePHP


La classe Configure est utilise pour grer un ensemble de variables de configuration du coeur de CakePHP.
Ces variables peuvent tre trouves dans app/Config/core.php. Ci-dessous se trouve une description
de chaque variable et comment elle affecte votre application CakePHP.
debug Change la sortie de debug de CakePHP.
0 = mode Production. Pas de sortie.
1 = Montre les erreurs et les avertissements.
2 = Montre les erreurs, avertissements, et le SQL. [le log SQL est seulement montr quand vous
ajoutez $this->element(sql_dump) votre vue ou votre layout.]
Error Configure le gestionnaire dError handler utilis pour grer les erreurs pour votre application.
Par dfaut ErrorHandler::handleError() est utilis. Cela affichera les erreurs en utilisant
Debugger, quand debug > 0 et les logs derreurs avec CakeLog quand debug = 0.
Sous-cls :
handler - callback - Le callback pour grer les erreurs. Vous pouvez dfinir cela nimporte quel
callback, en incluant les fonctions anonymes.
level - int - Le niveau derreurs pour lequel vous souhaitez faire une capture.
trace - boolean - Inclut les traces de pile derreurs dans les fichiers log.
Exception Configure le gestionnaire Exception utilis pour les exceptions non attrapes. Par dfaut, ErrorHandler : :handleException() est utilise. Elle va afficher une page HTML pour lexception, et tant
que debug > 0, les erreurs du framework comme Missing Controller seront affiches. Quand debug =
0, les erreurs du framework seront forces en erreurs gnriques HTTP. Pour plus dinformations sur
la gestion de dException, regardez la section Exceptions.
App.baseUrl Si vous ne souhaitez pas ou ne pouvez pas avoir le mod_rewrite (ou un autre module compatible) et ne pouvez pas le lancer sur votre serveur, vous aurez besoin dutiliser le systme de belles URLs
construit dans CakePHP. Dans /app/Config/core.php, dcommentez la ligne qui ressemble
cela :
Configure::write('App.baseUrl', env('SCRIPT_NAME'));

Retirez aussi ces fichiers .htaccess :


/.htaccess
/app/.htaccess
/app/webroot/.htaccess

Cela fera apparaitre vos URLs de la faon suivante www.example.com/index.php/controllername/actionname/param


plutt que www.example.com/controllername/actionname/param.
Si vous installez CakePHP sur un serveur web autre que Apache, vous pouvez trouver des instructions
pour faire fonctionner lURL rewriting pour dautres serveurs dans la section URL Rewriting.
App.encoding Dfinit quel encodage votre application utilise. Cet encodage est utilis pour gnrer le
charset dans le layout, et les entits dencodage. Il doit correspondre aux valeurs encodes spcifies
pour votre base de donnes.
Routing.prefixes Dcommentez cette dfinition si vous souhaitez tirer profit des routes prfixes de
CakePHP comme admin. Dfinissez cette variable avec un tableau de noms prfixs de routes que
vous voulez utiliser. En savoir plus sur cela plus tard.

Configuration

853

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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');

static Configure::write($key, $value)


Paramtres
Configuration

855

CakePHP Cookbook Documentation, Version 2.x

$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');

//yields: 'Pizza, Inc.'


//yields: 'Pizza for your body and soul'

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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.

Lire et crire les fichiers de configuration


CakePHP est fourni avec deux fichiers readers de configuration intgrs. PhpReader est capable de lire les
fichiers de config de PHP, dans le mme format dans lequel Configure a lu historiquement. IniReader est
capable de lire les fichiers de config ini du coeur. Regardez la documentation PHP 1 pour plus dinformations
sur les fichiers ini spcifis. Pour utiliser un reader de config du coeur, vous aurez besoin de lattacher
Configure en utilisant Configure::config() :
App::uses('PhpReader', 'Configure');
// Lire les fichiers de config partir de app/Config
Configure::config('default', new PhpReader());
// Lire les fichiers de config partir du chemin
Configure::config('default', new PhpReader('/path/to/your/config/files/'));

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

CakePHP Cookbook Documentation, Version 2.x

// Rcupre le tableau d'alias pour les readers attachs.


Configure::configured()
// Vrifie si un reader spcifique est attach
Configure::configured('default');

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.

Chargement des fichiers de configuration


static Configure::load($key, $config = default, $merge = true)
Paramtres
$key (string) Lidentifieur du fichier de configuration charger.
$config (string) Lalias du reader configur.
$merge (boolean) Si oui ou non les contenus du fichier de lecture doivent tre
fusionns, ou craser les valeurs existantes.
Une fois que vous attachez un reader de config Configure, vous pouvez charger les fichiers de configuration :
// Charge my_file.php en utilisant l'objet reader 'default'.
Configure::load('my_file', 'default');

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Sauvegarder seulement les erreur grant la configuration :


Configure::dump('error.php', 'default', array('Error', 'Exception'));

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

CakePHP Cookbook Documentation, Version 2.x

Crer vos propres readers de Configuration


Depuis que les readers de configuration sont une partie extensible de CakePHP, vous pouvez crer des readers de configuration dans votre application et plugins. Les readers de configuration ont besoin dimplmenter
l ConfigReaderInterface. Cette interface dfinit une mthode de lecture, comme seule mthode requise. Si vous aimez vraiment les fichiers XML, vous pouvez crer un reader de config simple Xml pour votre
application :
// dans app/Lib/Configure/MyXmlReader.php
App::uses('Xml', 'Utility');
class MyXmlReader implements ConfigReaderInterface {
public function __construct($path = null) {
if (!$path) {
$path = APP . 'Config' . DS;
}
$this->_path = $path;
}
public function read($key) {
$xml = Xml::build($this->_path . $key . '.xml');
return Xml::toArray($xml);
}
// Depuis 2.3 une mthode dump() est ausi requise
public function dump($key, $data) {
// code pour supprimer les donnes d'un fichier
}
}

Dans votre app/Config/bootstrap.php, vous pouvez attacher ce reader et lutiliser :


App::uses('MyXmlReader', 'Configure');
Configure::config('xml', new MyXmlReader());
...
Configure::load('my_xml');

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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
)
);

Des fichiers sans $config entraneraient une ConfigureException.


Charger votre fichier de configuration personnalis en insrant
app/Config/bootstrap.php :

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Enregistrer les constantes globales.


Dfinir un model supplmentaire, une vue, et des chemins de controller.
Crer des configurations de cache.
Configurer les inflections.
Charger les fichiers de configuration.
Fates attention de maintenir le model MVC du logiciel quand vous ajoutez des choses au fichier de bootstrap : il pourrait tre tentant de placer des fonctions de formatage ici afin de les utiliser dans vos controllers.
Rsister la tentation. Vous serez content plus tard davoir suivi cette ligne de conduite.
Vous pouvez aussi envisager de placer des choses dans la classe AppController. Cette class est une
classe parente pour tous les controllers dans votre application. AppController est un endroit pratique
pour utiliser les callbacks de controller et dfinir des mthodes utiliser pour tous les controllers.

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.

Configuration des Routes


Les Routes dans une application sont configures dans app/Config/routes.php. Ce fichier est inclu
par le Dispatcher quand on gre les routes et vous permet de dfinir des routes spcifiques dapplication
que vous voulez utiliser. Les Routes dclares dans ce fichier sont traites de haut en bas quand les requtes entrantes correspondent. Cela signifie que lordre dans lequel vous placez les routes peuvent affecter
comment les routes sont parses. Cest gnralement une bonne ide de placer les routes visites le plus
frquemment en haut du fichier de routes si possible. Cela va permettre de ne pas avoir vrifier un certain
nombre de routes qui ne correspondront pas chaque requte.
Les Routes sont parses et matches dans lordre dans lequel elles sont connectes. Si vous dfinissez deux
routes similaires, la premire route dfinie va avoir une priorit plus haute sur celle dfinie plus tard. Aprs
avoir connect les routes, vous pouvez manipuler lordre des routes en utilisant Router::promote().
CakePHP vient aussi avec quelques routes par dfaut pour commencer. Celles-ci peuvent tre dsactives
plus tard une fois que vous tes sr que vous nen aurez pas besoin. Regardez Dsactiver les routes par
dfaut sur la faon de dsactiver le routing par dfaut.

Routing par Dfaut


Avant que vous appreniez configurer vos propres routes, vous devez savoir que CakePHP est configur
avec un ensemble de routes par dfaut. Le routing de CakePHP par dfaut va vous faire aller assez loin

Routing

863

CakePHP Cookbook Documentation, Version 2.x

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

LURL /posts/view mappe laction view() de PostsController, et /products/view_clearance mappe vers


laction view_clearance() de ProductsController. Si aucune action nest spcifie dans lURL, la mthode
index() est suppose.
La configuration du routing par dfaut vous permet aussi de passer les paramtres vos actions en utilisant
lURL. Une requte pour /posts/view/25 serait quivalente appeler view(25) dans le PostsController, par
exemple. Le routing par dfaut fournit aussi les routes pour les plugins, et les routes prfixes si vous
choisissez dutiliser ces fonctionnalits.
Les routes intgres sont dans Cake/Config/routes.php. Vous pouvez dsactiver le routing par dfaut en les retirant du fichier routes.php de votre application.

Connecter les Routes


Dfinir vos propres routes vous permet de dfinir la faon dont votre application va rpondre une URL
donne. Dfinir vos propres routes dans le fichier app/Config/routes.php en utilisant la mthode
Router::connect().
La mthode connect() prend trois paramtres : lURL que vous souhaitez faire correspondre, les valeurs
par dfaut pour les lments de votre route, et les rgles dexpression rgulire pour aider le routeur faire
correspondre les lments dans lURL.
Le format basique pour une dfinition de route est :
Router::connect(
'URL',
array('default' => 'defaultValue'),
array('option' => 'matchingRegex')
);

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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')
);

LURL entrante de /pages/the-example-/-and-proof rsulterait en un argument unique pass de


the-example-/-and-proof.
Introduit dans la version 2.1 : Ltoile double trailing a t ajoute dans 2.1.
Vous pouvez utiliser le deuxime paramtre de Router::connect() pour fournir tout paramtre de
routing qui est compos des valeurs par dfaut de la route :
Router::connect(
'/government',
array('controller' => 'products', 'action' => 'display', 5)
);

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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)')
);

Un exemple de plus, et vous serez un routing pro :


Router::connect(
'/:controller/:year/:month/:day',
array('action' => 'index'),
array(
'year' => '[12][0-9]{3}',
'month' => '0[1-9]|1[012]',
'day' => '0[1-9]|[12][0-9]|3[01]'
)
);

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

CakePHP Cookbook Documentation, Version 2.x

// 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'
));

Paramtres Nommes Per-route


Alors que vous pouvez contrler les paramtres nomms une grande chelle en utilisant
Router::connectNamed(), vous pouvez aussi contrler le comportement des paramtres nomms
au niveau de la route en utilisant le 3me argument de Router::connect() :
Router::connect(
'/:controller/:action/*',
array(),
array(
'named' => array(
'wibble',
'fish' => array('action' => 'index'),
'fizz' => array('controller' => array('comments', 'other')),
'buzz' => 'val-[\d]+'
)
)
);

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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 :

Router::connect('/admin', array('controller' => 'pages', 'action' => 'index', 'admin' => tr

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 :

Router::connect("/{$prefix}/:plugin/:controller", array('action' => 'index', 'prefix' => $p


Router::connect("/{$prefix}/:plugin/:controller/:action/*", array('prefix' => $prefix, $pre
Router::connect("/{$prefix}/:controller", array('action' => 'index', 'prefix' => $prefix, $
Router::connect("/{$prefix}/:controller/:action/*", array('prefix' => $prefix, $prefix => t

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

CakePHP Cookbook Documentation, Version 2.x

// Allez dans une route prfixe.


echo $this->Html->link('Manage posts', array('manager' => true, 'controller' => 'posts', 'a

// laissez un prfixe
echo $this->Html->link('View Post', array('manager' => false, 'controller' => 'posts', 'act

Routing des Plugins


Le routage des Plugins utilise la cl plugin. Vous pouvez crer des liens qui pointent vers un plugin, mais
en ajoutant la cl plugin votre tableau dURL :
echo $this->Html->link('New todo', array('plugin' => 'todo', 'controller' => 'todo_items',

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

}
}

Vous auriez la sortie suivante :


Array
(
[0] => recent
[1] => mark
)

La mme donne est aussi disponible dans $this->request->params[pass] et dans


$this->passedArgs dans vos controllers, vues, et helpers. Les valeurs dans le tableau pass sont indices numriquement bas sur lordre dans lequel elles apparaissent dans lURL appel :
debug($this->request->params['pass']);
debug($this->passedArgs);

Les deux du dessus sortiraient :


Array
(
[0] => recent
[1] => mark
)

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)

Comme 5 a une cl numrique, il est trait comme un argument pass.

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

$url = Router::url(array(
'controller' => 'posts',
'action' => 'index',
'filter' => array(
'published' => 1,
'frontpage' => 1
)
));

Ce qui est au-dessus gnrerait lURL /posts/index/filter[published]:1/filter[frontpage]:1.


Les paramtres sont ensuite parss et stocks dans la variable passedArgs de votre controller en tableau, de
la mme faon que vous les envoyez au Router::url :
$this->passedArgs['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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

'filter' => array(


'published' => 1
)
),
'comment' => array(
'order' => 'desc',
'filter' => array(
'spam' => 0
)
),
);

Contrler les Paramtres Nomms


Vous pouvez contrler la configuration du paramtre nomm au niveau-par-route ou les contrler globalement. Le contrle global est fait travers Router::connectNamed(). Ce qui suit donne quelques
exemples de la faon dont vous contrlez le parsing du paramtre nomm avec connectNamed().
Ne parsez aucun paramtre nomm :
Router::connectNamed(false);

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 sa valeur est un nombre :

Router::connectNamed(array('page' => '[\d]+'), array('default' => false, 'greedy' => false)

Parsez seulement le paramtre de la page dans tous les cas :


Router::connectNamed(array('page'), array('default' => false, 'greedy' => false));

Parsez seulement le paramtre de la page si laction courante est index :


Router::connectNamed(
array('page' => array('action' => 'index')),
array('default' => false, 'greedy' => false)
);

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)
);

connectNamed() supporte un certain nombre doptions :


greedy Configurer cela true fera que le Router va parser tous les paramtres nomms. Configurer cela
false va parser seulement les paramtres nomms.
default Dfinissez cela true pour fusionner dans lensemble par dfaut des paramtres nomms.
Routing

875

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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.

Dsactiver les routes par dfaut


Si vous avez compltement personnalis toutes les routes, et voulez viter toute pnalit de contenu dupliqu
possible des moteurs de recherche, vous pouvez retirer les routes par dfaut que CakePHP offre en les
supprimant de votre fichier dapplication routes.php.
Cela fera en sorte que CakePHP serve les erreurs, quand les utilisateurs essaient de visiter les URLs qui
seraient normalement fournies par CakePHP mais nont pas t connecte explicitement.

Classes de Route Personnalises


Les classes de route personnalises vous permettent dtendre et de modifier la faon dont certaines routes
parsent les demandes et de traiter le routing invers. Une classe personnalise de route devrait tre cre
dans app/Routing/Route et tendre CakeRoute et mettre en uvre un ou les deux match() et/ou
parse(). parse() est utilise pour analyser les demandes et correspondance et match() est utilise
pour traiter les routes inverses.
Vous pouvez utiliser une classe de route personnalise lors dun cration dune route laide des options de
la classe routeClass, et en chargeant le fichier contenant votre routes avant dessayer de lutiliser :
App::uses('SlugRoute', 'Routing/Route');
Router::connect(
'/:slug',
array('controller' => 'posts', 'action' => 'view'),
array('routeClass' => 'SlugRoute')
);

Cette route crerait une instance de SlugRoute et vous permet dimplmenter la gestion de paramtre
personnalise.

Routing

877

CakePHP Cookbook Documentation, Version 2.x

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 .

Router::connect('/home-page', array('controller' => 'pages', 'action' => 'display', 'h

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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
)
));

Gestionnaires de Session intgrs & configuration


CakePHP dispose de plusieurs configurations de session intgres. Vous pouvez soit utiliser celles-ci comme
base pour votre configuration de session, soit crer une solution compltement personnalise. Pour utiliser
les valeurs par dfaut, dfinissez simplement la cl defaults avec le nom par dfaut que vous voulez utiliser.
Vous pouvez ensuite surcharger toute sous-configuration en la dclarant dans votre config Session :
Configure::write('Session', array(
'defaults' => 'php'
));

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Les Sessions de Cache


La classe Cache peut aussi tre utilise pour stocker les sessions. Cela vous permet de stocker les sessions
dans un cache comme APC, memcache, ou Xcache. Il y a quelques prcautions prendre dans lutilisation
des sessions en cache, puisque si vous avez puis lespace de cache, les sessions vont commencer expirer
tandis que les enregistrements sont supprims.
884

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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.

Configurer les directives ini


Celui intgr par dfaut tente de fournir une base commune pour la configuration de session. Vous aurez aussi
besoin dajuster les flags ini spcifiques. CakePHP permet de personnaliser les configurations ini pour les
deux configurations par dfaut, ainsi que celles personnalises. La cl ini dans les configurations de session
vous permet de spcifier les valeurs de configuration individuelles. Par exemple vous pouvez lutiliser pour
contrler les configurations comme session.gc_divisor :
Configure::write('Session', array(
'defaults' => 'php',
'ini' => array(
'session.gc_divisor' => 1000,
'session.cookie_httponly' => true
)
));

Crer un gestionnaire de session personnalis


Crer un gestionnaire de session personnalis est simple dans CakePHP. Dans cet exemple, nous allons crer
un gestionnaire de session qui stocke les sessions la fois dans le Cache (apc) et la base de donnes. Cela
nous donne le meilleur du IO rapide de apc, sans avoir se soucier des sessions qui disparaissent quand le
cache se remplit.
Dabord, nous aurons besoin de crer notre classe personnalise et de la mettre dans
app/Model/Datasource/Session/ComboSession.php. La classe devrait ressembler :
App::uses('DatabaseSession', 'Model/Datasource/Session');
class ComboSession extends DatabaseSession implements CakeSessionHandlerInterface {
public $cacheKey;
public function __construct() {
$this->cacheKey = Configure::read('Session.handler.cache');
parent::__construct();
}
// Lit les donnes partir d'une session.

Sessions

885

CakePHP Cookbook Documentation, Version 2.x

public function read($id) {


$result = Cache::read($id, $this->cacheKey);
if ($result) {
return $result;
}
return parent::read($id);
}
// crit les donnes dans la session.
public function write($id, $data) {
Cache::write($id, $data, $this->cacheKey);
return parent::write($id, $data);
}
// dtruit une session.
public function destroy($id) {
Cache::delete($id, $this->cacheKey);
return parent::destroy($id);
}
// retire les sessions expires.
public function gc($expires = null) {
Cache::gc($this->cacheKey);
return parent::gc($expires);
}
}

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Lire & crire les donnes de session


Selon le contexte dans lequel vous tes dans votre application, vous avez diffrentes classes qui fournissent
un accs la session. Dans les controllers, vous pouvez utiliser SessionComponent. Dans la vue,
vous pouvez utiliser SessionHelper. Dans toute autre partie de votre application, vous pouvez utiliser
CakeSession pour accder aussi la session. Comme les autres interfaces de session, CakeSession
fournit une interface simple de CRUD.
static CakeSession::read($key)
Vous pouvez lire les valeurs de session en utilisant la syntaxe compatible Set::classicExtract() :
CakeSession::read('Config.language');

static CakeSession::write($key, $value)


$key devrait tre le chemin spar de point et $value sa valeur :
CakeSession::write('Config.language', 'eng');

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

CakePHP Cookbook Documentation, Version 2.x

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.

Exceptions intgres pour CakePHP


Il y a plusieurs exceptions intgres dans CakePHP, en-dehors des exceptions internes du framework, il y a
plusieurs exceptions pour les mthodes HTTP.
exception BadRequestException
Utilis pour faire une erreur 400 de Mauvaise Requte.
exception UnauthorizedException
Utilis pour faire une erreur 401 Non Autoris.
exception ForbiddenException
Utilis pour faire une erreur 403 Interdite.
exception NotFoundException
Utilis pour faire une erreur 404 Non Trouv.
exception MethodNotAllowedException
Utilis pour faire une erreur 405 pour les Mthodes Non Autorises.
exception InternalErrorException
Utilis pour faire une Erreur 500 du Serveur Interne.
exception NotImplementedException
Utilis pour faire une Erreur 501 Non Implmente.
Vous pouvez lancer ces exceptions partir de vos controllers pour indiquer les tats dchecs, ou les erreurs
HTTP. Un exemple dutilisation des exceptions HTTP pourrait tre le rendu de pages 404 pour les items qui
nont pas t trouvs :

888

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

public function view($id) {


$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException('Impossible de trouver ce poste');
}
$this->set('post', $post);
}

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

CakePHP Cookbook Documentation, Version 2.x

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.

Utiliser les exceptions HTTP dans vos controllers


Vous pouvez envoyer nimporte quelle exception HTTP lie partir des actions de votre controller pour
indiquer les tats dchec. Par exemple :
public function view($id) {
$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException();
}
$this->set(compact('post'));
}

Ce qui est au-dessus causerait lException.handler configure pour attraper et traiter


NotFoundException. Par dfaut, cela va crer une page derreur et enregistrer lexception.

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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.

Crer vos propres exceptions dans votre application


Vous pouvez crer vos propres exceptions dapplication en utilisant toute exception SPL 2 intgre,
Exception lui-mme, ou CakeException. Les exceptions dApplication qui tendent les Exceptions ou les exceptions SPL vont tre traites comme une erreur 500 dans le mode de production.
CakeException est spcial dans le fait que tous les objets CakeException sont contraints dtre
soit dans des erreurs 500 soit 404, selon le code quils utilisent. Quand vous tes en mode dveloppement,
les objets CakeException ont besoin simplement dun nouveau template qui matche le nom de classe
afin fournir des informations utiles. Si votre application contenait lexception suivante :
class MissingWidgetException extends CakeException {};

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

CakePHP Cookbook Documentation, Version 2.x

throw new MissingWidgetHelperException('Widget manquant', 501);

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.

Etendre et Implementer vos Propres Gestionnaires dException


Vous pouvez implmenter un gestionnaire dexception spcifique pour votre application de plusieurs faons.
Chaque approche vous donne diffrents montants de contrle sur le processus de gestion dexception.
Set Configure::write(Exception.handler, YourClass::yourMethod);
Create AppController::appError();
Set Configure::write(Exception.renderer, YourClass);
Dans les prochaines sections, nous allons dtailler les diffrentes approches et les bnfices de chacun.

Crer vos Propres Gestionnaires dException avec Exception.handler


Crer votre propre gestionnaire dexception vous donne plus de contrle sur le processus de gestion des exceptions. La classe que vous choisissez devra tre charge dans votre app/Config/bootstrap.php,
ainsi elle sera disponible pour grer toute exception. Vous pouvez dfinir le gestionnaire comme tout type
de callback. En configurant Exception.handler CakePHP va ignorer toutes les configurations dException. Une configuration de gestionnaire dexception personnalise pourrait par exemple ressembler
ceci :
// dans app/Config/core.php
Configure::write('Exception.handler', 'AppExceptionHandler::handle');
// dans app/Config/bootstrap.php
App::uses('AppExceptionHandler', 'Lib');
// dans app/Lib/AppExceptionHandler.php
class AppExceptionHandler {
public static function handle($error) {
echo 'Oh noes! ' . $error->getMessage();
// ...
}
// ...
}

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Configure::write('Exception.handler', function ($error) {


echo 'Ruh roh ' . $error->getMessage();
});

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.
}
}

Utiliser AppController : :appError()


Implmenter cette mthode est une alternative pour implmenter un gestionnaire dexception personnalis.
Il est fourni principalement pour une compatibilit backwards, et il nest pas recommand pour les nouvelles
applications. Cette mthode de controller est appele la place du rendu dexception par dfaut. Il reoit
lexception lance comme son seul argument. Vous devriez implmenter votre gestionnaire derreur dans
cette mthode :
class AppController extends Controller {
public function appError($error) {
// logique personnalise va ici.
}
}

Utiliser un rendu personnalis avec Exception.renderer pour grer les exceptions


dapplication
Si vous ne voulez pas prendre contrle du gestionnaire dexception, mais que vous
voulez changer la faon dont les exceptions sont rendues, vous pouvez utiliser
Configure::write(Exception.renderer,AppExceptionRenderer); pour choisir
une classe qui va rendre les pages dexception. Par dfaut :php :classExceptionRenderer est utilise.
Votre classe de rendu dexception personnalise doit tre place dans app/Lib/Error. Ou un rpertoire
Error dans tout chemin bootstrapped Lib. Dans une classe de rendu dexception, vous pouvez fournir une
gestion spcialise pour les erreurs spcifiques de lapplication :
// dans app/Lib/Error/AppExceptionRenderer.php
App::uses('ExceptionRenderer', 'Error');
class AppExceptionRenderer extends ExceptionRenderer {
public function missingWidget($error) {

Exceptions

893

CakePHP Cookbook Documentation, Version 2.x

echo 'Oops that widget is missing!';


}
}

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.

Crer un controller personnalis pour grer les exceptions


Dans votre sous-classe ExceptionRenderer, vous pouvez utiliser la mthode _getController pour vous
permettre de retourner un controller personnalis pour grer vos erreurs/ Par dfaut, CakePHP utilise
CakeErrorController qui enlve quelques callbacks habituels pour aider sassurer que les erreurs saffichent toujours. Cependant, vous aurez peut-tre besoin dun controller de gestionnaire derreur plus personnalis dans votre application. En implmentant _getController dans votre classe
AppExceptionRenderer, vous pouvez utiliser tout controller que vous souhaitez :
class AppExceptionRenderer extends ExceptionRenderer {
protected function _getController($exception) {
App::uses('SuperCustomError', 'Controller');
return new SuperCustomErrorController();
}
}

De faon alternative, vous pouvez simplement craser le CakeErrorController du coeur, en en incluant un


dans app/Controller. Si vous utilisez un controller personnalis pour la gestion des erreurs, assurezvous de faire toutes les configurations dont vous aurez besoin dans votre constructeur, ou dans la mthode de
rendu. Puisque celles-ci sont les seules mthodes que la classe ErrorHandler intgre appelle directement.
Logging Exceptions
Utiliser la gestion dexception intgre, vous pouvez lancer les exceptions qui sont gres avec ErrorHandler
en configurant Exception.log true dans votre core.php. Activer cela va lacer chaque exception vers
CakeLog et les loggers configurs.
Note : Si vous utilisez un Exception.handler personnalis, cette configuration naura aucun effet. A
moins que vous le rfrenciez lintrieur de votre implmentation.

894

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Gestion des Erreurs


Pour 2.0 Object::cakeError() a t retire. A la place, elle a t remplac par un certain nombre
dexceptions. Toutes les classes du coeur qui appelaient avant cakeError envoient maintenant des exceptions.
Cela vous laisse choisir soit la gestion des erreurs dans le code de votre application, soit laisser la gestion
intgre des exceptions le faire pour vous.
Il y a plus de contrle que jamais pour les erreurs et la gestion des exceptions dans CakePHP 2.0. Vous
pouvez configurer quelles mthodes vous voulez dfinir en tant que gestionnaire derreur, et en gestionnaire
dexception en utilisant configure.

Configuration des Erreurs


La configuration des Erreurs est faite lintrieur du fichier app/Config/core.php de votre application. Vous pouvez dfinir un callback pour quil soit effectu chaque fois que votre application attrape une
erreur PHP - les exceptions sont gres sparment Exceptions. Le callback peut tre nimporte quel PHP
appelable, avec la possibilit dappeler une fonction anonyme. Lerreur par dfaut de la configuration de
gestion ressemble ceci :
Configure::write('Error', array(
'handler' => 'ErrorHandler::handleError',
'level' => E_ALL & ~E_DEPRECATED,
'trace' => true
));

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).

Gestion des Erreurs

895

CakePHP Cookbook Documentation, Version 2.x

Crer vos propres gestionnaires derreurs


Vous pouvez crer un gestionnaire derreur partir de nimporte quel type de callback. Par exemple, vous
pouvez utiliser une classe appele AppError pour grer vos erreurs. Ce qui suit serait faire :
//dans app/Config/core.php
Configure::write('Error.handler', 'AppError::handleError');
//dans app/Config/bootstrap.php
App::uses('AppError', 'Lib');

//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.

Configure::write('Error.handler', function($code, $description, $file = null, $line = null,


echo 'Oh non quelque chose est apparu';
});

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.

Changer le comportement des erreurs fatales


Depuis CakePHP 2.2, Error.handler va aussi recevoir les codes derreur fatal. Si vous ne voulez pas
montrer la page derreur de cake, vous pouvez la remplacer comme cela :
//dans app/Config/core.php
Configure::write('Error.handler', 'AppError::handleError');
//dans app/Config/bootstrap.php
App::uses('AppError', 'Lib');

//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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Utiliser la Classe Debugger


class Debugger
Pour utiliser le debugger, assurez-vous dabord que Configure : :read(debug) est dfini une valeur
suprieure 0.
static Debugger::dump($var, $depth = 3)
Dump prints out the contents of a variable. Elle affiche toutes les proprits et mthodes (si il y en a)
de la variable fournie :
$foo = array(1,2,3);
Debugger::dump($foo);
// sortie
array(
1,
2,
3
)
// objet simple
$car = new Car();
Debugger::dump($car);
// sortie
Car
Car::colour = 'red'
Car::make = 'Toyota'
Car::model = 'Camry'
Car::mileage = '15000'
Car::acclerate()
Car::decelerate()
Car::stop()

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

//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) );

//sortira ce qui suit.


Array
(
[0] => <code><span style="color: #000000"> * @access public</span></code>
[1] => <code><span style="color: #000000"> */</span></code>
[2] => <code><span style="color: #000000">
function excerpt($file, $line, $cont

[3] => <span class="code-highlight"><code><span style="color: #000000">


$da
[4] => <code><span style="color: #000000">
$data = @explode("\n", file_get_
)

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

CakePHP Cookbook Documentation, Version 2.x

Utiliser Logging pour debug


Logger des messages est une autre bonne faon de debugger les applications, et vous pouvez utiliser
CakeLog pour faire le logging dans votre application. Tous les objets qui tendent Object ont une mthode dinstanciation log() qui peut treui peut tre utilise pour logger les messages :
$this->log('Got here', 'debug');

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Installation via Composer


Les dernires versions de PHPUnit ne fonctionnent pas avec cake :
"phpunit/phpunit": "3.7.38"

Installation via Package .phar


Vous pouvez galement tlcharger le fichier directement. Assurez-vous de rcuprer la bonne version
depuis https ://phar.phpunit.de/. Assurez-vous galement que /usr/local/bin est dans le include_path de votre
fichier php.ini
wget https://phar.phpunit.de/phpunit-3.7.38.phar -O phpunit.phar
chmod +x phpunit.phar
mv phpunit.phar /usr/local/bin/phpunit

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.

Tester la Configuration de la Base de Donnes


Souvenez-vous quil faut avoir un niveau de debug dau moins 1 dans votre fichier
app/Config/core.php avant de lancer des tests. Les tests ne sont pas accessibles via le navigateur quand le debug est gal 0. Avant de lancer des tests, vous devrez vous assurer dajouter une
configuration de base de donnes $test. Cette configuration est utilise par CakePHP pour les tables
fixture et les donnes :
public $test = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host'
=> 'dbhost',
'login'
=> 'dblogin',
'password'
=> 'dbpassword',
'database'
=> 'test_database'
);

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

CakePHP Cookbook Documentation, Version 2.x

Vrifier la Configuration Test


Aprs avoir install PHPUnit et configur le $test de la configuration de la base de donnes, vous pouvez
vous assurer que vous tes prt crire et lancer vos propres tests en lanant un de ceux prsents dans
le coeur. Il y a deux excuteurs intgrs pour le test, nous commencerons en utilisant lexcution par le
navigateur. Les tests peuvent tre accessibles par le navigateur http ://localhost/votre_app/test.php. Vous
devriez voir une liste des cas de test du coeur. Cliquez sur le test AllConfigure. Vous devriez voir une barre
verte avec quelques informations supplmentaires sur les tests lancs, et les nombres passs.
Flicitations, vous tes maintenant prt commencer crire des tests !

Conventions des cas de Test


Comme beaucoup de choses dans CakePHP, les cas de test ont quelques conventions. En ce qui concerne les
tests :
1. Les fichiers PHP contenant les tests devraient tre dans votre rpertoire app/Test/Case/[Type].
2. Les noms de fichier de ces fichiers devraient finir avec Test.php la place de .php.
3. Les classes contenant les tests devraient tendre CakeTestCase, ControllerTestCase ou
PHPUnit_Framework_TestCase.
4. Comme les autres noms de classe, les noms de classe des cas de test doivent correspondre au nom de
fichier. RouterTest.php doit contenir class RouterTest extends CakeTestCase.
5. Le nom de toute mthode contenant un test (par ex : contenant une assertion) devrait commencer
par test, comme dans testPublished(). Vous pouvez aussi utiliser lannotation @test pour
marquer les mthodes en mthodes de test.
Quand vous avez cr un cas de test, vous pouvez lexcuter en naviguant sur
http://localhost/votre_app/test.php (selon votre configuration spcifique) Cliquez
sur les cas de test de App, et cliquez ensuite sur le lien de votre fichier spcifique. Vous pouvez lancer les
tests partir des lignes de commande en utilisant le shell de test :
./Console/cake test app Model/Post

Par exemple, lancerait les tests pour votre model Post.

Crer Votre Premier Cas de Test


Dans lexemple suivant, nous allons crer un cas de test pour une mthode de helper trs simple. Le helper
que nous allons tester sera format en progress bar HTML. Notre helper ressemblerait cela :
class ProgressHelper extends AppHelper {
public function bar($value) {
$width = round($value / 100, 2) * 100;
return sprintf(
'<div class="progress-container">
<div class="progress-bar" style="width: %s%%"></div>
</div>', $width);
}
}

902

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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.

Lancer les Tests


Une fois que vous avez install PHPUnit et que quelques cas de tests sont crits, vous voudrez lancer les cas
de test trs frquemment. Cest une bonne ide de lancer les tests avant de committer tout changement pour
aider sassurer que vous navez rien cass.
Lancer les tests partir dun navigateur
CakePHP fournit une interface web pour lancer les tests, donc vous pouvez excuter vos tests par le navigateur si vous tes plus habitu cet environnement. Vous pouvez accder au web runner en allant sur
http://localhost/votre_app/test.php. La localisation exacte du test.php va changer en fonction de votre configuration. Mais le fichier est au mme niveau que index.php.
Une fois que vous charg les tests runners, vous pouvez naviguer dans les suites test de App, Core et Plugin.
Cliquer sur un cas de test individuel va lancer ce test et afficher les rsultats.
Voir la couverture du code

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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

Filtrer les cas de test

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Les Callbacks du Cycle de vie des cas de Test


Les cas de Test ont un certain nombre de callbacks de cycle de vue que vous pouvez utiliser quand vous
fates les tests :
setUp est appel avant chaque mthode de test. Doit tre utilis pour crer les objets qui vont tre tests,
et initialiser toute donne pour le test. Toujours se rappeler dappeler parent::setUp().
tearDown est appel aprs chaque mthode de test. Devrait tre utilis pour nettoyer une fois que le test
est termin. Toujours se rappeler dappeler parent::tearDown().
setupBeforeClass est appel une fois avant que les mthodes de test aient commences dans un cas.
Cette mthode doit tre statique.
tearDownAfterClass est appel une fois aprs que les mthodes de test ont commenc dans un cas.
Cette mthode doit tre statique.

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

CakePHP Cookbook Documentation, Version 2.x

'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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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();
}
}

Quand vous surchargez init(), rappelez-vous juste de toujours appeler parent::init().


Importer les informations de table et les enregistrements
Votre application peut avoir dj des models travaillant avec des donnes relles associes eux, et vous
pouvez dcider de tester votre application avec ces donnes. Ce serait alors un effort dupliqu pour avoir
dfinir une dfinition de table et/ou des enregistrements sur vos fixtures. Heureusement, il y a une faon
pour vous de dfinir cette dfinition de table et/ou denregistrements pour une fixture particulire venant
dun model existant ou dune table existante.
Commenons par un exemple. Imaginons que vous ayez un model nomm Article disponible dans votre
application (qui est li avec une table nomme articles), on changerait le fixture donn dans la section
prcdente (app/Test/Fixture/ArticleFixture.php) en ce qui suit :
Testing

909

CakePHP Cookbook Documentation, Version 2.x

class ArticleFixture extends CakeTestFixture {


public $import = 'Article';
}

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 :

class ArticleFixture extends CakeTestFixture {


public $import = 'Article';
public $records = array(
array('id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'publi
array('id' => 2, 'title' => 'Second Article', 'body' => 'Second Article Body', 'pub
array('id' => 3, 'title' => 'Third Article', 'body' => 'Third Article Body', 'publi
);
}

910

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Charger les fixtures dans vos cas de test


Aprs avoir cr vos fixtures, vous voudrez les utiliser dans vos cas de test. Dans chaque cas de test vous
devriez charger les fixtures dont vous aurez besoin. Vous devriez charger une fixture pour chaque model qui
aura une requte lance contre elle. Pour charger les fixtures, vous dfinissez la proprit $fixtures dans
votre model :
class ArticleTest extends CakeTestCase {
public $fixtures = array('app.article', 'app.comment');
}

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

class ArticleTest extends CakeTestCase {


public $fixtures = array('app.article', 'app.comment');
public $autoFixtures = false;
public function testMyFunction() {
$this->loadFixtures('Article', 'Comment');
}
}

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.

Tester les Models


Disons que nous avons dj notre model Article dfini dans app/Model/Article.php, qui ressemble
ceci :

Testing

911

CakePHP Cookbook Documentation, Version 2.x

class Article extends AppModel {


public function published($fields = null) {
$params = array(
'conditions' => array(
$this->name . '.published' => 1
),
'fields' => $fields
);
return $this->find('all', $params);
}
}

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.

Crer une mthode de test


Ajoutons maintenant une mthode pour tester la fonction published() dans le model Article. Modifier le
fichier app/Test/Case/Model/ArticleTest.php afin quil ressemble maintenant ceci :
App::uses('Article', 'Model');
class ArticleTest extends CakeTestCase {
public $fixtures = array('app.article');
public function setUp() {
parent::setUp();
$this->Article = ClassRegistry::init('Article');
}
public function testPublished() {
$result = $this->Article->published(array('id', 'title'));

912

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

$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.

Mthodes de Mocking des models


Il y aura des fois o vous voudrez mock les mhodes sur les models quand vous les testez. Vous devrez
utiliser getMockForModel pour crer les mocks de test des models. Cela vite des problmes avec les
reflected properties that normal mocks have :
public function testSendingEmails() {
$model = $this->getMockForModel('EmailVerification', array('send'));
$model->expects($this->once())
->method('send')
->will($this->returnValue(true));
$model->verifyEmail('test@example.com');
}

Introduit dans la version 2.3 : CakeTestCase : :getMockForModel() a t ajoute dans 2.3.

Tester les Controllers


Alors que vous pouvez tester les classes de controller de la mme manire que les Helpers, Models et Components, CakePHP offre une classe spcialise ControllerTestCase. Lutilisation de cette classe en
tant que classe de base pour les cas de test de votre controller vous permet dutiliser testAction() pour
des cas test plus simples. ControllerTestCase vous permet de facilement mock out les components
et les models, ainsi que la difficult potentielle pour tester les mthodes comme redirect().
Disons que vous avez un controller typique Articles, et son model correspondant. Le code du controller
ressemble ceci :

Testing

913

CakePHP Cookbook Documentation, Version 2.x

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

class ArticlesControllerTest extends ControllerTestCase {


public $fixtures = array('app.article');
public function testIndex() {
$result = $this->testAction('/articles/index');
debug($result);
}
public function testIndexShort() {
$result = $this->testAction('/articles/index/short');
debug($result);
}
public function testIndexShortGetRenderedHtml() {
$result = $this->testAction(
'/articles/index/short',
array('return' => 'contents')
);
debug($result);
}
public function testIndexShortGetViewVars() {
$result = $this->testAction(
'/articles/index/short',
array('return' => 'vars')
);

914

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

}
}
// 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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Utiliser mocks avec testAction


Il y aura des fois o vous voudrez remplacer les components ou les models avec soit des objets partiellement mock, soit des objets compltement mocks. Vous pouvez faire ceci en utilisant
ControllerTestCase::generate(). generate() fait le sale boulot afin de gnrer les mocks
sur votre controller. Si vous dcidez de gnrer un controller utiliser dans les tests, vous pouvez gnrer
les versions mocks de ses models et components avec ceci :
$Posts = $this->generate('Posts', array(
'methods' => array(
'isAuthorized'
),
'models' => array(
'Post' => array('save')
),
'components' => array(
'RequestHandler' => array('isPut'),
'Email' => array('send'),
'Session'
)
));

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

CakePHP Cookbook Documentation, Version 2.x

->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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Tester un Controller de Rponse JSON


JSON est un format sympa et courant utiliser quand on construit un service web. Tester les endpoints
de votre service web est trs simple avec CakePHP. Commenons par un exemple de controller simple qui
rponde dans JSON :
class MarkersController extends AppController {
public $autoRender = false;
public function index() {
$data = $this->Marker->find('first');
$this->response->body(json_encode($data));
}
}

Maintenant nous crons le fichier app/Test/Case/Controller/MarkersControllerTest.php


et nous assurons que notre service web retourne la rponse approprie :
class MarkersControllerTest extends ControllerTestCase {
public function testIndex() {
$result = $this->testAction('/markers/index.json');
$result = json_decode($result, true);
$expected = array(
'Marker' => array('id' => 1, 'lng' => 66, 'lat' => 45),
);
$this->assertEquals($expected, $result);
}
}

Tester les Views


Gnralement, la plupart des applications ne va pas directement tester leur code HTML. Faire a donne
souvent des rsultats fragiles, il est difficile de maintenir les suites de test qui sont sujet se casser. En
crivant des tests fonctionnels en utilisant ControllerTestCase, vous pouvez inspecter le contenu de
la vue rendue en configurant loption return view. Alors quil est possible de tester le contenu de la
vue en utilisant ControllerTestCase, un test dintgration/vue plus robuste et maintenable peut tre effectu
en utilisant des outils comme Selenium webdriver 7 .

Tester les Components


Imaginons que nous avons un component appel PagematronComponent dans notre application. Ce component nous aide paginer la valeur limite travers tous les controllers qui lutilisent. Voici notre exemple de
component localis dans app/Controller/Component/PagematronComponent.php :
class PagematronComponent extends Component {
public $Controller = null;
public function startup(Controller $controller) {
parent::startup($controller);
7. http ://seleniumhq.org

Testing

919

CakePHP Cookbook Documentation, Version 2.x

$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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

// Tester notre mthode adjust avec les configurations de diffrents paramtres


$this->PagematronComponent->adjust();
$this->assertEquals(20, $this->Controller->paginate['limit']);
$this->PagematronComponent->adjust('medium');
$this->assertEquals(50, $this->Controller->paginate['limit']);
$this->PagematronComponent->adjust('long');
$this->assertEquals(100, $this->Controller->paginate['limit']);
}
public function tearDown() {
parent::tearDown();
// Nettoie aprs l'avoir fait
unset($this->PagematronComponent);
unset($this->Controller);
}
}

Tester les Helpers


Puisquun bon nombre de logique se situe dans les classes Helper, il est important de sassurer que ces
classes sont couvertes par des cas de test.
Tout dabord, nous crons un helper dexemple tester. CurrencyRendererHelper va nous aider
afficher les monnaies dans nos vues et pour simplifier, il ne va avoir quune mthode usd().
// app/View/Helper/CurrencyRendererHelper.php
class CurrencyRendererHelper extends AppHelper {
public function usd($amount) {
return 'USD ' . number_format($amount, 2, '.', ',');
}
}

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

CakePHP Cookbook Documentation, Version 2.x

$View = new View($Controller);


$this->CurrencyRenderer = new CurrencyRendererHelper($View);
}
// Test de la fonction usd()
public function testUsd() {
$this->assertEquals('USD 5.30', $this->CurrencyRenderer->usd(5.30));
// Nous devrions toujours avoir 2 dcimales
$this->assertEquals('USD 1.00', $this->CurrencyRenderer->usd(1));
$this->assertEquals('USD 2.05', $this->CurrencyRenderer->usd(2.05));
// Test du sparateur des milliers
$this->assertEquals('USD 12,000.70', $this->CurrencyRenderer->usd(12000.70));
}
}

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.

Crer les Test Suites


Si vous voulez que plusieurs de vos tests soient lancs en mme temps vous pouvez crer un test suite. Un
testsuite est compos de plusieurs cas de test. CakeTestSuite offre quelques mthodes pour facilement
crer des test suites bas sur le systme de fichier. Si nous voulions crer un test suite pour tous nos models
tests, nous pourrions crer app/Test/Case/AllModelTest.php. Mettez ce qui suit dedans :
class AllModelTest extends CakeTestSuite {
public static function suite() {
$suite = new CakeTestSuite('All model tests');
$suite->addTestDirectory(TESTS . 'Case/Model');
return $suite;
}
}

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

return $suite;
}
}

Vous pouvez ensuite lancer ce test en ligne de commande en utilisant :


$ Console/cake test app AllTests

Crer des Tests pour les Plugins


Les Tests pour les plugins sont crs dans leur propre rpertoire lintrieur du dossier des plugins.
/app
/Plugin
/Blog
/Test
/Case
/Fixture

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.

Intgration avec Jenkins


Jenkins 8 est un serveur dintgration continu, qui peut vous aider automatiser lexcution de vos cas de
8. http ://jenkins-ci.org

Testing

923

CakePHP Cookbook Documentation, Version 2.x

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 :

mysql -u jenkins -pcakephp_jenkins -e 'DROP DATABASE IF EXISTS jenkins_test; CREATE DATABAS

Ajouter vos tests


Ajoutez une autre tape de script shell votre build. Dans cette tape, lancez les tests pour votre application.
Crer un fichier de log junit, ou clover coverage est souvent un bonus sympa, puisquil vous donne une vue
graphique sympa des rsultats de votre test :
9. http ://jenkins-ci.org/

924

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

app/Console/cake testsuite app AllTests \


--stderr \
--log-junit junit.xml \
--coverage-clover clover.xml

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.

Mise en place Simple


Le moyen le plus rapide pour dmarrer avec REST est dajouter quelques lignes votre fichier routes.php,
situ dans app/Config. Lobjet Router comporte une mthode appele mapResources() utilise pour
mettre en place un certain nombre de routes par dfaut accdant par REST vos controllers. Assurez-vous
que mapResources() vienne avant require CAKE . Config . DS . routes.php;.
Si nous souhaitions permettre laccs par REST une base de donnes de recettes, nous ferions comme
cela :
//Dans app/Config/routes.php...
Router::mapResources('recipes');
Router::parseExtensions();

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

CakePHP Cookbook Documentation, Version 2.x

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

Action de contrleur appele


RecipesController : :index()
RecipesController : :view(123)
RecipesController : :add()
RecipesController : :edit(123)
RecipesController : :edit(123)
RecipesController : :delete(123)

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

'_serialize' => array('message')


));
}
public function edit($id) {
$this->Recipe->id = $id;
if ($this->Recipe->save($this->request->data)) {
$message = 'Saved';
} else {
$message = 'Error';
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
public function delete($id) {
if ($this->Recipe->delete($id)) {
$message = 'Deleted';
} else {
$message = 'Error';
}
$this->set(array(
'message' => $message,
'_serialize' => array('message')
));
}
}

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

CakePHP Cookbook Documentation, Version 2.x

Le XML rendu va au final ressembler ceci :


<recipes>
<recipe id="234" created="2008-06-13" modified="2008-06-14">
<author id="23423" first_name="Billy" last_name="Bob"></author>
<comment id="245" body="Yummy yummmy"></comment>
</recipe>
<recipe id="3247" created="2008-06-15" modified="2008-06-15">
<author id="625" first_name="Nate" last_name="Johnson"></author>
<comment id="654" body="This is a comment for this tasty dish."></comment>
</recipe>
</recipes>

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.

Accepter une entre dans dautres formats


Typiquement, les applications REST ne sortent pas seulement le contenu dans les formats de donnes alternatifs, elles acceptent aussi les donnes dans des formats diffrents. Dans CakePHP,
RequestHandlerComponent facilite cela. Par dfaut, il va dcoder toute entre de donnes entrante
JSON/XML pour les requtes POST/PUT et fournir la version de tableau de cette donne dans $this>request->data. Vous pouvez aussi connecter dans les deserializers supplmentaires pour des formats alternatifs si vous en avez besoin, utilisez RequestHandler::addInputType().

Modifier les routes REST par dfaut


Introduit dans la version 2.1.
Si les routes REST par dfaut ne fonctionnent pas pour votre application, vous pouvez les modifier en
utilisant Router::resourceMap(). Cette mthode vous permet de dfinir les routes par dfaut qui
rcuprent lensemble avec Router::mapResources(). Quand vous utilisez cette mthode vous devez
dfinir toutes les valeurs par dfaut que vous voulez utiliser :
Router::resourceMap(array(
array('action' => 'index', 'method' => 'GET', 'id' => false),
array('action' => 'view', 'method' => 'GET', 'id' => true),
array('action' => 'add', 'method' => 'POST', 'id' => false),
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
array('action' => 'update', 'method' => 'POST', 'id' => true)
));

En crivant par dessus la ressource map par dfaut, les appels futurs mapResources() vont utiliser les
nouvelles valeurs.
928

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

Routing REST Personnalis


Si les routes cres par dfaut par Router::mapResources() ne fonctionnent pas pour vous, utilisez
la mthode Router::connect() pour dfinir un ensemble personnalis de routes REST. La mthode
connect() vous permet de dfinir un certain nombre doptions diffrentes pour une URL donne. Regardez la section sur Utiliser des conditions supplmentaires de correspondance des routes pour plus dinformations.
Introduit dans la version 2.5.
Vous pouvez fournir la cl connectOptions dans le
Router::mapResources()
pour
fournir
un
paramtre
Router::connect() :

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.

Configurer les Filtres


Les filtres sont gnralement configurs dans le fichier bootstrap.php, mais vous pouvez facilement
les charger partir dun autre fichier de configuration avant que la requte soit dispatche. Ajouter et retirer
les filtres est fait par la classe Configure, en utilisant la cl spciale Dispatcher.filters. Par dfaut
CakePHP est fourni avec des classes de filtre dj actives pour toutes les requtes, allons voir comment
elles ont t ajoutes :
Configure::write('Dispatcher.filters', array(
'AssetDispatcher',
'CacheDispatcher'
));

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Cette classe devrait tre sauvegarde dans un fichier dans app/Routing/Filter/HelloWorldFilter.php


et configure dans le fichier bootstrap comme on la expliqu dans la section prcdente. Il y a plein de
choses expliquer ici, commenons avec la valeur $priority.
Comme mentionn avant, quand vous utilisez les classes de filtre, vous pouvez seulement dfinir lordre
dans lequel elles sont lances en utilisant la proprit $priority dans la classe, la valeur par dfaut est 10
si la proprit est dclare, cela signifie quil sera excut _aprs_ que la classe de Router a pars la requte.
Nous ne voulons pas que cela arrive dans notre exemple prcdent, parce que probablement, vous navez
pas de controller configur pour rpondre cette URL, donc nous avons choisi 9 comme notre priorit.
DispatcherFilter propose deux mthodes qui peuvent tre crases dans des sous-classes, elles sont
beforeDispatch et afterDispatch, et sont excutes respectivement avant ou aprs que tout controller soit excut. Les deux mthodes reoivent un objet CakeEvent contenant les objets request
et response (instances CakeRequest et CakeResponse) avec un tableau additionalParams
lintrieur de la proprit data. Ce qui suit contient des informations utilises pour le dispatching interne
quand on appelle requestAction.
Dans notre exemple, nous avons retourn selon les cas lobjet $response comme rsultat, cela dira au Dispatcher pour ninstancier aucun controller et retourner un objet comme cela en rponse immdiatement au
client. Nous avons aussi ajout $event->stopPropagation() pour empcher dautres filtres dtre
excut aprs celui-ci.
Crons maintenant un autre filtre pour modifier les headers de rponse dans toute page publique, dans notre
cas, ce serait tout ce qui est servi partir de PagesController :
App::uses('DispatcherFilter', 'Routing');
class HttpCacheFilter extends DispatcherFilter {
public function afterDispatch($event) {
$request = $event->data['request'];
$response = $event->data['response'];
if ($request->params['controller'] !== 'pages') {
return;
}
if ($response->statusCode() === 200) {
$response->sharable(true);
$response->expires(strtotime('+1 day'));
}
}
}

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

Chapitre 10. Dveloppement

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

934

Chapitre 10. Dveloppement

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.

Vrifier votre scurit


Si vous sortez votre application dans la nature, il est bon de vous assurer quelle na pas de fuites. Allez voir
Security (Scurit) pour vous scuriser contre les attaques CSRF, la falsification de champ de formulaire,
etc... Utiliser Validation des Donnes, et/ou Assainissement des Donnes (Data Sanitization) est aussi une
bonne ide, pour protger votre base de donnes et aussi contre les attaques XSS. Vrifiez que seul votre
rpertoire webroot est visible publiquement, et que vos secrets (comme le salt de votre app, et les cls de
scurit) sont privs et uniques aussi !

Dfinir le document root


Configurer le document root correctement dans votre application est aussi une tape importante pour garder
votre code scuris et votre application plus sre. Les applications CakePHP devraient avoir le document
root configur au rpertoire app/webroot de lapplication. Cela rend les fichiers de lapplication et de
configuration inaccessibles via une URL. Configurer le document root est diffrent selon les webserveurs.
Regardez la documentation URL Rewriting pour une information sur la spcificit de chaque webserveur.
Dans tous les cas, vous devez dfinir le document de lhte/domaine virtuel pour quil soit app/webroot/.
Cela retire la possibilit que des fichiers soient excuts en-dehors du rpertoire webroot.

Mise jour de core.php


Mettre jour core.php, spcialement la valeur de debug est extrmement important. Mettre debug = 0
dsactive un certain nombre de fonctionnalits de dveloppement qui ne devraient jamais tre exposes sur
internet. Dsactiver le debug change les types de choses suivantes :

935

CakePHP Cookbook Documentation, Version 2.x

Les messages de Debug, crs avec pr() et debug() sont dsactivs.


Les caches du Coeur de CakePHP sont flushs tous les 999 jours, au lieu de toutes les 10 secondes en
dveloppement.
Les vues dErreur sont moins informatives, et renvoient des messages gnriques derreur la place.
Les Erreurs ne sont pas affiches.
Les traces de pile dException sont dsactives.
En plus des lments ci-dessus, beaucoup de plugins et dextensions dapplication utilisent debug pour
modifier leur comportement.
Vous pouvez crer une variable denvironnement pour dfinir le niveau de debug dynamiquement entre
plusieurs environnements. Cela va viter de dployer une application avec debug > 0 et vous permet de ne
pas avoir changer de niveau de debug chaque fois avant de dployer vers un environnement de production.
Par exemple, vous pouvez dfinir une variable denvironnement dans votre configuration Apache :
SetEnv CAKEPHP_DEBUG 2

Et ensuite vous pouvez dfinir le niveau de debug dynamiquement dans core.php :


if (getenv('CAKEPHP_DEBUG')) {
Configure::write('debug', 2);
} else {
Configure::write('debug', 0);
}

Amliorer les performances de votre application


Comme la gestion des lments statiques, comme les images, le Javascript et les fichiers CSS des plugins
travers le Dispatcher est incroyablement inefficace, il est chaudement 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

936

Chapitre 11. Dploiement

CHAPITRE 12

Authentification Simple et Autorisation de


lApplication

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.

Crer le code li de tous les users


Premirement, creons une nouvelle table dans notre base de donnes du blog pour contenir les donnes de
notre user :
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
password VARCHAR(255),
role VARCHAR(20),
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);

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

CakePHP Cookbook Documentation, Version 2.x

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) {
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

Chapitre 12. Authentification Simple et Autorisation de lApplication

CakePHP Cookbook Documentation, Version 2.x

return $this->redirect(array('action' => 'index'));


} else {
$this->Flash->error(__('L\'user n\'a pas t sauvegard. Merci de ressayer
}
}
}

public function edit($id = null) {


$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('User Invalide'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->save($this->request->data)) {
$this->Flash->success(__('L\'user a t sauvegard'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Flash->error(__('L\'user n\'a pas t sauvegard. Merci de ressayer
}
} else {
$this->request->data = $this->User->findById($id);
unset($this->request->data['User']['password']);
}
}
public function delete($id = null) {
// Avant 2.5, utilisez
// $this->request->onlyAllow('post');
$this->request->allowMethod('post');
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('User invalide'));
}
if ($this->User->delete()) {
$this->Flash->success(__('User supprim'));
return $this->redirect(array('action' => 'index'));
}
$this->Flash->error(__('L\'user n\'a pas t supprim'));
return $this->redirect(array('action' => 'index'));
}
}

Modifi dans la version 2.5 : Depuis 2.5, utilisez CakeRequest::allowMethod() au lieu de


CakeRequest::onlyAllow() (dprcie).
De la mme faon, nous avons cr les vues pour nos posts de blog ou en utilisant loutil de gnration de
code, nous excutons les vues. Dans le cadre de ce tutoriel, nous allons juste montrer le add.ctp :
<!-- app/View/Users/add.ctp -->
<div class="users form">

Crer le code li de tous les users

939

CakePHP Cookbook Documentation, Version 2.x

<?php echo $this->Form->create('User');?>


<fieldset>
<legend><?php echo __('Ajouter User'); ?></legend>
<?php echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->input('role', array(
'options' => array('admin' => 'Admin', 'auteur' => 'Auteur')
));
?>
</fieldset>
<?php echo $this->Form->end(__('Ajouter'));?>
</div>

Authentification (Connexion et Deconnexion)


Nous sommes maintenant prt ajouter notre couche dauthentification. Dans CakePHP, cest gr par
AuthComponent, une classe responsable dexiger la connexion pour certaines actions, de grer la connexion et la dconnexion, et aussi dautoriser aux users connects les actions que lon souhaite leur voir
autorises.
Pour
ajouter
ce
component

votre
application,
ouvrez
app/Controller/AppController.php et ajoutez les lignes suivantes :

votre

fichier

// app/Controller/AppController.php
class AppController extends Controller {
//...

public $components = array(


'Flash',
'Auth' => array(
'loginRedirect' => array('controller' => 'posts', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home
)
);
public function beforeFilter() {
$this->Auth->allow('index', 'view');
}
//...
}

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

Chapitre 12. Authentification Simple et Autorisation de lApplication

CakePHP Cookbook Documentation, Version 2.x

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 :

Authentification (Connexion et Deconnexion)

941

CakePHP Cookbook Documentation, Version 2.x

//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.

Autorisation (Qui est autoris accder quoi)


Comme mentionn avant, nous convertissons ce blog en un outil multi-user autorisation, et pour ce faire,
nous avons besoin de modifier un peu la table posts pour ajouter la rfrence au model User :
ALTER TABLE posts ADD COLUMN user_id INT(11);

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

Chapitre 12. Authentification Simple et Autorisation de lApplication

CakePHP Cookbook Documentation, Version 2.x

$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;
}

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

CakePHP Cookbook Documentation, Version 2.x

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);
}

Nous surchargeons maintenant lappel isAuthorized() de AppControllers et vrifions lintrieur si


la classe parente autorise dj luser. Si elle ne le fait pas, alors nous ajoutons juste lautorisation daccder
laction add, et ventuellement accs pour modifier et de supprimer. Une dernire chose que nous avons
oublie dexcuter est de dire si luser lautorisation ou non de modifier le post, nous appelons une fonction
isOwnedBy() dans le model Post. Cest gnralement une bonne pratique de dplacer autant que possible
la logique dans les models. Laissons la fonction sexcuter :
// app/Model/Post.php
public function isOwnedBy($post, $user) {
return $this->field('id', array('id' => $post, 'user_id' => $user)) !== false;
}

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.

Lectures suivantes suggres


1. Gnration de code avec Bake Gnration basique CRUD de code
2. Authentification : Inscription duser et connexion

944

Chapitre 12. Authentification Simple et Autorisation de lApplication

CHAPITRE 13

Application Simple contrle par Acl

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.

Prparer notre Application


Premirement, rcuprons une copie rcente de CakePHP
Pour obtenir un tlchargement jour, visitez le projet CakePHP sur Github :
https ://github.com/cakephp/cakephp/tags et tlchargez la version stable. Pour ce tutoriel vous aurez
besoin de la dernire version 2.x.
Vous pouvez aussi dupliquer le dpt en utilisant git 1 :
1. http ://git-scm.com/

945

CakePHP Cookbook Documentation, Version 2.x

git clone git://github.com/cakephp/cakephp.git.

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

Chapitre 13. Application Simple contrle par Acl

CakePHP Cookbook Documentation, Version 2.x

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.

Prparer lajout dAuth


Nous avons maintenant une application CRUD (Crer Lire Editer Supprimer) fonctionnelle. Bake devrait
avoir mis en place toutes les relations dont nous avons besoin, si ce nest pas le cas, faites-le maintenant. Il
y a quelques autres lments qui doivent tre ajouts avant de pouvoir ajouter les components Auth et Acl.
Tout dabord, ajoutez une action login et une action logout votre UsersController :

public function login() {


if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash(__('Votre nom d\'user ou mot de passe sont incorrects.
}
}
}
public function logout() {
//Laissez vide pour le moment.
}

Ensuite crer le fichier de vue suivant pour la connexion app/View/Users/login.ctp :


echo $this->Form->create('User', array('action' => 'login'));
echo $this->Form->inputs(array(
'legend' => __('Login'),
'username',
'password'
));
echo $this->Form->end('Connexion');

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.

public function beforeSave($options = array()) {


$this->data['User']['password'] = AuthComponent::password($this->data['User']['pass
return true;

Prparer lajout dAuth

947

CakePHP Cookbook Documentation, Version 2.x

}
}

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

Chapitre 13. Application Simple contrle par Acl

CakePHP Cookbook Documentation, Version 2.x

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.

Initialiser les tables Acl dans la BdD


Avant de crer des users et groups, nous voulons les connecter lAcl. Cependant, nous navons pour le
moment aucune table dAcl et si vous essayez de visualiser les pages maintenant, vous aurez peut-tre une
erreur de table manquante (Error : Database table acos for model Aco was not found.). Pour supprimer
ces erreurs, nous devons excuter un fichier de schma. Dans un shell, excutez la commande suivante :
./Console/cake schema create DbAcl

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.

Agir comme un requteur


Pour que Auth et Acl fonctionnent correctement, nous devons associer nos users et groups dans les entres de
nos tables Acl. Pour ce faire, nous allons utiliser le behavior AclBehavior. Le behavior AclBehavior
permet de connecter automagiquement des models avec les tables Acl. Son utilisation requiert limplmentation de parentNode() dans vos models. Dans notre Model User nous allons ajouter le code suivant
class User extends Model {
public $belongsTo = array('Group');
public $actsAs = array('Acl' => array('type' => 'requester'));
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['group_id'])) {
$groupId = $this->data['User']['group_id'];
} else {
$groupId = $this->field('group_id');
}
if (!$groupId) {
return null;
}
return array('Group' => array('id' => $groupId));
}
}

Initialiser les tables Acl dans la BdD

949

CakePHP Cookbook Documentation, Version 2.x

Ensuite dans notre Model Group ajoutons ce qui suit :


class Group extends Model {
public $actsAs = array('Acl' => array('type' => 'requester'));
public function parentNode() {
return null;
}
}

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.

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']);
}

950

Chapitre 13. Application Simple contrle par Acl

CakePHP Cookbook Documentation, Version 2.x

Ensuite modifiez le actsAs pour le model User et dsactivez la directive requester :


public $actsAs = array('Acl' => array('type' => 'requester', 'enabled' => false));

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.

Crer les ACOs (Access Control Objects)


Maintenant que nous avons nos users et groups (aros), nous pouvons commencer intgrer nos controllers
existants dans lAcl et dfinir des permissions pour nos groups et users, et permettre la connexion / dconnexion.
Nos AROs sont automatiquement crs lorsque de nouveaux users et groups sont ajouts. Quen est-til de
lauto-gnration des ACOs pour nos controllers et leurs actions ? Et bien, il ny a malheureusement pas de
solution magique dans le core de CakePHP pour raliser cela. Les classes du core offrent cependant quelques
moyens pour crer manuellement les ACOs. Vous pouvez crer des objets ACO depuis le shell Acl, ou alors
vous pouvez utiliser lAclComponent. Crer les Acos depuis le shell ressemble cela :
./Console/cake acl create aco root controllers

En utilisant lAclComponent, cela ressemblera :


$this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'controllers'));
$this->Acl->Aco->save();

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 :

Crer les ACOs (Access Control Objects)

951

CakePHP Cookbook Documentation, Version 2.x

class AppController extends Controller {


public $components = array(
'Acl',
'Auth' => array(
'authorize' => array(
'Actions' => array('actionPath' => 'controllers')
)
),
'Session'
);

Continuez Application Simple contrle par Acl - partie 2 pour continuer le tutoriel.

952

Chapitre 13. Application Simple contrle par Acl

CHAPITRE 14

Application Simple contrle par Acl partie 2

Un outil automatique pour la cration des ACOs


Comme mentionn avant, il ny a pas de faon pr-construite dinsrer tous vos controllers et actions dans
Acl. Cependant, nous dtestons tous faire des choses rptitives comme faire ce qui pourrait tre des centaines dactions dans une grande application.
Pour cela, il existe un plugin disponible trs branch sur github, appel AclExtras 1 qui peut tre tlcharg
sur La page de Tlchargements de Github 2 . Nous allons dcrire brivement la faon dont on lutilise pour
gnrer tous nos ACOs.
Premirement prenez une copie du plugin et dzipper le ou dupliquer le en utilisant git dans
app/Plugin/AclExtras. Ensuite, activez le plugin dans votre fichier app/Config/boostrap.php comme montr
ci-dessus :
//app/Config/boostrap.php
// ...
CakePlugin::load('AclExtras');

Enfin excutez la commande suivante dans la console de CakePHP :


./Console/cake AclExtras.AclExtras aco_sync

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

CakePHP Cookbook Documentation, Version 2.x

Configurer les permissions


Pour crer les permissions, limage de la cration des ACOs, il ny a pas de solution magique et je nen
fournirai pas non plus. Pour autoriser des AROs accder des ACOs depuis linterface en ligne de commande, utilisez AclShell : Pour plus dinformations sur la faon de lutiliser, consultez laide de AclShell
que lon peut avoir en lanant :
./Console/cake acl --help

Note : * a besoin dtre mis entre quotes (*)


Pour donner des autorisations avec AclComponent, nous utiliserons la syntaxe de code suivante dans une
mthode personnalise :
$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";

954

Chapitre 14. Application Simple contrle par Acl - partie 2

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

Si luser est dj connect, on le redirige en ajoutant ceci au controller UsersController :


public function login() {
if ($this->Session->read('Auth.User')) {
$this->Session->setFlash('Vous tes connect!');
return $this->redirect('/');
}
}

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 14. Application Simple contrle par Acl - partie 2

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.

Tutoriel dun Blog


Bienvenue sur CakePHP. Vous consultez probablement ce tutoriel parce que vous voulez en apprendre plus
propos du fonctionnement de CakePHP. Cest notre but damliorer la productivit et de rendre le dveloppement plus agrable : nous esprons que vous le dcouvrirez au fur et mesure que vous plongerez dans le
code.
Ce tutoriel vous accompagnera travers la cration dune simple application de blog. Nous rcuprerons et
installerons CakePHP, crerons et configurerons une base de donnes et ajouterons suffisamment de logique
applicative pour lister, ajouter, diter et supprimer des posts.
Voici ce dont vous aurez besoin :
1. Un serveur web fonctionnel. Nous supposerons que vous utilisez Apache, bien que les instructions
pour utiliser dautres serveurs doivent tre assez semblables. Nous aurons peut-tre besoin de jouer un
peu sur la configuration du serveur, mais la plupart des personnes peuvent faire fonctionner CakePHP
sans aucune configuration pralable.
2. Un serveur de base de donnes. Dans ce tutoriel, nous utiliserons MySQL. Vous aurez besoin dun
minimum de connaissance en SQL afin de crer une base de donnes : CakePHP prendra les rnes
partir de l.
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.
1. http ://plugins.cakephp.org/
2. http ://bakery.cakephp.org/

957

CakePHP Cookbook Documentation, Version 2.x

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.

Crer la base de donnes du blog


Maintenant, mettons en place la base de donnes pour notre blog. Si vous ne lavez pas dj fait, crez une
base de donnes vide avec le nom de votre choix pour lutiliser dans ce tutoriel. Pour le moment, nous allons
3. http ://git-scm.com/

958

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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.

Configurer la base de donnes CakePHP


En avant : indiquons CakePHP o se trouve notre base de donnes et comment sy connecter. Pour la
plupart dentre vous, cest la premire et dernire fois que vous configurerez quelque chose.
Une copie du fichier de configuration CakePHP pour la base de donnes se trouve dans
/app/Config/database.php.default. Faites une copie de ce fichier dans le mme rpertoire mais
nommez le database.php.
Le fichier de configuration devrait tre assez simple : remplacez simplement les valeurs du tableau
$default par celles qui correspondent votre installation. Un exemple de tableau de configuration complet pourrait ressembler ce qui suit :
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'port' => '',
'login' => 'cakeBlog',
'password' => 'c4k3-rUl3Z',
'database' => 'cake_blog_tutorial',
'schema' => '',

Tutoriel dun Blog

959

CakePHP Cookbook Documentation, Version 2.x

'prefix' => '',


'encoding' => 'utf8'
);

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');

Une note sur mod_rewrite


Occasionnellement, les nouveaux utilisateurs peuvent avoir des problmes de mod_rewrite. Par exemple si
la page daccueil de CakePHP a lair bizarre (pas dimages ou de styles CSS), cela signifie probablement
que mod_rewrite ne fonctionne pas sur votre systme. Merci de vous rfrer la section suivante sur lURL
rewriting pour que votre serveur web fonctionne :

960

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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.

Tutoriel dun Blog

961

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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

De belles URLs sur nginx

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/;

Tutoriel dun Blog

963

CakePHP Cookbook Documentation, Version 2.x

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 ;).

Rewrites dURL sur IIS7 (serveurs Windows)

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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"
)

Rgles de rewrite URL pour Hiawatha

La rgle ncessaire UrlToolkit (pour le rewriting URL) pour utiliser CakePHP avec Hiawatha est :

Tutoriel dun Blog

965

CakePHP Cookbook Documentation, Version 2.x

UrlToolkit {
ToolkitID = cakephp
RequestURI exists Return
Match .* Rewrite /index.php
}

Je ne veux / ne peux utiliser lURL rewriting

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.

Blog Tutoriel - Ajouter la logique


Crer un model Post
La classe Model est le pain quotidien des applications CakePHP. En crant un model CakePHP qui interagira
avec notre base de donnes, nous aurons mis en place les fondations ncessaires pour faire plus tard nos
oprations de lecture, dinsertion, ddition et de suppression.
Les fichiers des classes Model de CakePHP se trouvent dans /app/Model, et le fichier que nous allons
crer maintenant sera enregistr dans /app/Model/Post.php. Le fichier complet devrait ressembler
ceci
class Post extends AppModel {
}

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.

Crer un controller Posts


Nous allons maintenant crer un controller pour nos posts. Le controller est lendroit o sexcutera toute la
logique mtier pour lintraction du processus de post. En un mot, cest lendroit o vous jouerez avec les

966

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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).

Crer les Vues des Posts


Maintenant que nous avons nos donnes en provenance du model, ainsi que la logique applicative et les flux
dfinis par notre controller, nous allons crer une vue pour laction index que nous avons cr ci-dessus.
Les vues de CakePHP sont juste des fragments de prsentation assaisonne, qui sintgrent au sein dun
layout applicatif. Pour la plupart des applications, elles sont un mlange de HTML et PHP, mais les vues
peuvent aussi tre constitues de XML, CSV ou mme de donnes binaires.
Un Layout est un code de prsentation, encapsul autour dune vue. Ils peuvent tre dfinis et interchangs,
mais pour le moment, utilisons juste celui par dfaut.

Blog Tutoriel - Ajouter la logique

967

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

<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) {

Blog Tutoriel - Ajouter la logique

969

CakePHP Cookbook Documentation, Version 2.x

throw new NotFoundException(__('Invalid post'));


}
$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this->set('post', $post);
}
}

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

<!-- Fichier : /app/View/Posts/view.ctp -->


<h1><?php echo h($post['Post']['title']); ?></h1>
<p><small>Cr le : <?php echo $post['Post']['created']; ?></small></p>
<p><?php echo h($post['Post']['body']); ?></p>

Vrifiez que cela fonctionne en testant les liens de la page /posts/index ou en affichant manuellement un
post via /posts/view/1.

Ajouter des Posts


Lire depuis la base de donnes et nous afficher les posts est un bon dbut, mais lanons-nous dans lajout de
nouveaux posts.
Premirement, commenons par crer une action add() dans le PostsController
class PostsController extends AppController {
public $helpers = array('Html', 'Form', 'Flash');
public $components = array('Flash');
public function index() {
$this->set('posts', $this->Post->find('all'));
}

970

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

public function view($id) {


if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findById($id);
if (!$post) {
throw new NotFoundException(__('Invalid post'));
}
$this->set('post', $post);
}
public function add() {
if ($this->request->is('post')) {
$this->Post->create();
if ($this->Post->save($this->request->data)) {
$this->Flash->success(__('Your post has been saved.'));
return $this->redirect(array('action' => 'index'));
}
$this->Flash->error(__('Unable to add your post.'));
}
}
}

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

Blog Tutoriel - Ajouter la logique

971

CakePHP Cookbook Documentation, Version 2.x

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.

Valider les donnes


Cake place la barre trs haute pour briser la monotonie de la validation des champs de formulaires. Tout le
monde dteste le dvelopement de formulaires interminables et leurs routines de validations. Cake rend tout
cela plus facile et plus rapide.
Pour tirer profit des fonctionnalits de validation, vous devez utiliser le helper Form (FormHelper) dans
vos vues. FormHelper est disponible par dfaut dans toutes les vues avec la variables $this->Form.
Voici le code de notre vue add (ajout)
<!-- Fichier : /app/View/Posts/add.ctp -->
<h1>Ajouter un post</h1>
<?php
echo $this->Form->create('Post');
echo $this->Form->input('title');
echo $this->Form->input('body', array('rows' => '3'));
echo $this->Form->end('Sauvegarder le post');
?>

Nous utilisons le FormHelper pour gnrer la balise douverture dune formulaire HTML. Voici le code
HTML gnr par $this->Form->create()
.. code-block:: html

<form id=PostAddForm method=post action=/posts/add>


Si create() est appele sans aucun paramtre, CakePHP suppose que vous construisez un formulaire qui
envoie les donnes en POST laction add() (ou edit() quand id est dans les donnes du formulaire)
du controller actuel.
La mthode $this->Form->input() est utilise pour crer des lments de formulaire du mme nom.
Le premier paramtre dit CakePHP quels champs ils correspondent et le second paramtre vous permet
de spcifier un large ventail doptions - dans ce cas, le nombre de lignes du textarea. Il y a un peu dintrospection et dautomagie ici : input() affichera diffrents lments de formulaire selon le champ spcifi
du model.
9. http ://api.cakephp.org

972

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

Lappel de la mthode $this->Form->end() gnre un bouton de soumission et ajoute la balise de


fermeture du formulaire. Si une chane de caractres est passe comme premier paramtre de la mthode
end(), le helper Form affichera un bouton de soumission dont le nom correspond celle-ci. Encore une
fois, rfrez-vous au chapitre Helpers (Assistants) pour en savoir plus sur les helpers.
A prsent, revenons en arrire et modifions notre vue /app/View/Posts/index.ctp pour ajouter un
lien Ajouter un post. Ajoutez la ligne suivante avant <table>
<?php echo $this->Html->link(
'Ajouter un Post',
array('controller' => 'posts', 'action' => 'add')
); ?>

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.

Editer des Posts


Ldition de posts : nous y voil. Vous tes un pro de CakePHP maintenant, vous devriez donc avoir adopt
le principe. Crez dabord laction puis la vue. Voici quoi laction edit() du controller Posts (PostsController) devrait ressembler
public function edit($id = null) {
if (!$id) {
throw new NotFoundException(__('Invalid post'));
}
$post = $this->Post->findById($id);

Blog Tutoriel - Ajouter la logique

973

CakePHP Cookbook Documentation, Version 2.x

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

(lien d\'dition ajout) -->

<h1>Blog posts</h1>

974

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

<p><?php echo $this->Html->link("Ajouter un Post", array('action' => 'add')); ?></p>


<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Action</th>
<th>Created</th>
</tr>
<!-- Ici se trouve la boucle de notre tableau $posts, impression de l\'info du post -->
<?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->Html->link(
'Editer',
array('action' => 'edit', $post['Post']['id'])
); ?>
</td>
<td>
<?php echo $post['Post']['created']; ?>
</td>
</tr>
<?php endforeach; ?>
</table>

Supprimer des Posts


A prsent, mettons en place un moyen de supprimer les posts pour les utilisateurs. Dmarrons avec une
action delete() dans le controller Posts (PostsController)
public function delete($id) {
if ($this->request->is('get')) {
throw new MethodNotAllowedException();
}
if ($this->Post->delete($id)) {
$this->Flash->success(
__('Le post avec id : %s a t supprim.', h($id))
);
} else {
$this->Flash->error(
__('Le post avec l\'id: %s n\'a pas pu tre supprim.', h($id))
);

Blog Tutoriel - Ajouter la logique

975

CakePHP Cookbook Documentation, Version 2.x

}
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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

<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.

Blog Tutoriel - Ajouter la logique

977

CakePHP Cookbook Documentation, Version 2.x

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.

Authentification Simple et Autorisation de lApplication


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.

Crer le code li de tous les users


Premirement, creons une nouvelle table dans notre base de donnes du blog pour contenir les donnes de
notre user :
CREATE TABLE users (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50),
password VARCHAR(255),
role VARCHAR(20),
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);
10. http ://api.cakephp.org

978

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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) {

Authentification Simple et Autorisation de lApplication

979

CakePHP Cookbook Documentation, Version 2.x

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'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Flash->error(__('L\'user n\'a pas t sauvegard. Merci de ressayer
}
}
}

public function edit($id = null) {


$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('User Invalide'));
}
if ($this->request->is('post') || $this->request->is('put')) {
if ($this->User->save($this->request->data)) {
$this->Flash->success(__('L\'user a t sauvegard'));
return $this->redirect(array('action' => 'index'));
} else {
$this->Flash->error(__('L\'user n\'a pas t sauvegard. Merci de ressayer
}
} else {
$this->request->data = $this->User->findById($id);
unset($this->request->data['User']['password']);
}
}
public function delete($id = null) {
// Avant 2.5, utilisez
// $this->request->onlyAllow('post');
$this->request->allowMethod('post');
$this->User->id = $id;
if (!$this->User->exists()) {
throw new NotFoundException(__('User invalide'));
}
if ($this->User->delete()) {
$this->Flash->success(__('User supprim'));
return $this->redirect(array('action' => 'index'));
}
$this->Flash->error(__('L\'user n\'a pas t supprim'));
return $this->redirect(array('action' => 'index'));
}

980

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

Modifi dans la version 2.5 : Depuis 2.5, utilisez CakeRequest::allowMethod() au lieu de


CakeRequest::onlyAllow() (dprcie).
De la mme faon, nous avons cr les vues pour nos posts de blog ou en utilisant loutil de gnration de
code, nous excutons les vues. Dans le cadre de ce tutoriel, nous allons juste montrer le add.ctp :
<!-- app/View/Users/add.ctp -->
<div class="users form">
<?php echo $this->Form->create('User');?>
<fieldset>
<legend><?php echo __('Ajouter User'); ?></legend>
<?php echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->input('role', array(
'options' => array('admin' => 'Admin', 'auteur' => 'Auteur')
));
?>
</fieldset>
<?php echo $this->Form->end(__('Ajouter'));?>
</div>

Authentification (Connexion et Deconnexion)


Nous sommes maintenant prt ajouter notre couche dauthentification. Dans CakePHP, cest gr par
AuthComponent, une classe responsable dexiger la connexion pour certaines actions, de grer la connexion et la dconnexion, et aussi dautoriser aux users connects les actions que lon souhaite leur voir
autorises.
Pour
ajouter
ce
component

votre
application,
ouvrez
app/Controller/AppController.php et ajoutez les lignes suivantes :

votre

fichier

// app/Controller/AppController.php
class AppController extends Controller {
//...

public $components = array(


'Flash',
'Auth' => array(
'loginRedirect' => array('controller' => 'posts', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'display', 'home
)
);
public function beforeFilter() {
$this->Auth->allow('index', 'view');
}
//...
}

Authentification Simple et Autorisation de lApplication

981

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

}
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.

Autorisation (Qui est autoris accder quoi)


Comme mentionn avant, nous convertissons ce blog en un outil multi-user autorisation, et pour ce faire,
nous avons besoin de modifier un peu la table posts pour ajouter la rfrence au model User :

Authentification Simple et Autorisation de lApplication

983

CakePHP Cookbook Documentation, Version 2.x

ALTER TABLE posts ADD COLUMN user_id INT(11);

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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);
}

Nous surchargeons maintenant lappel isAuthorized() de AppControllers et vrifions lintrieur si


la classe parente autorise dj luser. Si elle ne le fait pas, alors nous ajoutons juste lautorisation daccder
laction add, et ventuellement accs pour modifier et de supprimer. Une dernire chose que nous avons
oublie dexcuter est de dire si luser lautorisation ou non de modifier le post, nous appelons une fonction
isOwnedBy() dans le model Post. Cest gnralement une bonne pratique de dplacer autant que possible
la logique dans les models. Laissons la fonction sexcuter :
// app/Model/Post.php
public function isOwnedBy($post, $user) {
return $this->field('id', array('id' => $post, 'user_id' => $user)) !== false;
}

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.

Authentification Simple et Autorisation de lApplication

985

CakePHP Cookbook Documentation, Version 2.x

Lectures suivantes suggres


1. Gnration de code avec Bake Gnration basique CRUD de code
2. Authentification : Inscription duser et connexion

Application Simple contrle par Acl


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.

Prparer notre Application


Premirement, rcuprons une copie rcente de CakePHP
Pour obtenir un tlchargement jour, visitez le projet CakePHP sur Github :
https ://github.com/cakephp/cakephp/tags et tlchargez la version stable. Pour ce tutoriel vous aurez
besoin de la dernire version 2.x.
Vous pouvez aussi dupliquer le dpt en utilisant git 11 :
git clone git://github.com/cakephp/cakephp.git.

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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
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.

Application Simple contrle par Acl

987

CakePHP Cookbook Documentation, Version 2.x

Prparer lajout dAuth


Nous avons maintenant une application CRUD (Crer Lire Editer Supprimer) fonctionnelle. Bake devrait
avoir mis en place toutes les relations dont nous avons besoin, si ce nest pas le cas, faites-le maintenant. Il
y a quelques autres lments qui doivent tre ajouts avant de pouvoir ajouter les components Auth et Acl.
Tout dabord, ajoutez une action login et une action logout votre UsersController :

public function login() {


if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash(__('Votre nom d\'user ou mot de passe sont incorrects.
}
}
}
public function logout() {
//Laissez vide pour le moment.
}

Ensuite crer le fichier de vue suivant pour la connexion app/View/Users/login.ctp :


echo $this->Form->create('User', array('action' => 'login'));
echo $this->Form->inputs(array(
'legend' => __('Login'),
'username',
'password'
));
echo $this->Form->end('Connexion');

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.

public function beforeSave($options = array()) {


$this->data['User']['password'] = AuthComponent::password($this->data['User']['pass
return true;
}
}

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

'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();
}

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.

Initialiser les tables Acl dans la BdD


Avant de crer des users et groups, nous voulons les connecter lAcl. Cependant, nous navons pour le
moment aucune table dAcl et si vous essayez de visualiser les pages maintenant, vous aurez peut-tre une
erreur de table manquante (Error : Database table acos for model Aco was not found.). Pour supprimer
ces erreurs, nous devons excuter un fichier de schma. Dans un shell, excutez la commande suivante :
Application Simple contrle par Acl

989

CakePHP Cookbook Documentation, Version 2.x

./Console/cake schema create DbAcl

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.

Agir comme un requteur


Pour que Auth et Acl fonctionnent correctement, nous devons associer nos users et groups dans les entres de
nos tables Acl. Pour ce faire, nous allons utiliser le behavior AclBehavior. Le behavior AclBehavior
permet de connecter automagiquement des models avec les tables Acl. Son utilisation requiert limplmentation de parentNode() dans vos models. Dans notre Model User nous allons ajouter le code suivant
class User extends Model {
public $belongsTo = array('Group');
public $actsAs = array('Acl' => array('type' => 'requester'));
public function parentNode() {
if (!$this->id && empty($this->data)) {
return null;
}
if (isset($this->data['User']['group_id'])) {
$groupId = $this->data['User']['group_id'];
} else {
$groupId = $this->field('group_id');
}
if (!$groupId) {
return null;
}
return array('Group' => array('id' => $groupId));
}
}

Ensuite dans notre Model Group ajoutons ce qui suit :


class Group extends Model {
public $actsAs = array('Acl' => array('type' => 'requester'));
public function parentNode() {
return null;
}
}

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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']);
}

Ensuite modifiez le actsAs pour le model User et dsactivez la directive requester :


public $actsAs = array('Acl' => array('type' => 'requester', 'enabled' => false));

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 :

Application Simple contrle par Acl

991

CakePHP Cookbook Documentation, Version 2.x

+----+-----------+-------+-------------+-------+------+------+
| 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.

Crer les ACOs (Access Control Objects)


Maintenant que nous avons nos users et groups (aros), nous pouvons commencer intgrer nos controllers
existants dans lAcl et dfinir des permissions pour nos groups et users, et permettre la connexion / dconnexion.
Nos AROs sont automatiquement crs lorsque de nouveaux users et groups sont ajouts. Quen est-til de
lauto-gnration des ACOs pour nos controllers et leurs actions ? Et bien, il ny a malheureusement pas de
solution magique dans le core de CakePHP pour raliser cela. Les classes du core offrent cependant quelques
moyens pour crer manuellement les ACOs. Vous pouvez crer des objets ACO depuis le shell Acl, ou alors
vous pouvez utiliser lAclComponent. Crer les Acos depuis le shell ressemble cela :
./Console/cake acl create aco root controllers

En utilisant lAclComponent, cela ressemblera :


$this->Acl->Aco->create(array('parent_id' => null, 'alias' => 'controllers'));
$this->Acl->Aco->save();

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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

Continuez Application Simple contrle par Acl - partie 2 pour continuer le tutoriel.

Application Simple contrle par Acl - partie 2


Un outil automatique pour la cration des ACOs
Comme mentionn avant, il ny a pas de faon pr-construite dinsrer tous vos controllers et actions dans
Acl. Cependant, nous dtestons tous faire des choses rptitives comme faire ce qui pourrait tre des centaines dactions dans une grande application.
Pour cela, il existe un plugin disponible trs branch sur github, appel AclExtras 12 qui peut tre tlcharg
sur La page de Tlchargements de Github 13 . Nous allons dcrire brivement la faon dont on lutilise pour
gnrer tous nos ACOs.
Premirement prenez une copie du plugin et dzipper le ou dupliquer le en utilisant git dans
app/Plugin/AclExtras. Ensuite, activez le plugin dans votre fichier app/Config/boostrap.php comme montr
ci-dessus :
//app/Config/boostrap.php
// ...
CakePlugin::load('AclExtras');

Enfin excutez la commande suivante dans la console de CakePHP :


./Console/cake AclExtras.AclExtras aco_sync

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.

Configurer les permissions


Pour crer les permissions, limage de la cration des ACOs, il ny a pas de solution magique et je nen
fournirai pas non plus. Pour autoriser des AROs accder des ACOs depuis linterface en ligne de commande, utilisez AclShell : Pour plus dinformations sur la faon de lutiliser, consultez laide de AclShell
que lon peut avoir en lanant :
./Console/cake acl --help

Note : * a besoin dtre mis entre quotes (*)


Pour donner des autorisations avec AclComponent, nous utiliserons la syntaxe de code suivante dans une
mthode personnalise :
12. https ://github.com/markstory/acl_extras/
13. https ://github.com/markstory/acl_extras/zipball/master

Application Simple contrle par Acl - partie 2

993

CakePHP Cookbook Documentation, Version 2.x

$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

Chapitre 15. Tutoriels et exemples

CakePHP Cookbook Documentation, Version 2.x

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');
?>

Si luser est dj connect, on le redirige en ajoutant ceci au controller UsersController :


public function login() {
if ($this->Session->read('Auth.User')) {
$this->Session->setFlash('Vous tes connect!');
return $this->redirect('/');
}
}

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).

Application Simple contrle par Acl - partie 2

995

CakePHP Cookbook Documentation, Version 2.x

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 15. Tutoriels et exemples

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

CakePHP Cookbook Documentation, Version 2.x

index.rst
cakephp-overview.rst
getting-started.rst
installation.rst
dossier /installation
dossier /getting-started
dossier /tutorials-and-examples

Note pour les Administrateurs de la Doc


La structure de tous les dossiers de langue doivent reflter la structure du dossier anglais. Si la structure
change pour la version anglaise, nous devrions appliquer ces changements dans les autres langues.
Par exemple, si un nouveau fichier anglais est cr dans en/file.rst, nous devrions :
Ajouter le fichier dans les autres langues : fr/file.rst, zh/file.rst, ...
Supprimer le contenu, mais en gardant les title, informations meta et dventuels lments
toc-tree. La note suivante sera ajoute en anglais tant que personne na traduit le fichier :
File Title
##########
.. note::
The documentation is not currently supported in XX language for this
page.
Please feel free to send us a pull request on
`Github <https://github.com/cakephp/docs>`_ or use the **Improve This Doc**
button to directly propose your changes.
You can refer to the English version in the select top menu to have
information about this page's topic.
// If toc-tree elements are in the English version
.. toctree::
:maxdepth: 1
one-toc-file
other-toc-file
.. meta::
:title lang=xx: File Title
:keywords lang=xx: title, description,...

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

Utilisez une Forme Informelle 3 .


Traduisez la fois le contenu et le titre en mme temps.
Comparez au contenu anglais avant de soumettre une correction (si vous corrigez quelque chose, mais
nintgrez pas un changement en amont, votre soumission ne sera pas accepte).
Si vous avez besoin dcrire un terme anglais, entourez le avec les balises <em>. Ex : asdf asdf Controller
asdf ou asdf asdf Kontroller (Controller) asfd comme il se doit.
Ne soumettez pas de traductions partielles.
Ne modifier pas une section avec un changement en attente.
Nutilisez pas d entits html 4 pour les caractres accentus, le livre utilise UTF-8.
Ne changez pas les balises (HTML) de faon significative ou najoutez pas de nouveau contenu.
Si le contenu original manque dinformations, soumettez une modification pour cette version originale.

Guide de mise en forme de la documentation


La documentation du nouveau CakePHP est crit avec le formatage du texte ReST 5 . ReST (Re Structured
Text) est une syntaxe de texte de balisage similaire markdown, ou textile. Pour maintenir la cohrence,
il est recommand quand vous ajoutez quelque chose la documentation CakePHP que vous suiviez les
directives suivantes sur la faon de formater et de structurer votre texte.
Longueur des lignes
Les lignes de texte doivent tre de 80 colonnes au maximum. Seules exceptions, pour les URLs longues et
les extraits de code.
En-ttes et Sections
Les sections den-tte sont cres par le soulignage du titre avec les caractres de ponctuation, avec une
longueur de texte au moins aussi longue.
# Est utilis pour indiquer les titres de page.
= Est utilis pour les sections dans une page.
- Est utilis pour les sous-sections.
~ Est utilis pour les sous-sous-sections.
^ Est utilis pour les sous-sous-sous-sections.
Les en-ttes ne doivent pas tre imbriqus sur plus de 5 niveaux de profondeur. Les en-ttes doivent tre
prcds et suivis par une ligne vide.
Les Paragraphes
Les paragraphes sont simplement des blocks de texte, avec toutes les lignes au mme niveau dindentation.
Les paragraphes ne doivent pas tre spars par plus dune ligne vide.
3. http ://en.wikipedia.org/wiki/Register_(linguistics)
4. http ://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
5. http ://en.wikipedia.org/wiki/ReStructuredText

Documentation

999

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

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>`_

Le lien ci-dessus gnrera ce Lien Externe 6


Note : Assurez-vous dajouter le underscore aprs le backtick, cest important !

Lien vers les autres pages

: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

CakePHP Cookbook Documentation, Version 2.x

Ailleurs, vous pouvez rfrencer la section suivante en utilisant :ref:label-name. Le texte


du lien serait le titre qui prcde le lien. Vous pouvez aussi fournir un texte de lien sur mesure en
utilisant :ref:Texte de lien <nom-label>.
Eviter lAffichage dAvertissements de Sphinx

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

: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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

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

CakePHP Cookbook Documentation, Version 2.x

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 .

Rapporter des bugs


Bien crits, les rapports de bug sont trs utiles. Il y a quelques tapes pour faire le meilleur rapport de bug
possible :
A Faire des recherches 9 pour un ticket similaire ventuellement existant, et sassurer que personne na
dj report le bug ou quil na pas dj t rsolu dans le rpertoire.
A Faire Inlcure des instructions dtailles de la manire de reproduire le bug. Cela peut tre sous la
forme de cas de Test ou un bout de code dmontrant le problme. Ne pas avoir une possibilit de reproduire le problme, signifie quil est moins facile de le rgler.
A Faire Donner autant de dtails que possible sur votre environnement : (OS, version de PHP, Version de
CakePHP).
A ne pas Faire Utiliser un ticket systme pour poser une question de support technique. Utilisez le Groupe
google 10 ou le canal IRC #cakephp pour cela.

Rapporter des problmes de scurit


Si vous avez trouv un problme de scurit dans CakePHP, merci de bien vouloir utiliser la procdure
suivante, plutt que le systme de rapport de bug classique. Au lieu dutiliser le tracker de bug, la mailingliste ou le canal IRC, merci denvoyer un email security [at] cakephp.org. Les Emails envoys cette
adresse vont lquipe qui construit le coeur de CakePHP via une mailing-liste prive.
Pour chaque rapport, nous essayons dabord de confirmer la vulnrabilit. Une fois confirme, lquipe du
coeur de CakePHP va entreprendre les actions suivantes :
La reconnaissance faite au rapporteur que nous avons reu son problme, et que nous travaillons sa
rparation. Nous demandons au rapporteur de garder le problme confidentiel jusqu ce que nous lannoncions.
Obtenir une prparation dun fix/patch.
Prparer un message dcrivant la vulnrabilit, et sa possible exploitation.
Sortir de nouvelles versions de toutes les versions affectes.
Montrer de faon prohminente le problme dans la publication de lannonce.

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

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>.

Travailler sur un correctif


A chaque fois que vous voulez travailler sur un bug, une fonctionnalit ou une amlioration, crez une
branche avec un sujet.
La branche que vous crez devrait tre base sur la version pour laquelle se tourne votre correctif/amlioration. Par exemple, si vous rgler un bug dans 2.3, vous pouvez utiliser la branche 2.3 comme
la base de votre branche. Cela simplifiera la fusion future de vos changements :
# grer un bug dans 2.3
git fetch upstream
git checkout -b ticket-1234 upstream/2.3
11. http ://git-scm.com/book/
12. http ://github.com
13. http ://github.com/cakephp/cakephp

Code

1007

CakePHP Cookbook Documentation, Version 2.x

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.

Soumettre un pull request


Une fois que vos changements sont faits et que vous tes prts pour la fusion dans CakePHP, vous voudrez
mettre jour votre branche :
git
git
git
git
git

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

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.

Ajout de Nouvelles Fonctionnalits


Aucune nouvelle fonctionnalit ne devrait tre ajoute, sans avoir fait ses propres tests - qui doivent tre
valids avant de les committer au dpt.

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

CakePHP Cookbook Documentation, Version 2.x

$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)));

Utilisez ceci la place :


$matches = array_intersect_key(
$this->_listeners,
array_flip(
preg_grep($matchPattern, array_keys($this->_listeners), 0)
)
);

Longueur des lignes


Il est recommand de garder les lignes une longueur denviron 100 caractres pour une meilleur lisibilit
du code. Les lignes ne doivent pas tre plus longues que 120 caractres.
En rsum :
100 caractres est la limite soft.
120 caractres est la limite hard.

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

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;

// Imbriquations des ternaires est mauvaise


$variable = isset($options['variable']) ? isset($options['othervar']) ? true : false : fals

Normes de codes

1011

CakePHP Cookbook Documentation, Version 2.x

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) {
// ...
}

La valeur avec laquelle on vrifie devra tre place sur le ct droit :


// non recommand
if (null === $this->foo()) {
// ...
}
// recommand
if ($this->foo() === null) {
// ...
}

Appels des Fonctions


Les fonctions doivent tre appeles sans espace entre le nom de la fonction et la parenthse ouvrante. Il doit
y avoir un espace entre chaque paramtre dun appel de fonction :
$var = foo($bar, $bar2, $bar3);

Comme vous pouvez le voir, il doit y avoir un espace des deux cts des signes gal (=).

1012

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

Dfinition des Mthodes


Exemple dun dfinition de mthode :
public function someFunction($arg1, $arg2 = '') {
if (expr) {
statement;
}
return $var;
}

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;
}

Il y a des espaces des deux cts du signe gal.


Typehinting
Les arguments qui attendent des objets ou des tableaux peuvent tre typs :
/**
* Some method description.
*
* @param Model $Model Le model utiliser.
* @param array $array Une valeur de tableau.
* @param bool $boolean Une valeur bolenne.
*/
public function foo(Model $Model, array $array, $boolean) {
}

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

CakePHP Cookbook Documentation, Version 2.x

* @param array|ArrayObject $array Some array value.


*/
public function foo($array) {
}

Chanage des Mthodes


Le chanage des mthodes doit avoir plusieurs mthodes rparties sur des lignes distinctes et indentes avec
une tabulation :
$email->from('foo@example.com')
->to('bar@example.com')
->subject('Un super message')
->send();

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
*
/
*

les tags phpDocumentor 18 inclure sont :


@copyright 19
@link 20
@since 21
18.
19.
20.
21.

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

@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 {
}

Les classes DocBlocks peuvent contenir les tags de phpDocumentor 23 suivants :


@deprecated 24 Utiliser le format @version <vector> <description>, o version et
description sont obligatoires.
@internal 25
@link 26
@property 27
@see 28
@since 29
@uses 30
DocBlocks des Attributs
Les DocBlocks des attributs doivent ressembler cela :
/**
* @var string|null Description of property.
*
* @deprecated 3.0.0 Deprecated as of 2.5.0. Will be removed in 3.0.0. Use $_bla instead.
* @see Bar::$_bla
* @link http://book.cakephp.org/2.0/en/foo.html#properties
22.
23.
24.
25.
26.
27.
28.
29.
30.

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

CakePHP Cookbook Documentation, Version 2.x

*/
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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

@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

CakePHP Cookbook Documentation, Version 2.x

Inclure les Fichiers


include, require, include_once et require_once nont pas de parenthses :
// mauvais = parenthses
require_once('ClassFileName.php');
require_once ($class);
// bon = pas de parenthses
require_once 'ClassFileName.php';
require_once $class;

Quand vous incluez les fichiers avec des classes ou librairies, utilisez seulement et toujours la fonction
require_once 48 .

Les Tags PHP


Toujours utiliser les tags longs (<?php ?>) plutt que les tags courts (<? ?>).

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

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

Visibilit des Membres


Utilisez les mots-cls private et protected de PHP5 pour les mthodes et variables. De plus les noms des
mthodes et variables protges commencent avec un underscore simple (_). Exemple :
class A {
protected $_jeSuisUneVariableProtegee;
protected function _jeSuisUnemethodeProtegee() {
/*...*/
}
}

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

CakePHP Cookbook Documentation, Version 2.x

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);

Guide de Compatibilit Rtroactive


Nous assurer que la mise jour de vos applications se fasse facilement et en douceur est important nos
yeux. Cest pour cela que nous ne cassons la compatibilit que pour les versions majeures. Vous connaissez
peut-tre le versioning smantique 51 , ce qui est la rgle gnrale que nous utilisons pour tous les projets
CakePHP. En rsum, le versioning smantique signifie que seules les versions majeures (comme 2.0, 3.0,
4.0) peuvent casser la compatibilit rtroactive. Les versions mineures (comme 2.1, 3.1, 3.2) peuvent introduire de nouvelles fonctionnalits, mais ne permettent pas de casser la compatibilit. Les versions de fix
de Bug (comme 2.1.2, 3.0.1) najoutent pas de nouvelles fonctionnalits, mais rgle seulement des bugs ou
amliore la performance.
Note : CakePHP a commenc utiliser le versioning smantique partir de la version 2.0.0. Ces rgles ne
sappliquent pas pour la version 1.x.
Pour clarifier les changements que vous pouvez attendre dans chaque version en entier, nous avons plus
dinformations dtailles pour les dveloppeurs utilisant CakePHP et pour les dveloppeurs travaillant sur
CakePHP qui aident dfinir les attentes de ce qui peut tre fait dans des versions mineures. Les versions
majeures peuvent avoir autant de changements que ncessaires.
51. http ://semver.org/

1020

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

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 :

Guide de Compatibilit Rtroactive

1021

CakePHP Cookbook Documentation, Version 2.x

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

Travailler avec CakePHP


Si vous aidez rendre CakePHP encore meilleur, merci de garder lesprit les conventions suivantes lors
des ajouts/changements de fonctionnalits :
Dans une version mineure, vous pouvez :
52. Votre code peut tre cass par des versions mineures. Vrifiez le guide de migration pour plus de dtails.

1022

Chapitre 16. Contribuer

CakePHP Cookbook Documentation, Version 2.x

Dans une versions mineure, pouvez-vous...


Classes
Retirer une classe
Non
Retirer une interface
Non
Retirer un trait
Non
Faire des final
Non
Faire des abstract
Non
Changer de nom
Oui 53
Proprits
Ajouter une proprit
Oui
publique
Retirer une proprit
Non
publique
Ajouter une proprit
Oui
protge
Retirer une proprit
Oui 54
protge
Mthodes
Ajouter une mthode
Oui
publique
Retirer une mthode
Non
publique
Ajouter une mthode
Oui
protge
Dplacer une classe
Oui
parente
Retirer une mthode
Oui 3
protge
Rduire la visibilit
Non
Changer le nom de
Oui 2
mthode
Ajouter un argument
Oui
avec la valeur par
dfaut
Ajouter une argument Non
ncessaire

Le processus de dveloppement CakePHP


Ici, nous tenterons dexpliquer le processus que nous utilisons lors de llaboration du CakePHP. Nous
comptons beaucoup sur linteraction communautaire par le biais billets et par le chat IRC. IRC est le meilleur
endroit pour trouver des membres de lquipe de dveloppement et pour discuter dides, du dernier code,
et de faire des commentaires gnraux. Si quelque chose de plus formel doit tre propos ou sil y a un
53. Vous pouvez changer des noms de classe/mthode tant que le vieux nom reste disponible. Cest gnralement vit moins
que le renommage apporte un vrai bnfice.
54. Nous essayons dviter ceci tout prix. Tout retrait doit tre document dans le guide de migration.

Le processus de dveloppement CakePHP

1023

CakePHP Cookbook Documentation, Version 2.x

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 16. Contribuer

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.

2.8 Guide de Migration


2.8 Guide de Migration
CakePHP 2.8 est une mise jour complte partir de lAPI de 2.7. Cette page souligne les changements et
amliorations faits dans 2.8.
Compatibilit avec PHP7
CakePHP 2.8 est compatible et test pour PHP7.
Dprciations
Loption action dans FormHelper::create() a t dprcie. Cest un portage de la version 3.x.
Notez que la cl action dun tableau URL va tout de mme toujours tre gnre comme ID du DOM.
Si vous utilisez la cl dprcie, vous devrez comparer lID gnr pour le formulaire avant et aprs.
Gestion des Erreurs
Quand vous grez des erreurs fatales, CakePHP ne va maintenant plus ajuster la mmoire limite 4MB
pour sassurer que lerreur peut tre mis correctement en log. Vous pouvez dsactiver ce comportement
en configurant Error.extraFatalErrorMemory 0 dans votre Config/core.php.

1025

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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.

2.7 Guide de Migration


2.7 Guide de Migration
CakePHP 2.7 est une mise jour complte partir de lAPI de 2.6. Cette page souligne les changements et
amliorations faits dans 2.7.
Requirements
La version de PHP requise pour CakePHP 2.7 est maintenant la version 5.3.0.
Console
Les shells de Plugin qui ont le mme nom que leur plugin peuvent maintenant tre appels sans le prfixe
de plugin. Par exemple Console/cake MyPlugin.my_plugin peut maintenant tre appel avec
Console/cake my_plugin.
Shell::param() was backported from 3.0 into 2.7. This method provides a notice error free way to
read CLI options.
Core
Configure

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

CakePHP Cookbook Documentation, Version 2.x

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

SessionComponent::consume() a t ajoute pour lire et supprimer dans Session en une seule


tape.
SessionComponent::setFlash() a t dprcie. Vous devez utiliser FlashComponent la
place.

1028

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

ControllerTestCase::testAction() supporte maintenant un tableau pour une URL.

2.6 Guide de Migration


2.6 Guide de Migration
CakePHP 2.6 est une mise jour complte partir de lAPI de 2.5. Cette page souligne les changements et
amliorations faits dans 2.6.
Basics.php
stackTrace() a t ajoute pour tre une fonction de wrapper pratique pour Debugger::trace().
Elle affiche directement un peu comme debug() le fait. Mais seulement si le niveau de debug est activ.
Les nouvelles fonctions i18n ont t ajoutes. Les nouvelles fonctions vous permettent dinclure un message de contexte ce qui vous permet denlever une ventuelle ambiguit dans des chaines de message. Par
exemple read peut signifier plusieurs choses en anglais selon le contexte. Les nouvelles fonctions __x,
__xn, __dx, __dxn, __dxc, __dxcn, et __xc fournissent un accs ces nouvelles fonctionnalits.
Cache
RedisEngine

RedisEngine a maintenant Inflector::slug(APP_DIR) comme prfixe par dfaut.

2.6 Guide de Migration

1029

CakePHP Cookbook Documentation, Version 2.x

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

LoptionuserFields a t ajoute AuthComponent.


AuthComponent dclenche maintenant un event Auth.afterIdentify aprs quun utilisateur a t
identifi et sest connect. Levent va contenir lutilisateur connect en donnes.
Behavior
AclBehavior

Model::parentNode() prend maintenant le type (Aro, Aco) en premier argument :


$model->parentNode($type).
Datasource
Mysql

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

Model::save() a loption atomic importe de 3.0.

1030

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Model::afterFind() utilise maintenant toujours un format cohrent pour afterFind(). Quand


$primary est false, les rsultats vont toujours tre localiss dans $data[0][ModelName].
Vous pouvez dfinir la proprit useConsistentAfterFind false sur vos models pour restaurer le
comportement original.
Network
CakeRequest

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

CakeTime::timeAgoInWords() supporte maintenant les formats de date absolus compatibles avec


strftime(). Cela facilite la localisation des formats de date.
Hash

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

Validation::between a t dprcie, vous devez utiliser Validation::lengthBetween


la place.
Validation::ssn a t dprcie et peut tre fournie en tant que plugin autonome.

2.6 Guide de Migration

1031

CakePHP Cookbook Documentation, Version 2.x

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.

2.5 Guide de Migration


2.5 Guide de Migration
CakePHP 2.5 est une mise jour complte partir de lAPI de 2.4. Cette page souligne les changements et
amliorations faits dans 2.5.

1032

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

CompletionShell a t ajoute. Il a pour objectif daider la cration de librairies autocompletion pour


les variables denvironnement de shell comme bash, ou zsh. Aucun script shell nest inclu dans CakePHP,
mais les outils sous-jacents sont maintenant disponibles.
Controller
AuthComponent

loggedIn() est maintenant dprcie et sera retire dans 3.0.


Lors de lutilisation de ajaxLogin, AuthComponent va retourner un code de statut 403 au lieu de 200
quand lutilisateur nest pas authentifi.
CookieComponent

CookieComponent peut utiliser le nouveau chiffrement AES-256 offert par Security. Vous pouvez
activer ceci en appelant CookieComponent::type() avec aes.
RequestHandlerComponent

RequestHandlerComponent::renderAs() ne dfinit plus Controller::$ext. Cela posait


des problmes lors de lutilisation dune extension autre que celle par dfaut pour les vues.

2.5 Guide de Migration

1033

CakePHP Cookbook Documentation, Version 2.x

AclComponent

Les checs de vrification de noeud ACL sont maintenant directement mis dans les logs. Lappel de
trigger_error() a t retir.
Scaffold

Le scaffold dynamique est maintenant dprci et sera retir dans 3.0.


Core
App

App::pluginPath() a t dprcie. CakePlugin::path() doit tre utilis la place.


CakePlugin

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

CakeRequest::addDetector() supporte maintenant options qui accepte un tableau des options


valides lors de la cration de paramtre bas sur les detecteurs.
CakeRequest::onlyAllow() a t dprcie. En remplacement, une nouvelle mthode nomme
CakeRequest::allowMethod() a t ajoute avec une fonctionnalit identique. Le nouveau nom
de la mthode est plus intuitif et transmet mieux ce que la mthode fait.
CakeSession

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

Debugger::dump() et Debugger::log() supportent un paramtre $depth. Ce nouveau


paramtre facilite la sortie de structures dobjet imbrique plus profonde.
Hash

Hash::insert() et Hash::remove() supportent maintenant les expressions de matcher dans les


selecteurs de chemin.

2.5 Guide de Migration

1035

CakePHP Cookbook Documentation, Version 2.x

File

File::replaceText() a t ajoute. Cette mthode vous permet de facilement remplacer le texte


en un fichier en utilisant str_replace.
Folder

Folder::addPathElement() accepte maintenant un tableau pour le paramtre $element.


Security

Security::encrypt() et Security::decrypt() ont t ajoutes. Ces mthodes montrent une


API trs simple pour accder au chiffrement symtrique AES-256. Ils doivent tre utiliss en faveur des
mthodes cipher() et rijndael().
Validation

Le troisime paramtre pour Validation::inList() et Validation::multiple() a t


modifi de $strict en $caseInsensitive. $strict a t retir puisquil ne fonctionnait pas correctement et
pouvait tre facilement contourn. Vous pouvez maintenant dfinir ce paramtre true pour des comparaisons non sensibles la casse. Par dfaut, cest false et cela ca comparer la valeur et lister la casse
sensible comme avant.
Le paramtre $mimeTypes de Validation::mimeType() peut aussi tre une chane regex. Aussi
maintenant quand $mimeTypes est un tableau ses valeurs sont en minuscule.
Logging
FileLog

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

Le Scaffold Dynamique est mainteanant dprci et sera retir dans 3.0.

2.4 Guide de Migration


2.4 Guide de Migration
CakePHP 2.4 est une mise jour complte partir de lAPI de 2.3. Cette page souligne les changements et
amliorations faits dans 2.4.
2.4 Guide de Migration

1037

CakePHP Cookbook Documentation, Version 2.x

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 schema generate supporte maintenant le paramtre --exclude.


La constante CAKEPHP_SHELL est maintenant dprcie et sera retire dans CakePHP 3.0.
BakeShell

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

Object::log() a un nouveau paramtre $scope.

1038

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Components
AuthComponent

AuthComponent supporte maintenant le mode proper stateless lors de lutilisation des


authentifieurs Basic ou Digest. Partir de session peut tre empch en configurant
AuthComponent::$sessionKey false. Aussi maintenant lors de lutilisation uniquement
de Basic ou Digest, vous ntes plus redirig vers la page de login. Pour plus dinfos, vrifiez la page
AuthComponent.
La proprit AuthComponent::$authError peut tre dfinie au bolen false pour supprimer
laffichage du message flash.
PasswordHasher

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

Le support de JSONP a t ajout JsonView.


2.4 Guide de Migration

1039

CakePHP Cookbook Documentation, Version 2.x

La cl _serialize supporte maintenant le renommage des variables srialises.


Quand debug > 0, JSON va tre bien imprim.
XmlView

La cl _serialize supporte maintenant le renommage des variables srialises.


Quand debug > 0, XML va tre bien imprim.
HtmlHelper

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

Loption round a t ajoute FormHelper::dateTime(). Peut tre dfinie up ou down pour


forcer larrondi quelque soit la direction. Par dfaut null qui arrondit la moiti suprieure selon
interval.
Network
CakeRequest

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

CakeResponse

CakeResponse::location() a t ajoute pour rcuprer ou dfinir len-tte de localisation du


redirect.
CakeEmail

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

CakePHP Cookbook Documentation, Version 2.x

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

pr() ne sort plus le HTML lors du lancement en mode cli.


Sanitize

La classe Sanitize a t dprcie.


Validation

Validation::date() supporte maintenant les formats y et ym.


Le code de pays de Validation::phone() pour le Canada a t chang de can en ca pour unifier
les codes de pays pour les mthodes de validation selon ISO 3166 (codes deux lettre).

1042

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

CakeNumber

Les monnaies AUD, CAD et JPY ont t ajoutes.


Les symboles pour GBP et EUR sont maintenant UTF-8. Si vous mettez jour une application non-UTF8, assurez-vous que vous mettez jour lattribut statique $_currencies avec les symboles dentit
HTML appropris (&#163; et &#8364;) avant dutiliser ces monnaies.
Loption fractionExponent a t ajoute CakeNumber::currency().
CakeTime

CakeTime::isPast() et CakeTime::isFuture() ont t ajoutes.


CakeTime::timeAgoInWords() a deux nouvelles options pour personnaliser les chanes de sortie :
relativeString (par dfaut %s ago) et absoluteString (par dfaut on %s).
CakeTime::timeAgoInWords() utilise les termes fuzzy quand time est infrieur des seuils.
Xml

La nouvelle option pretty a t ajoute Xml::fromArray() pour retourner un Xml joliment


format.
Error
ErrorHandler

La nouvelle option de configuration skipLog a t ajoute, qui permet dchapper certains


types
dException
du
Log.
Configure::write(Exception.skipLog,
array(NotFoundException, ForbiddenException)); vont viter ces exceptions et
celles qui les tendent dtre dans les logs quand la config Exception.log est true
Routing
Router

Router::fullBaseUrl() a t ajoute en mme temps que la valeur de Configure


App.fullBaseUrl. Elles remplacent FULL_BASE_URL qui est maintenant dprcie.
Router::parse() parse maintenant les arguments de chane de requte.

2.3 Guide de Migration


2.3 Guide de Migration
CakePHP 2.3 est une mise jour de lAPI compltement compatible partir de 2.2. Cette page souligne les
changements et les amliorations faits dans 2.3.
2.3 Guide de Migration

1043

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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)))

2.3 Guide de Migration

1045

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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.

2.3 Guide de Migration

1047

CakePHP Cookbook Documentation, Version 2.x

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

La nouvelle proprit Helper::$settings a t ajoute pour votre configuration du helper. Le


paramtre $settings de Helper::__construct() est fusionn avec Helper::$settings.
FormHelper
FormHelper::select() accpte maintenant une liste de valeurs dans lattribut disabled. Combin
avec multiple => checkbox, cela vous permet de fournir une liste de valeurs que vous voulez
dsactiver.
FormHelper::postLink() accpte maintenant une cl method. Cela vous permet de crer des
formulaires en lien en utilisant dautres mthodes HTTP que POST.
Lors de la cration dinputs avec FormHelper::input(), vous pouvez maintenant dfinir loption
errorMessage false. Ceci va dsactiver laffichage de message erreur, mais laisse les noms de classe
derreur intact.
Le FormHelper ajoute aussi lattribut HTML5 required vos elements dinput bas sur les rgles
de validation pour un champ. Si vous avez un bouton Cancel dans votre formulaire va soumettre le
formulaire puis vous devriez ajouter formnovalidate => true vos options de bouton pour
empcher le dclenchement de la validation dans le HTML. Vous pouvez aussi empcher le dclenchement de la validation pour lensemble du formulaire en ajoutant novalidate => true dans les
options de FormHelper : :create().
FormHelper::input() gnre maintenant les elements dinput de type tel et email bas sur les
noms de champ si loption type nest pas spcifie.
HtmlHelper
HtmlHelper::getCrumbList() a maintenant les options separator, firstClass et
lastClass. Celles-ci vous permettent de mieux contrler le HTML que cette mthode gnre.
TextHelper
TextHelper::tail() a t ajoute pour tronquer le texte en commenant par la fin.
ending dans TextHelper::truncate() est dprci en faveur de ellipsis.

1048

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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/

2.3 Guide de Migration

1049

CakePHP Cookbook Documentation, Version 2.x

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().

2.2 Guide de Migration


2.2 Guide de Migration
CakePHP 2.2 est une mise jour de lAPI compltement compatible partir de 2.0/2.1. Cette page souligne
les changements et amliorations faits dans 2.2.
Etapes requises pour mettre jour
Quand on met jour vers CakePHP 2.2, il est important dajouter quelques nouvelles valeurs de configuration dans app/Config/bootstrap.php. Les ajoutez va assurer que le behavior soit cohrent avec
2.1.x :
// Active les filtres du Dispatcher pour les assets du plugin, et
// du CacheHelper.
Configure::write('Dispatcher.filters', array(
'AssetDispatcher',
'CacheDispatcher'
));
// Ajouter la configuration logging.
CakeLog::config('debug', array(
'engine' => 'FileLog',
'types' => array('notice', 'info', 'debug'),
'file' => 'debug',
));
CakeLog::config('error', array(
'engine' => 'FileLog',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'error',
));

Vous devrez aussi modifier app/Config/core.php. Changez la valeur de LOG_ERROR en LOG_ERR :


define('LOG_ERROR', LOG_ERR);

1050

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Quand on utilise Model::validateAssociated() ou Model::saveAssociated() et les


checs de validation du model principal, les erreurs de validation des models associs ne sont plus dtruites.
Model::$validationErrors va maintenant toujours montrer toutes les erreurs. Vous aurez peut-tre
besoin de mettre jour vos cas de test pour prendre en compte ce changement.
Console
I18N extract shell

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.

2.2 Guide de Migration

1051

CakePHP Cookbook Documentation, Version 2.x

Vous pouvez maintenant configurer la gestion derreur en console spcifique. En configurant


Error.consoleHandler, et Exception.consoleHandler vous pouvez dfinir le callback qui
va grer les errors/exceptions leves dans les applications en console.
Le gestionnaire configur dans Error.handler et Error.consoleHandler va recevoir des codes
derreur fatal (par ex : E_ERROR, E_PARSE, E_USER_ERROR).
Exceptions

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Pagination
Paginer les finders personnaliss va maintenant retourner des comptes corrects, vois les changements de
Model pour plus dinformations.
Network
CakeEmail

CakeEmail::charset() et CakeEmail::headerCharset() ont t ajouts.


Les encodages Japonnais lgaux sont maintenant grs correctement. ISO-2202-JP est utilis lorsque
lencodage est ISO-2202-JP-MS qui fonctionne autour dun nombre de questions dans les mail clients
quand il sagit des encodages CP932 et Shift_JIS.
CakeEmail::theme() a t ajoute.
CakeEmail::domain() a t ajoute. Vous pouvez utiliser cette mthode pour dfinir le nom de
domaine utilis lors de lenvoi de mail partir dun script CLI ou si vous voulez contrler le nom dhte
utilis pour envoyer lemail.
Vous pouvez maintenant dfinir theme et helpers dans votre classe EmailConfig.
CakeRequest

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.

2.2 Guide de Migration

1053

CakePHP Cookbook Documentation, Version 2.x

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

HtmlHelper::tableHeaders() supporte maintenant la configuration des attributs par cellule de


table.
Routing
Dispatcher

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Router

Router::setExtensions() a t ajoute. Avec la nouvelle mthode, vous pouvez maintenant


ajouter plus dextensions parser, par exemple dans un fichier de routes de plugin.
Cache
Redis Engine

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

2.2 Guide de Migration

1055

CakePHP Cookbook Documentation, Version 2.x

CakeLog::debug($message, $scope = array())


Un troisime argument $scope a t ajout CakeLog::write. Regardez Scopes de journalisation.
Un nouveau moteur de log : ConsoleLog a t ajout.
Validation de Model
Un nouvel objet ModelValidator a t ajout pour dlguer le travail de validation des donnes du
model, il est normalement transparent pour lapplication et compltement rtro-compatible. Il fournit
aussi une API riche pour ajouter, modifier et retirer les rgles de validation. Vrifiez les docs pour cet
objet dans Validation des Donnes.
Les fonctions de validation dans vos models devront avoir la visibilit public afin dtre accessibles par
ModelValidator.
De nouvelles rgles de validation ont t ajoutes :
Validation::naturalNumber()
Validation::mimeType()
Validation::uploadError()

2.1 Guide de Migration


2.1 Guide de Migration
CakePHP 2.1 est une mise jour de lAPI compltement compatible partir de 2.0. Cette page souligne les
changements et amliorations faits pour 2.1.
AppController, AppHelper, AppModel et AppShell
Ces classes sont dsormais tenues de faire partie du rpertoire app, puisquelles ont t retires du coeur de
CakePHP. Si vous navez toujours pas ces classes, vous pouvez utiliser ce qui suit pour la mise jour :
// app/View/Helper/AppHelper.php
App::uses('Helper', 'View');
class AppHelper extends Helper {
}
// app/Model/AppModel.php
App::uses('Model', 'Model');
class AppModel extends Model {
}
// app/Controller/AppController.php
App::uses('Controller', 'Controller');
class AppController extends Controller {
}
// app/Console/Command/AppShell.php
App::uses('Shell', 'Console');

1056

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

class AppShell extends Shell {


}

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

I18nModel a t dplac vers un fichier spar.

2.1 Guide de Migration

1057

CakePHP Cookbook Documentation, Version 2.x

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

File::info() inclut les informations de taille et de mimetype du fichier.


File::mime() a t ajoute.
Cache

CacheEngine a t dplace dans un fichier spar.


Configuration

ConfigReaderInterface a t dplace dans un fichier spar.


App

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

Le vieux shell testsuite et sa syntaxe sont encore disponibles.


Gnral

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

Ajout de is(requested) et isRequested() pour la dtection de requestAction.


CakeResponse

Ajout CakeResponse::cookie() pour la dfinition des cookies.


Ajout dun nombre de mthodes pour Rglage fin du Cache HTTP
Controller
Controller

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

CakePHP Cookbook Documentation, Version 2.x

dans la plupart des cas.


true va charger le model par dfaut et fusionnser avec AppController.
Un tableau va charger ces models et fusionner avec AppController.
Un tableau vide ne va charger aucun model, sauf ceux dclars dans la classe de base.
false ne va charger aucun model, et ne va pas non plus fusionner avec la classe de base.
Components (Composants)
AuthComponent

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

HtmlHelper::script() avait une option ajoute block.


HtmlHelper::scriptBlock() avait une option ajoute block.
HtmlHelper::css() avait une option ajoute block.
HtmlHelper::meta() avait une option ajoute block.

1060

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Le paramtre $startText de HtmlHelper::getCrumbs() peut maintenant tre un tableau. Cela


donne plus de contrle et de flexibilit sur le premier lien crumb.
HtmlHelper::docType() est par dfaut HTML5.
HtmlHelper::image() a maintenant une option fullBase.
HtmlHelper::media() a t ajoute. Vous pouvez utiliser cette mthode pour crer des lments
audio/vido HTML5.
Le support du syntaxe de plugin a t ajout pour HtmlHelper::script(),
HtmlHelper::css(), HtmlHelper::image(). Vous pouvez maintenant faciliter les liens
vers les assets des plugins en utilisant Plugin.asset.
HtmlHelper::getCrumbList() a eu le paramtre $startText ajout.
Vue
View::$output est dprci.
$content_for_layout est dprci. Utilisez $this->fetch(content); la place.
$scripts_for_layout est dprci. Utilisez ce qui suit la place :
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');

$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.

2.1 Guide de Migration

1061

CakePHP Cookbook Documentation, Version 2.x

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

Deux nouveaux callbacks ont t ajouts aux Helpers. Helper::beforeRenderFile() et


Helper::afterRenderFile(). Ces deux nouveaux callbacks sont dclenchs avant/aprs que chaque
fragment de vue soit rendu. Cela inclut les lments, layouts et vues.
CacheHelper

Les tags <!--nocache--> fonctionnent maintenant correctement lintrieur des lments.


FormHelper

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

PaginatorHelper::numbers() a maintenant une option currentClass.


Testing
Les Web test runner affichent maintenant le numro de version de PHPUnit.
Les Web test runner configurent par dfaut laffichage des test des app.
Les Fixtures peuvent tre cres pour diffrentes sources de donnes autre que $test.

1062

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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.

Nouvelles caractristiques dans CakePHP 2.1


Models
Model : :saveAll(), Model : :saveAssociated(), Model : :validateAssociated()

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.

2.1 Guide de Migration

1063

CakePHP Cookbook Documentation, Version 2.x

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(); ?>

Le Block capturant aussi le support dimbrication :


<?php $this->start('my_block'); ?>
<h1>Hello Block!</h1>
<p>This is a block of content</p>
<?php $this->start('second_block'); ?>
<p>Page title: <?php echo $title_for_layout; ?></p>
<?php $this->end(); ?>
<?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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

JsonView

Une nouvelle classe qui facilite la sortie de contenu JSON.


Prcdemment, il tait ncessaire de crer un layout JSON (APP/View/Layouts/json/default.ctp)
et une vue correspondante pour chaque action qui sortirait le JSON. Ceci nest plus requis avec JsonView.
JsonView est utilise comme tout autre classe de vue, en la dfinissant sur le controller. Exemple :
App::uses('Controller', 'Controller');
class AppController extends Controller {
public $viewClass = 'Json';
}

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

CakePHP Cookbook Documentation, Version 2.x

<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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

// 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.

2.0 Guide de Migration


Guide de Migration 2.0
Cette page rsume les changements par rapport CakePHP 1.3 qui aidera pour les projets de migration
vers la version 2.0, ainsi quune rfrence pour se mettre jour sur les changements faits dans le coeur
depuis la branche CakePHP 1.3. Assurez vous de lire les autres pages de ce guide pour toutes les nouvelles
fonctionnalits et les changements de lAPI.
Astuce : Faites bien un checkout Mise jour shell inclu dans le coeur de la 2.0 pour vous aider migrer du
code de la 1.3 la 2.0.

Support des Versions de PHP


CakePHP 2.x supporte la Version de PHP 5.2.8 et suprieur. Le support de PHP4 a t supprim. Pour
les dveloppeurs qui travaillent avec un environnement de production PHP4, les versions de CakePHP 1.x
continuent le support de PHP4 pour la dure de vie de leur dveloppement.
Le passage PHP5 siginifie que toutes les mthodes et proprits ont t mises jour avec les mots-cls
correspondants. Si votre code tente daccder des mthodes prives ou protges avec une tendue public,
vous rencontrerez des erreurs.
Bien que cela ne constitue pas un changement normer du framework, cela signifie quun accs aux mthodes et variables la visibilit serre nest maintenant plus possible.
2.0 Guide de Migration

1067

CakePHP Cookbook Documentation, Version 2.x

Le nommage des Fichiers et Dossiers


Dans CakePHP 2.0, nous avons repens la faon de structurer nos fichiers et dossiers. Etant donn que
PHP 5.3 supporte les espaces de nom (namespaces), nous avons dcid de prparer notre base de code pour
ladoption dans un futur proche de cette version de PHP, donc nous avons adopt https ://github.com/phpfig/fig-standards/blob/master/accepted/PSR-0.md. Tout dabord, nous avons regard la structure interne de
CakePHP 1.3 et avons ralis quaprs toutes ces annes, il ny avait ni organisation claire des fichiers, ni une
structure de dossiers vraiment logique o chaque fichier se trouve o il devrait. Avec ce changement, nous
serions autoriss exprimenter un peu le chargement (presque) automatique des classes pour augmenter
les performances globales du framework.
Le plus grand obstacle pour russir cela, tait de maintenir une sorte de compatiblit rtro-active
avec la faon dont les classes sont charges en ce moment, et nous ne voulions dfinitivement
pas devenir un framework avec des normes prfixes de classe, des noms de classe du type
Mon_Enorme_Classe_Dans_Le_Progiciel. Nous avons dcid dadopter une stratgie de garder
des noms de classe simples, tout en offrant une faon trs intuitive de dclaration des emplacements de
classe et des chemins de migration clairs pour la future version PHP 5.3 de CakePHP. Tout dabord, mettons
en vidence les principaux changements dans la standardisation du nommage des fichiers que nous avons
adopte :
Noms des Fichiers

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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');

Cela remplace toutes les mthodes de traduction raccourcies :


__()
__n()
__d()
__dn()
__dc()
__dcn()
__c()

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

2.0 Guide de Migration

1069

CakePHP Cookbook Documentation, Version 2.x

Elle est valide pour toutes les mthodes raccourcies de traduction.


Plus dinformations sur les spcificits de la fonction : sprintf 6 .
Emplacement de la Classe et constantes changes
Les constantes APP et CORE_PATH ont des valeur cohrentes entre le web et les environnement de la
console. Dans les prcedentes versions de CakePHP, ces valeurs changeaient selon lenvironnement.
Basics.php

getMicrotime() a t retire. Utilisez la fonction native microtime(true) la place.


e() a t retire. Utilisez echo.
r() a t retire. Utilisez str_replace.
a() a t retire. Utilisez array()
aa() a t retire. Utilisez array()
up() a t retire. Utilisez strtoupper()
low() a t retire. Utilisez strtolower()
params() a t retire. Il ntait utilis nul part dans CakePHP
ife() a t retire. Utilisez un oprateur ternaire.
uses() a t retire. Utilisez App::import() la place.
La compatibilit des fonctions de PHP4 a t retire.
La constante PHP5 a t retire.
La variable Globale appele $TIME_START a t retire. Utilisez la constante TIME_START ou
$_SERVER[REQUEST_TIME] la place.

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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) { }

2.0 Guide de Migration

1071

CakePHP Cookbook Documentation, Version 2.x

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));

Changement dans la dsactivation des components

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

Les implmentations AclComponent sont maintenant requises pour implmenter AclInterface.


AclComponent::adapter() a t ajout pour permettre lxecution de la modification de lutilisation de limplmentation du component ACL.
AclComponent::grant() a t dprci, il sera supprim dans une version future. Utilisez
AclComponent::allow() la place.
AclComponent::revoke() a t dprci, il sera supprim dans une version future. Utilisez
AclComponent : :deny() la place.
RequestHandlerComponent

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

SessionComponent a perdu les mthodes suivantes.


activate()
active()
__start()
Retrait de cakeError
La mthode cakeError() a t retire. Il est recommand que vous changiez toutes les utilisations de
cakeError pour utiliser les exceptions. cakeError a t retire car elle simulait les exceptions. Plutt
que la simulation, de relles exceptions sont utilises dans CakePHP 2.0.
Gestion des Erreurs
Limplmentation de la gestion des erreurs a chang de faon spectaculaire dans 2.0. Les exceptions ont t
introduites partout dans le framework, et la gestion des erreurs a t mise jour pour offrir plus de contrle
et de flexibilit. Vous pouvez en lire plus dans les sections Exceptions et Gestion des Erreurs.
2.0 Guide de Migration

1073

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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')

2.0 Guide de Migration

1075

CakePHP Cookbook Documentation, Version 2.x

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');

Au contraire de la faon dont fonctionnait App::import(), la nouvelle classe de chargement ne va pas


localiser les classes de faon rcursive. Cela entrane un gain de performance impressionnant mme en
mode dveloppement, au prix de certaines fonctionnalits rarement utilises qui ont toujours provoques
des effets secondaires. Pour tre encore plus clair, la classe de chargement va seulement attraper la classe
dans le package exact dans lequel vous lui avez dit de la trouver.
App : :build() et les chemins du coeur App::build() ne va plus fusionner les chemins de app avec
les chemins du coeur.
Exemples :
App::build(array('controllers' => array('/chemin/complet/vers/controllers')))
//devient
App::build(array('Controller' => array('/chemin/complet/vers/controllers')))
App::build(array('helpers' => array('/chemin/complet/vers/controllers')))
//devient
App::build(array('View/Helper' => array('/chemin/complet/vers/Vues/Helpers')))

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

Vous ne pouvez plus modifier les paramtres de configuration avec Router::setRequestInfo().


Vous devriez utiliser Router::connectNamed() pour configurer la faon dont les paramtres nomms sont grs.
Le Router na plus de mthode getInstance(). Cest une classe statique, appelle ses mthodes et
proprits de faon statique.
Router::getNamedExpressions() est deprci. Utilisez les nouvelles constantes du routeur. Router::ACTION, Router::YEAR, Router::MONTH, Router::DAY, Router::ID, et
Router::UUID la place.
Router::defaults() a t retir. Supprimer linclusion de fichier des routes du coeur de
votre fichier routes.php de vos applications pour dsactiver le routing par dfaut. Inversement, si
vous voulez le routing par dfaut, vous devrez ajouter une inclusion dans votre fichier de routes
Cake/Config/routes.php.
Quand vous utilisez Router : :parseExtensions() le paramtre dextension nest
plus sous $this->params[url][ext]. A la place, il est disponible avec
$this->request->params[ext].
Les routes des plugins par dfaut ont chang. Les routes courtes de Plugin ne sont plus construites que
dans les actions index. Prcdemment /users et /users/add mappaient le UsersController dans le
plugin Users. Dans 2.0, seule laction index est donn par une route courte. Si vous souhaitez continuer
utiliser les routes courtes, vous pouvez ajouter une route comme :
Router::connect('/users/:action', array('controller' => 'users', 'plugin' => 'users'));

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.

2.0 Guide de Migration

1077

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Inflector

LInflecteur na plus de mthode getInstance().


Inflector::slug() ne supporte plus largument $map. Utilisez Inflector::rules() pour
dfinir les rgles de translitration.
CakeSession

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

Afin de prendre en considration le fait que View a t retir de la ClassRegistry, la signature du


Helper : :__construct() a t change. Vous devez mettre jour toutes les sous-classes pour utiliser ce qui
suit :
public function __construct(View $View, $settings = array())

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

2.0 Guide de Migration

1079

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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 paramtre $selected retir Le paramtre $selected a t retir de plusieurs mthodes dans


FormHelper. Toutes les mthodes supportent maintenant une cl $attributes[value] qui doit
tre utilise la place de $selected. Ce changement simplifie les mthodes FormHelper, rduit le
nombre darguments, et rduit les rptitions que $selected crait. Les mthodes effectives sont :
FormHelper : :select()
FormHelper : :dateTime()
FormHelper : :year()
FormHelper : :month()
FormHelper : :day()
FormHelper : :hour()
FormHelper : :minute()
FormHelper : :meridian()
Les URLs par dfaut dans les formulaires sont laction courante Lurl par dfaut pour tous les
formulaires est maintenant lurl courante, incluant les paramtres passs, nomms et querystring. Vous
pouvez craser ce rglage par dfaut en fournissant $options[url] dans le second paramtre de
$this->Form->create().
FormHelper : :hidden() Les champs cachs nenlvent plus la classe attribut. Cela signifie que si il y a
des erreurs de validation sur des champs cachs, le nom de classe error-field sera appliqu.
CacheHelper

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

La classe Helper a 3 attributs protgs :

2.0 Guide de Migration

1081

CakePHP Cookbook Documentation, Version 2.x

Helper::_minimizedAttributes : tableau avec des attributs minimums (ex :


array(checked, selected, ...)) ;
Helper::_attributeFormat : comment les attributs vont tre gnrs (ex : %s="%s") ;
Helper::_minimizedAttributeFormat : comment les attributs minimums vont tre gnrs :
(ie %s="%s")
Par dfaut, les valeurs utilises dans CakePHP 1.3 nont pas t changes. Mais vous pouvez maintenant
utiliser les attributs bolens de HTML, comme <input type="checkbox" checked />. Pour cela,
changez juste $_minimizedAttributeFormat dans votre AppHelper en %s.
Pour utiliser avec les helpers Html/Form et les autres, vous pouvez crire :
$this->Form->checkbox('field', array('checked' => true, 'value' => 'une_valeur'));

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'));

Notez que checked a une cl numrique.


Controller (Contrleur)
Le constructeur du Controller prend maintenant deux paramtres. Les objets CakeRequest et CakeResponse. Ces objets sont utiliss pour remplir plusieurs proprits dprecies et seront mis dans $request
et $response lintrieur du controller.
Controller::$webroot est deprcie, utilisez la proprit webroot de lobjet request.
Controller::$base est deprcie, utilisez la proprit base de lobjet request.
Controller::$here est deprcie, utilisez la proprit here de lobjet request.
Controller::$data est deprcie, utilisez la proprit data de lobjet request.
Controller::$params est deprcie, utilisez $this->request la place.
Controller::$Component a t dplace vers Controller::$Components. Voir la documentation Collections pour plus dinformations.
Controller::$view a t renomme en Controller::$viewClass. Controller::$view
est maintenant utilise pour changer le fichier vue qui doit tre rendu.
Controller::render() retourne maintenant un objet CakeResponse.
Les proprits deprcies dans Controller seront accessibles travers la mthode __get(). Cette mthode
va tre retire dans les versions futures, donc il est recommand que vous mettiez votre application jour.
Le Controller dfinit maintenant une limite Max (maxLimit) pour la pagination. Cette limite maximale est
mise 100, mais peut tre crase dans les options de $paginate.
Pagination

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

View::$webroot est deprci, utilisez la proprit webroot de lobjet request.


View::$base est deprci, utilisez la proprit base de lobjet request.
View::$here est deprci, utilisez la proprit here de lobjet request.
View::$data est deprci, utilisez la proprit data de lobjet request.
View::$params est deprci, utilisez $this->request la place.
View::$loaded a t retir. Utilisez HelperCollection pour accder aux helpers chargs.
View::$model a t retir. Ce behavior est maintenant dans Helper
View::$modelId a t retir. Ce behavior est maintenant dans Helper
View::$association a t retir. Ce behavior est maintenant dans Helper
View::$fieldSuffix a t retir. Ce behavior est maintenant dans Helper
View::entity() a t retir. Ce behavior est maintenant dans Helper
View::_loadHelpers() a t retir, utilisez View::loadHelpers() la place.
La faon dont View::element() utilise le cache a chang, voir en-dessous pour plus dinformations.
Les callbacks de Vue ont t transfrs, voir en-dessous pour plus dinformations.
LAPI pour View::element() a chang. Lire ici pour plus dinformations.

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

View::_triggerHelpers() Utilisez $this->Helpers->trigger() la place.


View::_loadHelpers() Utilisez $this->loadHelpers() la place. Les Helpers chargent
maintenant facilement leurs propres helpers.
Mthodes ajoutes

View::loadHelper($name, $settings = array()); Charge un unique helper.


View::loadHelpers() charge tous les helpers indiqus dans View::$helpers.

2.0 Guide de Migration

1083

CakePHP Cookbook Documentation, Version 2.x

View->Helpers

Par dfaut, les objets Vue contiennent un HelperCollection dans $this->Helpers.


Thmes

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

beforeLayout utilis pour se dclencher aprs scripts_for_layout et content_for_layout a t prpar. Dans


2.0, beforeLayout est tir avant que toute variable spciale soit prpare, vous autorisant les manipuler
avant quelles soient passes au layout. La mme chose a t faite pour beforeRender. Il est maintenant
tir bien avant que toute variable soit manipule. En plus de ces changements, les callbacks des helpers
reoivent toujours le nom du fichier qui est sur le point dtre rendu. Ceci, combin avec le fait que les
helpers soient capables daccder la vue travers $this->_View et la vue courante du contenu travers
$this->_View->output vous donne plus de puissance quavant.
La signature du callback Helper change

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

MediaView::render() force maintenant le tlchargement de types de fichiers inconnus la place de


juste retourner false. Si vous le voulez, vous pouvez fournir un fichier de tlchargement alternatif, vous
spcifiez le nom complet incluant lextension en utilisant la cl name dans le paramtre tableau pass la
fonction.
PHPUnit plutt que SimpleTest
Tous les cas de test du coeur et les infrastructures supportant ont t ports pour utiliser PHPUnit 3.7.
Bien sur, vous pouvez continuer utiliser SimpleTest dans votre application en remplaant les fichiers lis.
Pas plus de support ne sera donn pour SimpleTest et il est recommand que vous migriez vers PHPUnit
aussi. Pour plus dinformations sur la faon de migrer vos tests, regardez les allusions sur la migration vers
PHPUnit.
Plus de tests groups

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.

2.0 Guide de Migration

1085

CakePHP Cookbook Documentation, Version 2.x

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';

Ou dclare juste la proprit dans la classe model :


class Post {
public $nonexistentProperty = array();
}

Chacune des ses approches rsoudra les erreurs de notice.


La notation de find() dans CakePHP 1.2 nest plus supporte. Les Finds devront utiliser la notation
$model->find(type, array(PARAMS)) comme dans CakePHP 1.3.
Model::$_findMethods est maintenant Model::$findMethods. Cette proprit est maintenant
publique et peut tre modifie par les behaviors.
Objets Database (Base de Donnes)

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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 :

$db->fetchAll('SELECT * from users where nom_utilisateur = ? AND mot_de_passe = ?', array


$db->fetchAll('SELECT * from users where nom_utilisateur = :nom_utilisateur AND mot_de_pa

Le driver PDO va automatiquement echapper ces valeurs pour vous.


Les statistiques de Base de donnes sont collectes seulement si la proprit fullDebug de la BDD
correspondante est mise true.
Nouvelle mthode DboSource : :getConnection() va retourner lobjet PDO dans le cas o vous auriez
besoin de parler directement au driver.
Le traitement des valeurs bolennes a chang un peu pour pouvoir faciliter le croisement de base de
donnes, vous devrez peut-tre changer vos cas de test.
Le support de PostgreSQL a t immensment amlior, il cre maintenant correctement les schmas,
vide les tables, et il est plus facile dcrire des tests en lutilisant.
DboSource : :insertMulti() nacceptera plus les chanes sql, passez juste un tableau de champs et un
tableau imbriqu de valeurs pour les insrer tous en une fois.
TranslateBehavior a t reconstruit pour utiliser les vituaFields des models, cela rend limplmentation
plus portable.
Tous les cas de test avec les choses lies de MySQL ont t dplacs vers le cas de test du driver correspondant. Cela a laiss le fichier DboSourceTest un peu maigre.
Support de limbrication des transactions. Maintenant il est possible de dmarrer une transaction plusieurs
fois. Il ne peut tre engag si la mthode de validation est appel le mme nombre de fois.
Le support SQLite a t grandement amlior. La diffrence majeure avec cake 1.3 est quil ne supportera
que SQLite 3.x. Cest une bonne alternative pour le dveloppement des apps, et rapidement en lanant les
cas de test.
Les valeurs des colonnes bolennes vont tre lances automatiquement vers le type boolen natif de php,
donc assurez vous de mettre jour vos cas de test et code si vous attendiez une valeur retourne de
type chane de caractre ou un entier : Si vous aviez une colonne published dans le pass en utilisant
2.0 Guide de Migration

1087

CakePHP Cookbook Documentation, Version 2.x

MySQL, toutes les valeurs retournes dun find auraient t numriques dans le pass, maintenant elles
sont strictement des valeurs bolennes.
Behaviors
BehaviorCollection

BehaviorCollection ne met plus en minuscule strtolower() les mappedMethods. Les


mappedMethods des Behaviors sont maintenant sensible la casse.
AclBehavior et TreeBehavior

Ne supporte plus les chanes de caractre pour la configuration. Exemple :


public $actsAs = array(
'Acl' => 'Controlled',
'Tree' => 'nested'
);

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Plugin App Controller et Plugin App Model

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

ShellDispatcher na plus de fichiers de gestion stdout, stdin, stderr.


ShellDispatcher::$shell a t retire.
ShellDispatcher::$shellClass a t retire.
ShellDispatcher::$shellName a t retire.
ShellDispatcher::$shellCommand a t retire.

2.0 Guide de Migration

1089

CakePHP Cookbook Documentation, Version 2.x

ShellDispatcher::$shellPaths a t retire, utilisez App::path(shells); la place.


ShellDispatcher nutilise plus help comme mthode magique qui a un statut spcial. A la place,
utilisez les options --help/-h, et un parseur doption.
Changements Rtro-incompatibles du Shell

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',
);

Nouvelles caractristiques dans CakePHP 2.0


Model
Le processus de construction du modle a t alleg. Les associations des Modles sont maintenant en lazy
loaded, les applications avec beaucoup de modles et dassociations vont voir une grande rduction de temps
dans le processus de bootstrap.
1090

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

getCrumbList() Cr un fil dariane de liens entours dlments <li>.


loadConfig() a t dplac de Helper vers la classe HtmlHelper. Cette mthode utilise maintenant les nouvelles classes de lecture (voir 2.0 Configure) pour charger votre fichier de config. En
option vous pouvez passer le chemin en deuxime paramtre (app/Config par dfaut). Pour simplifier,
vous pouvez dfinir le fichier de configuration (et le lecteur) dans Controller::$helpers (exemple
ci-dessous) pour charger le constructeur du helper. Dans le fichier de configuration, vous pouvez dfinir
les cls ci-dessous :

tags Doit tre un tableau avec une valeur cl ;


minimizedAttributes Doit tre une liste ;
docTypes Doit tre un tableau avec une valeur cl ;
attributeFormat Doit tre une chane de caractre ;
minimizedAttributeFormat Doit tre une chane de caractre.

Exemple sur la faon de dfinir le fichier de configuration sur les contrleurs :

public $helpers = array(


'Html' => array(
'configFile' => array('config_file', 'php') // Option une: un tableau avec le nom d
'configFile' => 'config_file' // Option deux: une chane de caractre avec le nom d
)
);

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

CakePHP Cookbook Documentation, Version 2.x

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

CakeSession et le SessionComponent ont connu un nombre de changements, regardez la section


session pour plus dinformations.
Router

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

echo $this->Html->link(
'Autre domaine',
array('subdomain' => 'test', 'controller' => 'posts', 'action' => 'add')
);

Ce qui est ci-dessus crera un lien avec lurl http ://test.localhost/posts/add.


Xml

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
)
###########################

Ceci devrait amliorer la lecture de debug() dans les lignes de commande.

2.0 Guide de Migration

1093

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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'
)
);

2.0 Guide de Migration

1095

CakePHP Cookbook Documentation, Version 2.x

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.

PHPUnit Migration Hints


Migrer vos cas de test vers PHPUnit 3.7 8 va, esprons-le tre une transition sans douleur. Cepeandant, il y
a quelques diffrences entre les cas de test sous PHPUnit et SimpleTest 9 .
Diffrences avec SimpleTest
Il y a un certain nombre de diffrences entre SimpleTest and PHPUnit. Ce qui suit est une tentative de lister
les diffrences les plus frquemment rencontres.
startCase() et endCase()

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

2.0 Guide de Migration

1097

CakePHP Cookbook Documentation, Version 2.x

Remplacez expectOnce() avec params


expectOnce\(([^,]+), array\((.+)\)\);
expects(\$this->once())->method($1)->with($2);

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

DS . 'View' . DS . 'Helper' . DS;


. 'JsHelperTest.php');
. 'JqueryEngineHelperTest.php');
. 'MootoolsEngineHelperTest.php');
. 'PrototypeEngineHelperTest.php');

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

}
}

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.

Migration de la version 1.2 vers la 1.3


Migrer de CakePHP 1.2 vers 1.3
Ce guide rsume plusieurs des changements ncessaires quand on migre du coeur de CakePHP 1.2 vers 1.3.
Chaque section contient des informations pertinentes pour les modifications fates aux mthodes existantes
ainsi que toute mthode qui a t retire/renomme.
Remplacements du fichier App (important)
webroot/index.php : Doit tre remplac cause des changements dans le processus de bootstrapping.
config/core.php : Des configurations additionnelles ont t mise en place qui sont requises pour PHP 5.3.
webroot/test.php : Remplacez si vous voulez lancer des tests unitiaires.
Constantes retires
Les constantes suivantes ont t retires de CakePHP. Si votre application dpend deux, vous devez les
dfinir dans app/config/bootstrap.php
CIPHER_SEED - Cela a t remplac par la variable Security.cipherSeed de la classe de configuration qui doit tre change dans app/config/core.php
PEAR
INFLECTIONS
VALID_NOT_EMPTY
VALID_EMAIL
VALID_NUMBER
VALID_YEAR
Configuration et bootstrapping de lapplication
Chemins de bootstrapping en plus.
Dans votre fichier app/config/bootstrap.php il se peut que vous ayez des variables telles que
$pluginPaths ou $controllerPaths. Il y a une nouvelle faon dajouter ces chemins. Comme dans
la 1.3 RC1, les variables $pluginPaths ne fonctionneront plus. Vous devez utiliser App::build()
pour modifier les chemins.

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

Migration de la version 1.2 vers la 1.3

1099

CakePHP Cookbook Documentation, Version 2.x

'datasources' => array('/chemin/complet/vers/sources_de_donnes/', '/prochain/chemin/co


'behaviors' => array('/chemin/complet/vers/behaviors/', '/prochain/chemin/complet/vers/
'components' => array('/chemin/complet/vers/components/', '/prochain/chemin/complet/ver
'helpers' => array('/chemin/complet/vers/helpers/', '/prochain/chemin/complet/vers/help
'vendors' => array('/chemin/complet/vers/vendors/', '/prochain/chemin/complet/vers/vend
'shells' => array('/chemin/complet/vers/shells/', '/prochain/chemin/complet/vers/shells
'locales' => array('/chemin/complet/vers/locale/', '/prochain/chemin/complet/vers/local
'libs' => array('/chemin/complet/vers/libs/', '/prochain/chemin/complet/vers/libs/')
));

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Les classes suivantes ne vont plus tendre Object :


Router
Set
Inflector
Cache
CacheEngine
Si vous utilisiez les mthodes de Object partir de ces classes, vous devrez ne plus utiliser ces mthodes.
Controllers & Components
Controller
Controller::set() ne change plus les variables partir de $var_name vers $varName. Les
variables apparaissent toujours dans la vue exactement comme vous laviez fixe.
Controller::set(title, $var) ne fixe plus $title_for_layout quand il rend le layout. $title_for_layout est toujours rempli par dfaut. Mais si vous voulez le modifier, utilisez
$this->set(title_for_layout, $var).
Controller::$pageTitle a t retir. Utilisez $this->set(title_for_layout,
$var); la place.
Controller a deux nouvelles mthodes startupProcess et shutdownProcess. Ces mthodes sont
responsables de la gestion du startup du controller et des processus de shutdown.
Component
Component::triggerCallback a t ajout. Cest un hook gnrique dans le processus de
callback du component. Il supplante Component::startup(), Component::shutdown() et
Component::beforeRender() comme manire prfrentielle pour dclencher les callbacks.
CookieComponent
del est dprecie, utilisez delete
AclComponent + DbAcl
La vrification de la rfrence du Noeud faite avec les chemins sont maintenant moins gourmands et ne
consommeront plus les noeuds intermdiaires quand on fait des recherches. Dans le pass, tant donn la
structure :
ROOT/
Users/
Users/
edit

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

Migration de la version 1.2 vers la 1.3

1101

CakePHP Cookbook Documentation, Version 2.x

2. Renommer la variable $content_for_layout en $message


3. Assurez vous davoir echo $session->flash(); dans votre layout
SessionComponent et SessionHelper ne sont pas chargs automatiquement. Les deux helpers
SessionComponent et SessionHelper ne sont plus inclus automatiquement sans que vous le
demandiez. SessionHelper et SessionComponent se comportent maintenant comme chaque autre component et doivent tre dclars comme tout autre helper/component. Vous devriez mettre jour
AppController::$components et AppController::$helpers pour inclure ces classes pour
conserver les behaviors existants.
var $components = array('Session', 'Auth', ...);
var $helpers = array('Session', 'Html', 'Form' ...);

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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 :

Router::connect('/([0-9]+)-p-(.*)/', array('controller' => 'products', 'action' => 'show'))

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

Model Databases and Datasources


Model
Model::del() and Model::remove() have been removed in favor of Model::delete(),
which is now the canonical delete method.
Model::findAll, findCount, findNeighbours, removed.
Dynamic calling of setTablePrefix() has been removed. tableprefix should be with the $tablePrefix
property, and any other custom construction behavior should be done in an overridden
Model::__construct().
DboSource::query() now throws warnings for un-handled model methods, instead of trying to run them as queries. This means, people starting transactions improperly via the
$this->Model->begin() syntax will need to update their code so that it accesses the models DataSource object directly.
Missing validation methods will now trigger errors in development mode.
Missing behaviors will now trigger a cakeError.
Model::find(first) will no longer use the id property for default conditions if no conditions are
supplied and id is not empty. Instead no conditions will be used
For Model : :saveAll() the default value for option validate is now first instead of true
Datasources
DataSource : :exists() has been refactored to be more consistent with non-database backed datasources.
Previously, if you set var $useTable = false; var $useDbConfig = custom;, it was
impossible for Model::exists() to return anything but false. This prevented custom datasources
from using create() or update() correctly without some ugly hacks. If you have custom datasources
that implement create(), update(), and read() (since Model::exists() will make a call to
Model::find(count), which is passed to DataSource::read()), make sure to re-run your
unit tests on 1.3.
Databases
Most database configurations no longer support the connect key (which has been deprecated since pre1.2). Instead, set persistent => true or false to determine whether or not a persistent database
connection should be used
SQL log dumping
A commonly asked question is how can one disable or remove the SQL log dump at the bottom of the page ?.
In previous versions the HTML SQL log generation was buried inside DboSource. For 1.3 there is a new
core element called sql_dump. DboSource no longer automatically outputs SQL logs. If you want to
output SQL logs in 1.3, do the following :
<?php echo $this->element('sql_dump'); ?>

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

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

Migration de la version 1.2 vers la 1.3

1107

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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.

Nouvelles caractristiques dans CakePHP 1.3


CakePHP 1.3 introduit un nombre de nouvelles fonctionnalits. Ce guide tente de rsumer ces changements
et de pointer vers la documentation nouvelle quand cest ncessaire.
Components
SecurityComponent
Les diffrentes mthodes requireXX comme requireGet et requirePost acceptent maintenant un
tableau unique en argument ainsi quune collection de noms en chanes de caractre.
$this->Security->requirePost(array('edit', 'update'));

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')
)
);

Ceci devrait rduire le dsordre dans vos mthodes beforeFilter() de Controller.


EmailComponent
Vous pouvez maintenant rcuprer les contenus rendus des messages Email envoys, en lisant
$this->Email->htmlMessage et $this->Email->textMessage. Ces proprits contiendront le contenu de lemail rendu correspondant son nom.
Many of EmailComponents private methods have been made protected for easier extension.
EmailComponent : :$to peut maintenant tre un tableau. Allowing easier setting of multiple recipients,
and consistency with other properties.

Migration de la version 1.2 vers la 1.3

1109

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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/

Migration de la version 1.2 vers la 1.3

1111

CakePHP Cookbook Documentation, Version 2.x

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

Using tableParameters in schema files


You use tableParameters just as you would any other key in a schema file. Much like 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'),

1112

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

),
'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

Migration de la version 1.2 vers la 1.3

1113

CakePHP Cookbook Documentation, Version 2.x

Router and Dispatcher


Router
Generating URLs with new style prefixes works exactly the same as admin routing did in
1.2. They use the same syntax and persist/behave in the same way. Assuming you have
Configure::write(Routing.prefixes, array(admin, member)); in your
core.php you will be able to do the following from a non-prefixed URL :

$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');

Would return the sum of all Movie ratings in $data.


L10N
All languages in the catalog now have a direction key. This can be used to determine/define the text direction
of the locale being used.
14. http ://ca2.php.net/callback

1114

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

You can also import libs files from plugins


App::import('Lib', 'Geocoding.Geocode'); //imports app/plugins/geocoding/libs/geocode.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

Migration de la version 1.2 vers la 1.3

1115

CakePHP Cookbook Documentation, Version 2.x

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';
}

Would use scaffolding for member prefixed URLs.


Validation
After 1.2 was released, there were numerous requests to add additional localizations to the phone() and
postal() methods. Instead of trying to add every locale to Validation itself, which would result in large
bloated ugly methods, and still not afford the flexibility needed for all cases, an alternate path was taken. In
1.3, phone() and postal() will pass off any country prefix it does not know how to handle to another
class with the appropriate name. For example if you lived in the Netherlands you would create a class like
class NlValidation {
public function phone($check) {
...
}
public function postal($check) {
...
}
}

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

Chapitre 17. Annexes

CakePHP Cookbook Documentation, Version 2.x

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

Pointerait vers la valeur suivante :


array(
'Asset' => array(
'filtre' => array(
'css' => 'vous m avez eu'
)
)
)

Informations gnrales

1117

CakePHP Cookbook Documentation, Version 2.x

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 17. Annexes

CHAPITRE 18

Indices et tables

genindex

1119

CakePHP Cookbook Documentation, Version 2.x

1120

Chapitre 18. Indices et tables

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

CakePHP Cookbook Documentation, Version 2.x

append() (mthode File), 704


append() (mthode View), 98
appError, 893
APPLIBS (global constant), 348
application exceptions, 891
apply() (mthode Hash), 718
apply() (mthode Set), 752, 779
AppShell (class), 824
assign() (mthode View), 99
attributs HTML, 1117
AuthComponent (class), 544
authenticate (AuthComponent property), 558
authError (AuthComponent property), 558
authorize (AuthComponent property), 558
autoLink() (mthode TextHelper), 188, 486, 671
autoLinkEmails() (mthode TextHelper), 188, 486,
670
autoLinkUrls() (mthode TextHelper), 188, 486, 671
autoParagraph() (mthode TextHelper), 189, 486,
671

boolean() (mthode Validation), 276


buffer() (mthode JsHelper), 156, 454, 638
build() (mthode App), 352
build() (mthode Xml), 797
buildFromArray() (mthode ConsoleOptionParser),
821
button() (mthode FormHelper), 131, 430, 614

Cache (class), 688


CACHE (global constant), 348
cache() (mthode CakeResponse), 77
CacheEngine (class), 685
CacheHelper (class), 105, 405, 588
CAKE (global constant), 348
CAKE_CORE_INCLUDE_PATH (global constant),
348
CakeBaseException, 890
CakeEmail (class), 690
CakeException, 890
CakeLog (class), 739
B
CakeNumber (class), 741
CakeRequest (class), 68
BadRequestException, 888
CakeResponse (class), 76
base (CakeRequest property), 70
CakeRoute (class), 880
base (RssHelper property), 185, 483, 667
beforeDelete() (mthode ModelBehavior), 325, 400 CakeSession (class), 886
CakeText (class), 780
beforeFilter() (mthode Controller), 54
CakeTime (class), 785
beforeFind() (mthode ModelBehavior), 325, 399
camelize() (mthode Inflector), 729
beforeLayout() (mthode Helper), 204, 502
cc() (mthode Validation), 276
beforeRedirect() (mthode Component), 85, 404
cd() (mthode Folder), 699
beforeRender() (mthode Component), 85, 404
channel() (mthode RssHelper), 185, 483, 668
beforeRender() (mthode Controller), 54
charset() (mthode CakeResponse), 77
beforeRender() (mthode Helper), 204, 501
charset() (mthode HtmlHelper), 136, 435, 619
beforeRenderFile() (mthode Helper), 204, 501
check() (mthode Configure), 856
beforeSave() (mthode ModelBehavior), 325, 400
check() (mthode CookieComponent), 574
beforeScaffold() (mthode Controller), 58
beforeValidate() (mthode ModelBehavior), 325, check() (mthode Hash), 713
check() (mthode SessionComponent), 542
400
check() (mthode SessionHelper), 186, 484, 669
between() (mthode Validation), 275
bindTranslation() (mthode TranslateBehavior), 305, check() (mthode Set), 752
checkbox() (mthode FormHelper), 125, 425, 608
380, 517
checkNotModified() (mthode CakeResponse), 77
blackHole() (mthode SecurityComponent), 561
blackHoleCallback (SecurityComponent property), childCount() (mthode TreeBehavior), 314, 388, 526
children() (mthode TreeBehavior), 313, 388, 526
561
chmod() (mthode Folder), 699
blank() (mthode Validation), 276
cipher() (mthode Security), 749
Blocks (View property), 99
classicExtract() (mthode Set), 753
blocks() (mthode View), 98
classify() (mthode Inflector), 729
body() (mthode CakeResponse), 77
1122

Index

CakePHP Cookbook Documentation, Version 2.x

cleanInsert() (mthode CakeText), 781


cleanup() (mthode ModelBehavior), 325, 399
clear() (mthode Cache), 690
clear() (mthode CacheEngine), 685
clear() (mthode Shell), 824
clearGroup() (mthode Cache), 690
clearGroup() (mthode CacheEngine), 685
clientIp() (mthode CakeRequest), 69
close() (mthode File), 704
combine() (mthode Hash), 709
combine() (mthode Set), 757
comparison() (mthode Validation), 277
compile() (mthode CakeRoute), 880
Component (class), 85, 404
components (AuthComponent property), 558
components (Controller property), 63
compress() (mthode CakeResponse), 77
config() (global function), 347
config() (mthode Cache), 688
config() (mthode CakeLog), 739
config() (mthode Configure), 857
ConfigReaderInterface (interface), 860
configuration, 852
Configure (class), 855
configured() (mthode CakeLog), 739
configured() (mthode Configure), 857
ConfigureException, 861
confirm() (mthode JsHelper), 162, 460, 644
connect() (mthode Router), 878
connectNamed() (mthode Router), 879
ConsoleOptionParser (class), 816
constructAuthenticate() (mthode AuthComponent),
559
constructAuthorize() (mthode AuthComponent),
559
constructClasses() (mthode Controller), 58
consume() (mthode Configure), 856
consume() (mthode SessionComponent), 542
consume() (mthode SessionHelper), 186, 484, 669
ContainableBehavior (class), 293, 369, 506
contains() (mthode Hash), 713
contains() (mthode Set), 760
Controller (class), 54
convert() (mthode CakeTime), 786
convert() (mthode TimeHelper), 193, 491, 676
convertSlash() (global function), 347
convertSpecifiers() (mthode CakeTime), 786

Index

convertSpecifiers() (mthode TimeHelper), 193, 491,


676
CookieComponent (class), 572
copy() (mthode File), 704
copy() (mthode Folder), 699
core() (mthode App), 351
core.php, 852
CORE_PATH (global constant), 348
correctSlashFor() (mthode Folder), 700
countDim() (mthode Set), 761
counter() (mthode PaginatorHelper), 176, 475, 659
create() (mthode File), 704
create() (mthode Folder), 700
create() (mthode FormHelper), 109, 408, 591
createFile() (mthode Shell), 824
critical() (mthode CakeLog), 741
CSRF, 1118
csrfCheck (SecurityComponent property), 563
csrfExpires (SecurityComponent property), 563
csrfUseOnce (SecurityComponent property), 563
CSS (global constant), 348
css() (mthode HtmlHelper), 137, 436, 619
CSS_URL (global constant), 348
currency() (mthode CakeNumber), 742
currency() (mthode NumberHelper), 166, 464, 648
current() (mthode PaginatorHelper), 176, 474, 658
custom() (mthode Validation), 277

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

CakePHP Cookbook Documentation, Version 2.x

decrement() (mthode CacheEngine), 685


decrypt() (mthode Security), 750
defaultCurrency() (mthode CakeNumber), 743
defaultCurrency() (mthode NumberHelper), 167,
466, 649
defaultLevels() (mthode CakeLog), 740
defaultModel() (mthode PaginatorHelper), 180,
478, 663
defaultRouteClass() (mthode Router), 880
delete() (mthode Cache), 689
delete() (mthode CacheEngine), 685
delete() (mthode CakeSession), 887
delete() (mthode Configure), 856
delete() (mthode CookieComponent), 574
delete() (mthode File), 704
delete() (mthode Folder), 700
delete() (mthode HttpSocket), 723
delete() (mthode SessionComponent), 542
deny() (mthode AuthComponent), 559
description() (mthode ConsoleOptionParser), 817
destroy() (mthode CookieComponent), 574
destroy() (mthode SessionComponent), 542
diff() (mthode Hash), 719
diff() (mthode Set), 762
dimensions() (mthode Hash), 717
dirsize() (mthode Folder), 701
disable() (mthode CakeLog), 741
disableCache() (mthode CakeResponse), 77
disableCache() (mthode Controller), 58
dispatchShell() (mthode Shell), 824
div() (mthode HtmlHelper), 144, 443, 627
doc (role), 1001
docType() (mthode HtmlHelper), 139, 438, 622
document() (mthode RssHelper), 185, 483, 668
domain() (mthode CakeRequest), 68
domId() (mthode Helper), 204, 501
domReady() (mthode JsHelper), 161, 460, 644
download() (mthode CakeResponse), 77
drag() (mthode JsHelper), 158, 457, 641
drop() (mthode CakeLog), 739
drop() (mthode Configure), 857
drop() (mthode JsHelper), 159, 457, 641
DRY, 1118
DS (global constant), 348
dump() (mthode ConfigReaderInterface), 861
dump() (mthode Configure), 858
dump() (mthode Debugger), 898

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

CakePHP Cookbook Documentation, Version 2.x

fileExistsInPath() (global function), 347


fileSize() (mthode Validation), 280
filter() (mthode Hash), 714
filter() (mthode Set), 764
find() (mthode Folder), 701
findRecursive() (mthode Folder), 701
first() (mthode PaginatorHelper), 175, 474, 658
flash (AuthComponent property), 558
flash() (mthode Controller), 57
flash() (mthode SessionHelper), 187, 484, 669
FlashComponent (class), 540
FlashHelper (class), 107, 407, 590
flatten() (mthode Hash), 714
flatten() (mthode Set), 765
Folder (class), 698
Folder (File property), 704
Folder() (mthode File), 705
ForbiddenException, 888
format() (mthode CakeNumber), 746
format() (mthode CakeTime), 787
format() (mthode Hash), 712
format() (mthode NumberHelper), 170, 468, 652
format() (mthode Set), 765
format() (mthode TimeHelper), 194, 492, 677
formatDelta() (mthode CakeNumber), 747
formatDelta() (mthode NumberHelper), 171, 469,
653
formatTreeList() (mthode TreeBehavior), 315, 389,
527
FormHelper (class), 108, 408, 591
fromReadableSize() (mthode CakeNumber), 745
fromReadableSize() (mthode NumberHelper), 169,
468, 652
fromString() (mthode CakeTime), 788
fromString() (mthode TimeHelper), 195, 493, 678
FULL_BASE_URL (global constant), 348
fullBaseUrl() (mthode Router), 880

getAjaxVersion() (mthode RequestHandlerComponent), 568


getBuffer() (mthode JsHelper), 156, 454, 638
getCrumbList() (mthode HtmlHelper), 152, 451,
634
getCrumbs() (mthode HtmlHelper), 152, 450, 634
getInstance() (mthode Security), 750
getLevel() (mthode TreeBehavior), 320, 395, 533
getOptionParser() (mthode Shell), 825
getParentNode() (mthode TreeBehavior), 315, 390,
528
getPath() (mthode TreeBehavior), 315, 390, 528
getType() (mthode Debugger), 899
getVar() (mthode View), 98
getVars() (mthode View), 98
gmt() (mthode CakeTime), 788
gmt() (mthode TimeHelper), 195, 493, 678
group() (mthode File), 705
groupConfigs() (mthode Cache), 690

h() (global function), 347


handle (File property), 704
Hash (class), 707
hash() (mthode Security), 750
hasMethod() (mthode Shell), 825
hasNext() (mthode PaginatorHelper), 176, 474, 658
hasPage() (mthode PaginatorHelper), 176, 474, 659
hasPrev() (mthode PaginatorHelper), 176, 474, 658
hasTask() (mthode Shell), 825
header() (mthode CakeRequest), 69
header() (mthode CakeResponse), 76
Helper (class), 203, 501
helpers (Controller property), 63
helpers (RssHelper property), 185, 483, 667
here (CakeRequest property), 70
here (RssHelper property), 185, 483, 667
hidden() (mthode FormHelper), 124, 424, 607
G
highlight() (mthode CakeText), 782
highlight() (mthode TextHelper), 189, 487, 671
gc() (mthode Cache), 690
host() (mthode CakeRequest), 68
gc() (mthode CacheEngine), 686
HOUR (global constant), 349
generateAuthKey() (mthode Security), 750
generateTreeList() (mthode TreeBehavior), 314, hour() (mthode FormHelper), 133, 433, 616
hr() (mthode Shell), 825
389, 527
HtmlHelper (class), 136, 435, 618
get() (mthode Hash), 708
HttpSocket (class), 722
get() (mthode HttpSocket), 722
humanize() (mthode Inflector), 729
get() (mthode JsHelper), 158, 456, 640
get() (mthode View), 98

Index

1125

CakePHP Cookbook Documentation, Version 2.x

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

isThisMonth() (mthode TimeHelper), 199, 497, 682


isThisWeek() (mthode CakeTime), 792
isThisWeek() (mthode TimeHelper), 199, 497, 682
isThisYear() (mthode CakeTime), 792
isThisYear() (mthode TimeHelper), 199, 497, 682
isToday() (mthode CakeTime), 792
isToday() (mthode TimeHelper), 199, 497, 682
isTomorrow() (mthode CakeTime), 792
isTomorrow() (mthode TimeHelper), 199, 497, 682
isWap() (mthode RequestHandlerComponent), 568
isWindowsPath() (mthode Folder), 702
isXml() (mthode RequestHandlerComponent), 567
item() (mthode RssHelper), 185, 483, 668
items() (mthode RssHelper), 185, 483, 668

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

CakePHP Cookbook Documentation, Version 2.x

loginRedirect (AuthComponent property), 558


logout() (mthode AuthComponent), 559
logoutRedirect (AuthComponent property), 558
LOGS (global constant), 349
luhn() (mthode Validation), 281

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

modified() (mthode CakeResponse), 77


money() (mthode Validation), 282
MONTH (global constant), 350
month() (mthode FormHelper), 133, 432, 615
move() (mthode Folder), 702
moveDown() (mthode TreeBehavior), 316, 391,
528
moveUp() (mthode TreeBehavior), 316, 391, 529
multiple() (mthode Validation), 282

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

CakePHP Cookbook Documentation, Version 2.x

output (View property), 99


overwrite() (mthode Shell), 826
owner() (mthode File), 706

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

postal() (mthode Validation), 283


postButton() (mthode FormHelper), 131, 431, 614
postConditions() (mthode Controller), 59
postLink() (mthode FormHelper), 131, 431, 614
pr() (global function), 348
precision() (mthode CakeNumber), 744
precision() (mthode NumberHelper), 168, 467, 651
prefers() (mthode RequestHandlerComponent), 570
prefix routing, 869
prepare() (mthode File), 706
prepend() (mthode View), 99
prev() (mthode PaginatorHelper), 174, 472, 657
PrivateActionException, 889
promote() (mthode Router), 879
prompt() (mthode JsHelper), 162, 460, 644
pushDiff() (mthode Set), 774
put() (mthode HttpSocket), 723
pwd() (mthode File), 706
pwd() (mthode Folder), 703

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

CakePHP Cookbook Documentation, Version 2.x

referer() (mthode Controller), 58


remember() (mthode Cache), 690
remove() (mthode Hash), 709
remove() (mthode Set), 775
removeFromTree() (mthode TreeBehavior), 317,
392, 530
render() (mthode Controller), 55
renderAs() (mthode RequestHandlerComponent),
570
reorder() (mthode TreeBehavior), 318, 319, 392,
394, 530, 532
replaceText() (mthode File), 707
request (AuthComponent property), 558
request (View property), 99
request() (mthode HttpSocket), 723
request() (mthode JsHelper), 157, 456, 640
requestAction() (mthode Controller), 60
RequestHandlerComponent (class), 566
requireAuth() (mthode SecurityComponent), 562
requireDelete() (mthode SecurityComponent), 562
requireGet() (mthode SecurityComponent), 562
requirePost() (mthode SecurityComponent), 562
requirePut() (mthode SecurityComponent), 562
requireSecure() (mthode SecurityComponent), 562
reset() (mthode Inflector), 730
respondAs() (mthode RequestHandlerComponent),
570
response (AuthComponent property), 559
responseHeader() (mthode CakeBaseException),
890
responseType() (mthode RequestHandlerComponent), 570
restore() (mthode Configure), 859
reverse() (mthode Set), 775
RFC
RFC 2606, 1019
RFC 2616, 725, 1079
RFC 4122, 781
rijndael() (mthode Security), 749
ROOT (global constant), 349
Router (class), 878
routes.php, 863, 1118
RssHelper (class), 181, 479, 664
rules() (mthode Inflector), 730
runCommand() (mthode Shell), 826

S
safe() (mthode File), 706
Index

scaffoldError() (mthode Controller), 58


script() (mthode HtmlHelper), 145, 444, 627
scriptBlock() (mthode HtmlHelper), 146, 445, 629
scriptEnd() (mthode HtmlHelper), 147, 446, 629
scriptStart() (mthode HtmlHelper), 146, 445, 629
SECOND (global constant), 349
secure() (mthode FormHelper), 135, 434, 618
Security (class), 748
SecurityComponent (class), 560
select() (mthode FormHelper), 126, 426, 609
send() (mthode CakeResponse), 78
serializeForm() (mthode JsHelper), 163, 462, 646
serverOffset() (mthode CakeTime), 789
serverOffset() (mthode TimeHelper), 196, 494, 679
SessionComponent (class), 541
SessionHelper (class), 186, 484, 668
sessionKey (AuthComponent property), 559
Set (class), 751
set() (mthode Cache), 689
set() (mthode Controller), 54
set() (mthode JsHelper), 158, 457, 641
set() (mthode View), 97
setContent() (mthode RequestHandlerComponent),
569
setExtensions() (mthode Router), 880
setFlash() (mthode SessionComponent), 543
setHash() (mthode Security), 751
setup() (mthode ModelBehavior), 325, 399
sharable() (mthode CakeResponse), 77
Shell (class), 824
shortPath() (mthode Shell), 826
shutdown() (mthode App), 356
shutdown() (mthode AuthComponent), 560
shutdown() (mthode Component), 85, 404
singularize() (mthode Inflector), 729
size() (mthode File), 706
slashTerm() (mthode Folder), 703
slider() (mthode JsHelper), 159, 458, 642
slug() (mthode Inflector), 729
sort (Folder property), 699
sort() (mthode Hash), 718
sort() (mthode PaginatorHelper), 172, 470, 654
sort() (mthode Set), 777
sortable() (mthode JsHelper), 157, 455, 639
sortByKey() (global function), 348
sortDir() (mthode PaginatorHelper), 173, 471, 655
sortKey() (mthode PaginatorHelper), 173, 471, 655
ssn() (mthode Validation), 284
1129

CakePHP Cookbook Documentation, Version 2.x

toList() (mthode TextHelper), 192, 490, 674


toPercentage() (mthode CakeNumber), 745
toPercentage() (mthode NumberHelper), 169, 467,
651
toQuarter() (mthode CakeTime), 790
toQuarter() (mthode TimeHelper), 198, 495, 680
toReadableSize() (mthode CakeNumber), 745
toReadableSize() (mthode NumberHelper), 169,
468, 652
toRSS() (mthode CakeTime), 791
toRSS() (mthode TimeHelper), 198, 496, 681
toServer() (mthode CakeTime), 791
toServer() (mthode TimeHelper), 198, 496, 681
toUnix() (mthode CakeTime), 791
toUnix() (mthode TimeHelper), 198, 496, 681
trace() (mthode Debugger), 898
TranslateBehavior (class), 301, 377, 514
tree() (mthode Folder), 704
T
TreeBehavior (class), 308, 313, 382, 388, 520, 526
tableau de routing, 1117
truncate() (mthode CakeText), 783
tableCells() (mthode HtmlHelper), 149, 448, 631
truncate() (mthode TextHelper), 190, 487, 672
tableHeaders() (mthode HtmlHelper), 148, 447, 630 type() (mthode CakeResponse), 77
tableize() (mthode Inflector), 729
type() (mthode CookieComponent), 574
tag() (mthode HtmlHelper), 144, 443, 626
tagIsInvalid() (mthode FormHelper), 134, 433, 617 U
UnauthorizedException, 888
tail() (mthode CakeText), 783
unauthorizedRedirect (AuthComponent property),
tail() (mthode TextHelper), 191, 488, 673
558
tasks (Shell property), 824
underscore() (mthode Inflector), 729
TESTS (global constant), 349
unlockedFields (SecurityComponent property), 563
text() (mthode FormHelper), 124, 423, 607
unlockField() (mthode FormHelper), 135, 434, 617
textarea() (mthode FormHelper), 125, 424, 607
uploadError() (mthode Validation), 284
TextHelper (class), 188, 485, 670
url() (mthode Helper), 204, 501
themePath() (mthode App), 354
url() (mthode HtmlHelper), 150, 449, 632
time() (mthode RssHelper), 186, 483, 668
url() (mthode PaginatorHelper), 180, 478, 662
time() (mthode Validation), 284
url() (mthode Router), 879
TIME_START (global constant), 349
url() (mthode Validation), 284
timeAgoInWords() (mthode CakeTime), 789
timeAgoInWords() (mthode TimeHelper), 196, user() (mthode AuthComponent), 560
userDefined() (mthode Validation), 285
494, 679
uses (Controller property), 62
TimeHelper (class), 192, 490, 675
uses (Shell property), 824
timezone() (mthode CakeTime), 791
uses() (mthode App), 350
timezone() (mthode TimeHelper), 199, 496, 681
useTag() (mthode HtmlHelper), 151, 450, 633
TMP (global constant), 349
uuid() (mthode CakeText), 781
toArray() (mthode Xml), 798
uuid() (mthode Validation), 285
toAtom() (mthode CakeTime), 790
uuid() (mthode View), 98
toAtom() (mthode TimeHelper), 197, 495, 680
tokenize() (mthode CakeText), 781
toList() (mthode CakeText), 785

stackTrace() (global function), 347


start() (mthode View), 98
startIfEmpty() (mthode View), 99
startup() (mthode AuthComponent), 560
startup() (mthode Component), 85, 404
startup() (mthode Shell), 826
statusCode() (mthode CakeResponse), 77
store() (mthode Configure), 859
stream() (mthode CakeLog), 741
stripLinks() (mthode CakeText), 783
stripLinks() (mthode TextHelper), 190, 487, 672
stripslashes_deep() (global function), 348
style() (mthode HtmlHelper), 139, 438, 622
subdomains() (mthode CakeRequest), 68
submit() (mthode FormHelper), 130, 430, 613
submit() (mthode JsHelper), 162, 461, 644
syntaxe de plugin, 1117

1130

Index

CakePHP Cookbook Documentation, Version 2.x

YEAR (global constant), 350


valid() (mthode SessionHelper), 186, 484, 669
year() (mthode FormHelper), 132, 431, 615
validateAuthKey() (mthode Security), 751
validatePost (SecurityComponent property), 563
Validation (class), 275
ValidationisUnique() (mthode ModelValidation),
280
value() (mthode Helper), 204, 501
value() (mthode JsHelper), 164, 462, 646
variable() (mthode Inflector), 729
VENDORS (global constant), 349
verify() (mthode TreeBehavior), 319, 394, 532
version (RssHelper property), 185, 483, 667
version() (mthode Configure), 857
View (class), 97
viewClassMap() (mthode RequestHandlerComponent), 571

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

Vous aimerez peut-être aussi