Vous êtes sur la page 1sur 875

CakePHP Cookbook Documentation

Version 2.x

Cake Software Foundation

juil. 31, 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
35
38

Dbuter avec CakePHP


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

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)

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

47
47
48
48
50
50
58
60
83
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 . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

83
85
88
90
93
93
96

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

.
.
.
.
.

349
349
372
372
429
429

Plugins
Comment Installer des Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comment Utiliser des Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Comment Crer des Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

551
551
553
555

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

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

563
563
565
567
568
569
569
570
578
578
581

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.

603
603
617
635
642
649
652
655
680
685

11 Dploiement
691
Vrifier votre scurit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
ii

Dfinir le document root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691


Mise jour de core.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 691
Amliorer les performances de votre application . . . . . . . . . . . . . . . . . . . . . . . . . . . 692
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) . . . . . . . . . . . . . . . . . . . . . . . . . . .

693
693
696
698

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)

.
.
.
.
.

703
703
705
707
707
709

.
.
.
.
.

711
711
712
713
714
714

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

14 Application Simple contrle par Acl - partie 2


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

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

15 Tutoriels et exemples
715
Tutoriel dun Blog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715
Blog Tutoriel - Ajouter la logique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719
16 Contribuer
Documentation . . . . . . . . . . . . . .
Tickets . . . . . . . . . . . . . . . . . . .
Code . . . . . . . . . . . . . . . . . . . .
Normes de codes . . . . . . . . . . . . .
Guide de Compatibilit Rtroactive . . . .
Le processus de dveloppement CakePHP

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

733
733
742
742
745
756
759

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

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

761
761
763
765
768
774
780
786
793
804
837
855

18 Indices et tables

.
.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.
.

857
iii

Index

iv

859

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

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

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 sousrpertoires).
#
# 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
webroot/
RewriteRule
^$
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 5 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).
5. 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

Tutoriel dun Blog

CakePHP Cookbook Documentation, Version 2.x

root
index

/var/www/example.com/public/app/webroot/;
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 6 pour installer lURL Rewrite Module 2.0 7
6. http://www.microsoft.com/web/downloads/platform.aspx
7. http://www.iis.net/downloads/microsoft/url-rewrite

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

ou tlchargez le directement (32-bit 8 / 64-bit 9 ).


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">
<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"
)
8. http://www.microsoft.com/en-us/download/details.aspx?id=5747
9. http://www.microsoft.com/en-us/download/details.aspx?id=7435

Tutoriel dun Blog

CakePHP Cookbook Documentation, Version 2.x

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

10

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

Blog Tutoriel - Ajouter la logique

11

CakePHP Cookbook Documentation, Version 2.x

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

12

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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>
<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,
Blog Tutoriel - Ajouter la logique

13

CakePHP Cookbook Documentation, Version 2.x

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

14

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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'));
}
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
Blog Tutoriel - Ajouter la logique

15

CakePHP Cookbook Documentation, Version 2.x

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
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 10 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');
?>
10. http://api.cakephp.org

16

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

Blog Tutoriel - Ajouter la logique

17

CakePHP Cookbook Documentation, Version 2.x

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

18

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

echo
echo
echo
echo
echo
?>

$this->Form->create('Post');
$this->Form->input('title');
$this->Form->input('body', array('rows' => '3'));
$this->Form->input('id', array('type' => 'hidden'));
$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>
<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; ?>

Blog Tutoriel - Ajouter la logique

19

CakePHP Cookbook Documentation, Version 2.x

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

20

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

Blog Tutoriel - Ajouter la logique

21

CakePHP Cookbook Documentation, Version 2.x

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

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 11 .
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.
11. http://api.cakephp.org

22

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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.

Fig. 1.1 Diagramme reprsentant une requte CakePHP typique.


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.

Blog Tutoriel - Ajouter la logique

23

CakePHP Cookbook Documentation, Version 2.x

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

24

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

Blog Tutoriel - Ajouter la logique

25

CakePHP Cookbook Documentation, Version 2.x

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

26

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

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 :

Blog Tutoriel - Ajouter la logique

27

CakePHP Cookbook Documentation, Version 2.x

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

28

Chapitre 1. Pour Commencer

CakePHP Cookbook Documentation, Version 2.x

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

Blog Tutoriel - Ajouter la logique

29

CakePHP Cookbook Documentation, Version 2.x

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
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 12 . Github hberge CakePHP lui-mme
ainsi que plusieurs autres plugins pour CakePHP. Les versions de CakePHP sont disponibles sur Tlchargements Github 13 .
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 14
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 | head -1 | cut -d\
-f1`
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.
12. http://github.com/cakephp/cakephp
13. https://github.com/cakephp/cakephp/tags
14. http://github.com/cakephp/cakephp

32

Chapitre 2. Installation

CakePHP Cookbook Documentation, Version 2.x

Production : Ncessite dtre habilit configurer le Document Root du serveur, URLs propres, trs
scuris.
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 :

Dveloppement

33

CakePHP Cookbook Documentation, Version 2.x

include_path = .:/home/mark/projects/cakephp/lib:/usr/local/php/lib/php

Aprs avoir redmarr votre serveur web, vous devriez voir les changements dans phpinfo().
Note : Si vous tes sur Windows, les chemins dinclusion sont spars par des ; au lieu de :
Une fois que vous avez configur votre include_path, vos applications devraient tre capable de trouver
automatiquement CakePHP.

Production
Une installation production est une faon plus flexible de lancer CakePHP. Utiliser cette mthode permet
tout un domaine dagir comme une seule application CakePHP. Cet exemple vous aidera installer CakePHP
nimporte o dans votre systme de fichiers et le rendre disponible ladresse : http://www.exemple.com.
Notez que cette installation demande davoir les droits pour modifier le DocumentRoot sur le serveur web
Apache.
Dcompressez les contenus de larchive CakePHP dans un rpertoire de votre choix. Pour les besoins de cet
exemple, nous considrons que vous avez choisi dinstaller CakePHP dans /cake_install. Votre installation
de production devrait ressembler quelque chose comme ceci dans votre systme de fichiers :
/cake_install/
app/
webroot/ (ce rpertoire est dfini comme rpertoire
``DocumentRoot``)
lib/
plugins/
vendors/
.htaccess
index.php
README

Les dveloppeurs utilisant Apache devraient rgler la directive DocumentRoot pour le domaine :
DocumentRoot /cake_install/app/webroot

Si votre serveur web est configur correctement, vous devriez maintenant accder votre application CakePHP accessible ladresse : http://www.exemple.com.

34

Chapitre 2. Installation

CakePHP Cookbook Documentation, Version 2.x

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 :
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
Avant de commencer, vous devez vous assurer que vous avez une version de PHP mise jour :
php -v

Vous devez avoir au moins PHP 5.3.0 (CLI) ou suprieur. La version de PHP du serveur web doit tre la
version 5.3.0 ou suprieur, et doit tre la mme version que la version de PHP de votre ligne de commande
(CLI).
Installer 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 15 est le dpt principal
des packages installables avec Composer. Puisque CakePHP publie aussi les versions dans Packagist, vous
pouvez installer CakePHP en utilisant Composer 16 .
Installer Composer sur Linux et Mac OS X
1. Excutez le script dinstallation comme dcrit dans la documentation officielle de Composer 17
et suivez les instructions pour installer Composer.
2. Excutez la commande suivante pour dplacer composer.phar vers un rpertoire qui est dans
votre path :
15. https://packagist.org/
16. http://getcomposer.org
17. https://getcomposer.org/download/

Installation avance et URL Rewriting

35

CakePHP Cookbook Documentation, Version 2.x

mv composer.phar /usr/local/bin/composer

Installer Composer sur Windows


Pour les systmes Windows, vous pouvez tlcharger linstalleur Windows de Composer ici 18 .
Dautres instructions pour linstalleur Windows de Composer se trouvent dans le README 19 .
Crer un Projet CakePHP
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/

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 :
18. https://github.com/composer/windows-setup/releases/
19. https://github.com/composer/windows-setup

36

Chapitre 2. Installation

CakePHP Cookbook Documentation, Version 2.x

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
/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.
Installation avance et URL Rewriting

37

CakePHP Cookbook Documentation, Version 2.x

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.

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

38

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 20 est un framework 21 pour PHP 22 gratuit 23 , open-source 24 , de dveloppement rapide 25 . 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 26 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.
20.
21.
22.
23.
24.
25.
26.

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

39

CakePHP Cookbook Documentation, Version 2.x

Systme de licence souple 27 .


Compatible avec les versions PHP 5.2.8 et suprieures.
Fonctions CRUD 28 . (create, read, update, delete) intgres pour les interactions avec la base de
donnes.
Scaffolding 29 (maquettage rapide) dapplication.
Gnration de code.
Architecture MVC 30 .
Dispatcheur de requtes avec des URLs propres et personnalisables grce un systme de routes.
Validation intgre des donnes 31 .
Systme de template 32 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 33 flexible.
Nettoyage des donnes.
Systme de cache 34 souple.
Localisation et internationalisation.
Fonctionne sur nimporte quelle arborescence de site web, avec un zest de configuration Apache 35
pas trs complique.

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


CakePHP suit le motif de conception logicielle MVC 36 . 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
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.

40

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

suggestions de nouveaux amis, etc ... Tandis que les objets Models seront Ami, User, Commentaire,
Photo.

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

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

41

CakePHP Cookbook Documentation, Version 2.x

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
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 37 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
37. http://en.wikipedia.org/wiki/Software_prototyping

42

Chapitre 3. Dbuter avec CakePHP

CakePHP Cookbook Documentation, Version 2.x

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.

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 38 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.
38. https://github.com/cakephp?tab=members

O obtenir de laide

43

CakePHP Cookbook Documentation, Version 2.x

Forum Officiel
Forum Officiel de CakePHP 39
Notre forum officiel o vous pouvez demander de laide, suggrer des ides et discuter de CakePHP. Cest
lendroit idal pour trouver rapidement des rponses et aider les autres. Rejoignez la famille de CakePHP en
vous y inscrivant.

Stackoverflow
http://stackoverflow.com/ 40
Taggez vos questions avec cakephp et la version spcifique que vous utilisez pour permettre aux utilisateurs existant de stackoverflow de trouver vos questions.

O Trouver de lAide dans Votre Langue


Portugais brsilien
Communaut de CakePHP brsilienne 41
Danoise
Canal CakePHP danois sur Slack 42
Franaise
Communaut de CakePHP Francophone 43
Allemande
Canal CakePHP allemand sur Slack 44
Groupe Facebook CakePHP Allemand 45
Iranienne
Communaut de CakePHP iranienne 46
39.
40.
41.
42.
43.
44.
45.
46.

44

http://discourse.cakephp.org
http://stackoverflow.com/questions/tagged/cakephp/
http://cakephp-br.org
https://cakesf.slack.com/messages/denmark/
http://cakephp-fr.org
https://cakesf.slack.com/messages/german/
https://www.facebook.com/groups/146324018754907/
http://cakephp.ir

Chapitre 3. Dbuter avec CakePHP

CakePHP Cookbook Documentation, Version 2.x

Hollandaise
Canal CakePHP hollandais sur Slack 47
Japonaise
Groupe Facebook CakePHP JAPAN 48
Portugaise
Groupe Google CakePHP protugais 49
Espagnol
Canal CakePHP espagnol sur Slack 50
Canal IRC de CakePHP espagnol
Groupe Google de CakePHP espagnol 51

47.
48.
49.
50.
51.

https://cakesf.slack.com/messages/netherlands/
https://www.facebook.com/groups/304490963004377/
http://groups.google.com/group/cakephp-pt
https://cakesf.slack.com/messages/spanish/
http://groups.google.com/group/cakephp-esp

O obtenir de laide

45

CakePHP Cookbook Documentation, Version 2.x

46

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 :

47

CakePHP Cookbook Documentation, Version 2.x

class AppController extends Controller {


}

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

48

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

et search(). Le controller serait trouv dans /app/Controller/RecettesController.php et


contiendrait :
# /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().
Les Actions du Controller

49

CakePHP Cookbook Documentation, Version 2.x

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.

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

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 :
52. http://api.cakephp.org/2.4/class-Controller.html

50

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

// 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:
?>
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
Les Mthodes du Controller

51

CakePHP Cookbook Documentation, Version 2.x

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

de

Vous pouvez aussi rendre les vues des plugins en utilisant la syntaxe suivante
$this->render('PluginName.PluginController/custom_file'). Par exemple :

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(

52

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

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.
Les Mthodes du Controller

53

CakePHP Cookbook Documentation, Version 2.x

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

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 :

54

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

Les Mthodes du Controller

55

CakePHP Cookbook Documentation, Version 2.x

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

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

56

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

Les Mthodes du Controller

57

CakePHP Cookbook Documentation, Version 2.x

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.
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 53 .
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 {
53. http://api.cakephp.org/2.4/class-Controller.html

58

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

Les attributs du Controller

59

CakePHP Cookbook Documentation, Version 2.x

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 54 , il y a dautres
attributs du controller qui mritent leurs propres sections dans le manuel.

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 :
54. http://api.cakephp.org

60

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

$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'];
// 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

En savoir plus sur les controllers

61

CakePHP Cookbook Documentation, Version 2.x

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 :
$foo = $this->request->data('Value.that.does.not.exist');
// $foo == null

Accder aux donnes PUT ou POST


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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

miner 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

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

En savoir plus sur les controllers

63

CakePHP Cookbook Documentation, Version 2.x

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

64

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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.
Nouveau dans la version 2.3.
Obsolte depuis la version 2.5 : Utilisez CakeRequest::allowMethod() la place.
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.
Nouveau 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');

En savoir plus sur les controllers

65

CakePHP Cookbook Documentation, Version 2.x

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

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

66

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les controllers

67

CakePHP Cookbook Documentation, Version 2.x

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

68

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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',
'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.
Nouveau 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() :

En savoir plus sur les controllers

69

CakePHP Cookbook Documentation, Version 2.x

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

70

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

$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
Nouveau dans la version 2.1.
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
Nouveau 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)) {

En savoir plus sur les controllers

71

CakePHP Cookbook Documentation, Version 2.x

return $this->response;
}
...
}

Len-tte Last-Modified
Nouveau 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 :
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');

72

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

// ...
}

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 :
// Dfinit la localisation du redirect
$this->response->location('http://example.com');
// Rcupre l'en-tte de localisation du redirect actuel
$location = $this->response->location();

Nouveau 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.
Nouveau dans la version 2.1.
CakeResponse::expires($time = null)
Permet de configurer len-tte Expires une date spcifique.
Nouveau dans la version 2.1.
CakeResponse::etag($tag = null, $weak = false)
Configure len-tte Etag pour identifier de manire unique une ressource de rponse.
Nouveau dans la version 2.1.
En savoir plus sur les controllers

73

CakePHP Cookbook Documentation, Version 2.x

CakeResponse::modified($time = null)
Configure len-tte Last-modified une date et un temps donn dans le format correct.
Nouveau 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.
Nouveau 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.
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.
Nouveau 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.

74

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les controllers

75

CakePHP Cookbook Documentation, Version 2.x

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

76

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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.

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

En savoir plus sur les controllers

77

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.

78

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

79

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 4. Controllers (Contrleurs)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les controllers

81

CakePHP Cookbook Documentation, Version 2.x

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.

82

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.

83

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

84

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


Nouveau 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

85

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


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

86

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


Nouveau 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

87

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
88

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

Layouts

89

CakePHP Cookbook Documentation, Version 2.x

Utiliser les layouts partir de plugins


Nouveau dans la version 2.1.
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 :

90

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

echo $this->element('helpbox', array(


"helptext" => "Ceci est pass l'element comme $helptext",
"foobar" => "Ceci est pass l'element via $foobar",
),
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'
);
?>

Elements

91

CakePHP Cookbook Documentation, Version 2.x

<ol>
<?php foreach ($posts as $post): ?>
<li><?php echo $post['Post']['title']; ?></li>
<?php endforeach; ?>
</ol>

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

92

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

Crer vos propres classes de vue

93

CakePHP Cookbook Documentation, Version 2.x

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

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.

94

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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.
Nouveau 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.
Nouveau dans la version 2.1.
View::append($name, $content)
Ajoute dans le block avec $name. Regardez la section sur les Utiliser les Blocs de Vues pour des
exemples.
Nouveau 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.
Nouveau 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.
Nouveau 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.
Nouveau 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.
Nouveau 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.
Nouveau 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.

API de View

95

CakePHP Cookbook Documentation, Version 2.x

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.
Nouveau dans la version 2.1.

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.

96

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

97

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

99

CakePHP Cookbook Documentation, Version 2.x

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

100

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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.
Nouveau 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.
JSONP response
Nouveau 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

En savoir plus sur les vues

101

CakePHP Cookbook Documentation, Version 2.x

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

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

102

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

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.

En savoir plus sur les vues

103

CakePHP Cookbook Documentation, Version 2.x

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 :

104

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<?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 :
<form id="UserAddForm" method="post" action="/users/add">

En savoir plus sur les vues

105

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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>

En savoir plus sur les vues

107

CakePHP Cookbook Documentation, Version 2.x

Obsolte depuis la version 2.8.0 : Loption $options['action'] a t dprcie depuis


2.8.0. Utilisez les options $options['url'] et $options['id'] la place.
$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(false, array(
'url' => array('controller' => 'recipes', 'action' => 'add'),
'id' => 'RecipesAdd'
));

Affichera :
<form method="post" action="/recipes/add">

ou pointer vers un domaine extrieur :


echo $this->Form->create(false, 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.
Modifi dans la version 2.8.0 : Utilisez 'url' => false si vous ne voulez pas afficher une
URL pour laction du formulaire.
$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'));

108

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 55 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.
55. http://api.cakephp.org/2.4/class-FormHelper.html

En savoir plus sur les vues

109

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 TypeChamp de formulaire rsultant
string (char, varchar, etc.)text
boolean, tinyint(1)checkbox
texttextarea
text, avec le nom de password, passwd, ou pswordpassword
text, avec le nom de emailemail
text, avec le nom de tel, telephone, ou phonetel
dateday, month, et year selects
datetime, timestampday, month, year, hour, minute, et meridian selects
timehour, minute, et meridian selects
binaryfile
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().
Nouveau dans la version 2.5 : Le type binaire mappe maintenant vers un input de fichier.
Nouveau 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');

110

//text
//password

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

echo $this->Form->input('approved');
echo $this->Form->input('quote');

//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().
FormHelper::inputs(mixed $fields = null, array $blacklist = null, $options = array())
En savoir plus sur les vues

111

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

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

En savoir plus sur les vues

113

CakePHP Cookbook Documentation, Version 2.x

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

114

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

115

CakePHP Cookbook Documentation, Version 2.x

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

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

// 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().
$options['maxlength'] Dfinissez cette cl pour dfinir lattribut maxlength du champ
input avec une valeur spcifique. Quand cette cl nest pas donne et que le type dinput est text,
textarea, email, tel, url ou search et que la dfinition de champ nest pas decimal,
time ou datetime, loption length du champ de la base de donnes est utilise.
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.

En savoir plus sur les vues

117

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

118

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

119

CakePHP Cookbook Documentation, Version 2.x

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

120

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<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.
Nouveau dans la version 2.4.

En savoir plus sur les vues

121

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

123

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$attributes['fieldset'] Si lattribut legend nest pas dfini false, alors cet attribut
peut tre utilis pour dfinir la classe de llment fieldset.
Modifi dans la version 2.1 : Loption dattribut $attributes['disabled'] a t ajoute dans
CakePHP 2.1.
Modifi dans la version 2.8.5 : Loption dattribut $attributes['fieldset'] a t ajoute
dans CakePHP dans 2.8.5.
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=""></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>

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

En savoir plus sur les vues

125

CakePHP Cookbook Documentation, Version 2.x

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

126

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<div class="checkbox">
<input name="data[Model][field][]" 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>

$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 :
echo $this->Form->create('Document', array(
'enctype' => 'multipart/form-data'
));
// OU

En savoir plus sur les vues

127

CakePHP Cookbook Documentation, Version 2.x

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


56. http://php.net/features.file-upload

128

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 $this->Form->button('Un bouton');
echo $this->Form->button('Un autre Bouton', array('type' => 'button'));
echo $this->Form->button('Initialise le Formulaire', array('type' =>
'reset'));
echo $this->Form->button('Soumettre le Formulaire', array('type' =>
'submit'));

En savoir plus sur les vues

129

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

jusqu $maxYear. Les attributs HTML devrons tre fournis dans


$attributes['empty'] est false, le select ninclura pas doption empty :

$attributes.

Si

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.

En savoir plus sur les vues

131

CakePHP Cookbook Documentation, Version 2.x

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

132

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

Configuration par dfaut pour tous les champs


Nouveau 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 avec les mmes valeurs par dfaut

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

En savoir plus sur les vues

133

CakePHP Cookbook Documentation, Version 2.x

Le
paramtre
$selected``a 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')

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.

134

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 /.
echo $this->Html->css('forms');

Affichera :

En savoir plus sur les vues

135

CakePHP Cookbook Documentation, Version 2.x

<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
<?php
echo $this->Html->meta(
'favicon.ico',
'/favicon.ico',
array('type' => 'icon')

136

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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


HtmlHelper::docType(string $type = xhtml-strict)
Paramtres
En savoir plus sur les vues

137

CakePHP Cookbook Documentation, Version 2.x

$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 $pathChemin de limage.
param array $optionsUn tableau de attributs html.
Cr une balise image formate. Le chemin fournit devra tre relatif /app/webroot/img/.

138

Chapitre 5. Views (Vues)

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

139

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 this recipe?');">Delete</a>

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
140

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

141

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

142

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

143

CakePHP Cookbook Documentation, Version 2.x

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

144

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

145

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

147

CakePHP Cookbook Documentation, Version 2.x

$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')) , 'Yes'),
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.
148

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$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

URL avec des paramtres GET et une ancre nomme :


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

En savoir plus sur les vues

149

CakePHP Cookbook Documentation, Version 2.x

// Restituera
/posts/search?foo=bar#first

Pour plus dinformation voir Router::url 57 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 :
echo $this->Html->getCrumbs(' > ', 'Home');
57. http://api.cakephp.org/2.4/class-Router.html#_url

150

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

151

CakePHP Cookbook Documentation, Version 2.x

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

152

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

$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

En savoir plus sur les vues

153

CakePHP Cookbook Documentation, Version 2.x

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

154

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

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

155

CakePHP Cookbook Documentation, Version 2.x

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

156

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 larequte.
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 uncallback. 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 pourllment
draggable.
Options dvnements
En savoir plus sur les vues

157

CakePHP Cookbook Documentation, Version 2.x

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

158

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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.
$("#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 :
En savoir plus sur les vues

159

CakePHP Cookbook Documentation, Version 2.x

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

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 :

160

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

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

161

CakePHP Cookbook Documentation, Version 2.x

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

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
162

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

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

163

CakePHP Cookbook Documentation, Version 2.x

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

164

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

),
'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
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
En savoir plus sur les vues

165

CakePHP Cookbook Documentation, Version 2.x

Le troisime
disponibles :
Option
before
after
zero

paramtre est un tableau doptions pour dfinir la sortie. Les options suivantes sont
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
wholeLa chane de caractres utiliser pour les tous nombres. ex : dollars
Symbol
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
fractioFraction exponent de cette monnaie spcifique. Par dfaut 2.
nExponent
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)

CakeNumber::currency().

Dfini

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.
Nouveau dans la version 2.3 : Cette mthode a t ajoute dans 2.3.
NumberHelper::addFormat(string $formatName, array $options)
166

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 :
array(
'wholeSymbol'
'wholePosition'
'fractionSymbol'
'fractionPosition'
'zero'
'places'
'thousands'
'decimals'
'negative'

En savoir plus sur les vues

=>
=>
=>
=>
=>
=>
=>
=>
=>

'',
'before',
false,
'after',
0,
2,
',',
'.',
'()',

167

CakePHP Cookbook Documentation, Version 2.x

'escape'
=> true,
'fractionExponent' => 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');
echo CakeNumber::toPercentage(45.691873645);
// Appel avec multiply. Sortie: 45.69%
echo CakeNumber::toPercentage(0.45691, 2, array(
'multiply' => true
));

Nouveau dans la version 2.4 : Largument $options avec loption multiply a t ajout.
NumberHelper::fromReadableSize(string $size, $default)
168

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

169

CakePHP Cookbook Documentation, Version 2.x

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

170

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

'places' => 2,
'decimals' => '.',
'thousands' => ','
));
// sortie '+123,456.79'

Nouveau 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.
lock Verrouiller la direction. Va seulement utiliser la direction par dfaut, par dfaut false.
Nouveau 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 :
En savoir plus sur les vues

171

CakePHP Cookbook Documentation, Version 2.x

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

172

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

173

CakePHP Cookbook Documentation, Version 2.x

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

174

Chapitre 5. Views (Vues)

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

175

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

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

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

En savoir plus sur les vues

177

CakePHP Cookbook Documentation, Version 2.x

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 58 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>
58. http://api.cakephp.org/2.4/class-PaginatorHelper.html

178

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<?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 uneentit 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().
En savoir plus sur les vues

179

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

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

180

Chapitre 5. Views (Vues)

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.


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

En savoir plus sur les vues

181

CakePHP Cookbook Documentation, Version 2.x

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

182

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

183

CakePHP Cookbook Documentation, Version 2.x

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

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

184

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 retournstring
Retourne un lment RSS <channel />.
RssHelper::document(array $attrib = array (), string $content = null)
Type retournstring
Retourne un document RSS entour de tags <rss />.
RssHelper::elem(string $name, array $attrib = array (), mixed $content = null, boolean $endTag = true)
Type retournstring
Gnre un lment XML.
RssHelper::item(array $att = array (), array $elements = array ())
Type retournstring
Convertit un tableau en un lment <item /> et ses contenus.
RssHelper::items(array $items, mixed $callback = null)
Type retournstring
Transforme un tableau de donnes en utilisant un callback optionnel, et le map pour un ensemble de
tags <item />.
RssHelper::time(mixed $time)
Type retournstring
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.

En savoir plus sur les vues

185

CakePHP Cookbook Documentation, Version 2.x

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 retournmixed
Lire partir de la Session. Retourne une chane de caractre ou un tableau dpendant des contenus de
la session.
SessionHelper::consume($name)
Type retournmixed
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 retournboolean
Vrifie si une cl est dans la Session. Retourne un bolen sur lexistence dun cl.
SessionHelper::error()
Type retournstring
Retourne la dernire erreur rencontre dans une session.
SessionHelper::valid()
Type retournboolean
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 :

186

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<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("L'utilisateur n'a pas 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('Merci pour votre paiement %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);.
En savoir plus sur les vues

187

CakePHP Cookbook Documentation, Version 2.x

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

Output :
188

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

<p>Pour plus d\'information<br />


selon nos clbres ptes et desserts.<p>
<p>contact info@example.com</p>

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

189

CakePHP Cookbook Documentation, Version 2.x

$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 :
array(
'ellipsis' => '...',

190

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

'exact' => true


)

Nouveau 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, '...');
// appel avec CakeText

En savoir plus sur les vues

191

CakePHP Cookbook Documentation, Version 2.x

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.

192

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

193

CakePHP Cookbook Documentation, Version 2.x

// 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.
Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::daysAsSql($begin, $end, $fieldName, $userOffset = NULL)
Type retournstring
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.
Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::format($date, $format = NULL, $default = false, $timezone = NULL)
Type retournstring
Va retourner une chane formate avec le format donn en utilisant les options de formatage de la
fonction PHP strftime() 59 :
// 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 :
59. http://www.php.net/manual/en/function.strftime.php

194

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

// 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.
Nouveau dans la version 2.2 : Le paramtre $date accepte aussi maintenant un objet DateTime.
TimeHelper::fromString($dateString, $timezone = NULL)
Type retournstring
Prend une chane et utilise strtotime 60 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.
Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::gmt($dateString = NULL)
Type retourninteger
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 retournstring
60. http://us.php.net/manual/en/function.date.php

En savoir plus sur les vues

195

CakePHP Cookbook Documentation, Version 2.x

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 retournstring
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 retournstring
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.
Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::serverOffset()
Type retourninteger
Retourne la valeur du serveur partir du GMT dans les secondes.
TimeHelper::timeAgoInWords($dateString, $options = array())
Type retournstring
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

196

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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


Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toAtom($dateString, $timezone = NULL)
Type retournstring
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.
Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
En savoir plus sur les vues

197

CakePHP Cookbook Documentation, Version 2.x

TimeHelper::toQuarter($dateString, $range = false)


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

Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
Nouveau 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 retournstring
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.
Nouveau dans la version 2.2 : Le paramtre $dateString accepte aussi maintenant un objet DateTime.
TimeHelper::toUnix($dateString, $timezone = NULL)
Type retourninteger
Un enrouleur pour fromString.
Modifi dans la version 2.2 : Le paramtre $timezone remplace le paramtre $userOffset
utilis dans 2.1 et suivants.
Nouveau 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 retournmixed
Nouveau dans la version 2.2 : Retourne une date formate dans le timezone du serveur.
198

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

TimeHelper::timezone($timezone = NULL)
Type retournDateTimeZone
Nouveau 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 retournarray
Nouveau 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)
Nouveau dans la version 2.4.
TimeHelper::isPast($dateString, $timezone = NULL)
Nouveau 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.
Nouveau 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.
En savoir plus sur les vues

199

CakePHP Cookbook Documentation, Version 2.x

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);
}
}
class AwesomeController extends AppController {
public $helpers = array('Awesome' => array('option1' => 'valeur1'));
}

200

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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

En savoir plus sur les vues

201

CakePHP Cookbook Documentation, Version 2.x

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 :
/* /app/View/Helper/LienHelper.php (Utilisant d'autres helpers) */
App::uses('AppHelper', 'View/Helper');
class LienHelper extends AppHelper {

202

Chapitre 5. Views (Vues)

CakePHP Cookbook Documentation, Version 2.x

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 :

206

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

class Recette extends AppModel {


public function steakRecipes() {
$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.
Pour en savoir plus sur les Models

207

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

211

CakePHP Cookbook Documentation, Version 2.x

Nous pouvons aussi dfinir une relation plus spcifique en utilisant une syntaxe de tableau :
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
(

212

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[id] => 121


[name] => Gwoo the Kungwoo
[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(

Pour en savoir plus sur les Models

213

CakePHP Cookbook Documentation, Version 2.x

'counterCache' => true,


// compte seulement si "ImageComment" est active = 1
'counterScope' => array(
'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

214

Schema
Comment.user_id
Virtue.cake_id
Option.product_id

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

On peut dfinir lassociation hasMany dans notre model User (/app/Model/User.php) en utilisant une chane
de caractres de cette manire :
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 :

Pour en savoir plus sur les Models

215

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

217

CakePHP Cookbook Documentation, Version 2.x

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

218

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

(
[Recipe] => Array
(
[id] => 2745
[name] => Chocolate Frosted Sugar Bombs
[created] => 2007-05-01 10:31:01
[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

Pour en savoir plus sur les Models

219

CakePHP Cookbook Documentation, Version 2.x

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

220

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

221

CakePHP Cookbook Documentation, Version 2.x

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

222

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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

Pour en savoir plus sur les Models

223

CakePHP Cookbook Documentation, Version 2.x

);
}

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

224

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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


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(

Pour en savoir plus sur les Models

225

CakePHP Cookbook Documentation, Version 2.x

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

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

226

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

'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.
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] => Array
(
[id] => 1
[champ1] => valeur1
[champ2] => valeur2

Pour en savoir plus sur les Models

227

CakePHP Cookbook Documentation, Version 2.x

[champ3] => 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(
'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')
));
// ...
}

228

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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]
(
[id] => 1
[champ1] =>
[champ2] =>
[champ3] =>
)

=> Array

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

Pour en savoir plus sur les Models

229

CakePHP Cookbook Documentation, Version 2.x

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

230

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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
(

Pour en savoir plus sur les Models

231

CakePHP Cookbook Documentation, Version 2.x

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

Array

=> 83
valeur1
valeur2
valeur3

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

232

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

233

CakePHP Cookbook Documentation, Version 2.x

[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.
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,
234

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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

Pour en savoir plus sur les Models

235

CakePHP Cookbook Documentation, Version 2.x

$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 ci-dessus)
public 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
*
* @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']);
}
}
}
}

236

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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)

Pour en savoir plus sur les Models

237

CakePHP Cookbook Documentation, Version 2.x

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','123');
User.username = 'jhon' AND
User.password = '123';
$this->User->findAllByLastName('psychic',array(),array('User.user_name
User.last_name = 'psychic'
=> 'asc'));
ORDER BY User.user_name
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)
));

Nouveau dans la version 2.8.0 : Les finders magiques personnaliss ont t ajouts dans 2.8.0.
findBy
findBy<fieldName>(string $value);
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','123');
User.username = 'jhon' AND
User.password = '123';
$this->Cake->findById(7);
Cake.id = 7

238

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

239

CakePHP Cookbook Documentation, Version 2.x

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
// affiche le nom de la dernire instance cre
echo $this->Post->field(
'name',
array('created <' => date('Y-m-d H:i:s')),
'created DESC'
);

240

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

241

CakePHP Cookbook Documentation, Version 2.x

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
)

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 ? :
array(
'fields' => array(
'Produit.type',
'MIN(Produit.prix) as prix'

Pour en savoir plus sur les Models

243

CakePHP Cookbook Documentation, Version 2.x

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

Qui produira la requte SQL suivante :

244

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 :

Pour en savoir plus sur les Models

245

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

246

Chapitre 6. Models (Modles)

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 :

Pour en savoir plus sur les Models

247

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

248

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

249

CakePHP Cookbook Documentation, Version 2.x

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

250

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

251

CakePHP Cookbook Documentation, Version 2.x

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

252

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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.

Pour en savoir plus sur les Models

253

CakePHP Cookbook Documentation, Version 2.x

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

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.

254

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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


information aux donnes
// 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).

Pour en savoir plus sur les Models

255

CakePHP Cookbook Documentation, Version 2.x

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

256

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

257

CakePHP Cookbook Documentation, Version 2.x

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

258

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

259

CakePHP Cookbook Documentation, Version 2.x

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
(
[Recipe] => Array
(
[id] => 43
)
[Tag] => Array
(
[name] => Pasta
)
)
[2] => Array
(
[Recipe] => Array
(
[id] => 51
)
[Tag] => Array
(
[name] => Mexican
)
)
[3] => Array
(
[Recipe] => Array

260

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

261

CakePHP Cookbook Documentation, Version 2.x

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

262

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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

Pour en savoir plus sur les Models

263

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

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

Pour en savoir plus sur les Models

265

CakePHP Cookbook Documentation, Version 2.x

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

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

266

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

267

CakePHP Cookbook Documentation, Version 2.x

'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.
Par exemple, pour sassurer que luser fournit une adresse email correcte, vous pouvez utiliser cette rgle :
public $validate = array('user_email' => 'email');

268

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Souvenez-vous, la cl rule est obligatoire pour les dfinitions de rgles sous forme de tableau.

Pour en savoir plus sur les Models

269

CakePHP Cookbook Documentation, Version 2.x

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.

270

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

Pour en savoir plus sur les Models

271

CakePHP Cookbook Documentation, Version 2.x

'last' => true


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

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

273

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

274

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

275

CakePHP Cookbook Documentation, Version 2.x

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(
'rule' => 'isUnique',
'required' => 'create'
),
'alphanumeric' => array(
'rule' => 'alphanumeric'
)
);

Modifier les rgles de validation courantes


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

276

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$validator = $this->validator();
$validator['username']['unique'] = array(
'rule' => 'isUnique',
'required' => 'create'
);
$validator['username']['unique']->last = true;
$validator['username']['unique']->message = 'Name already taken';

Retirer des rgles dun ensemble


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

Pour en savoir plus sur les Models

277

CakePHP Cookbook Documentation, Version 2.x

)
);

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

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

278

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

electron
enroute
jcb
maestro
mc
solo
switch
visa
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 :

Pour en savoir plus sur les Models

279

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

281

CakePHP Cookbook Documentation, Version 2.x

)
);

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

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

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

282

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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',
'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)
Nouveau dans la version 2.2.

Pour en savoir plus sur les Models

283

CakePHP Cookbook Documentation, Version 2.x

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

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'

284

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

)
);

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)
Nouveau dans la version 2.7.
La rgle de base pour sassurer quun champ nest pas vide.
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)


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

Pour en savoir plus sur les Models

285

CakePHP Cookbook Documentation, Version 2.x

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.
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)
Nouveau dans la version 2.2.
286

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

287

CakePHP Cookbook Documentation, Version 2.x

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

288

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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

Pour en savoir plus sur les Models

289

CakePHP Cookbook Documentation, Version 2.x

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

290

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

291

CakePHP Cookbook Documentation, Version 2.x

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.

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

292

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

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

293

CakePHP Cookbook Documentation, Version 2.x

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


$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
61. http://en.wikipedia.org/wiki/Mixin

294

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 :

Pour en savoir plus sur les Models

295

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

296

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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
(
[0] => Array
(
[id] => 1
[name] => A
)
[1] => Array
(
[id] => 2
[name] => B
)

Pour en savoir plus sur les Models

297

CakePHP Cookbook Documentation, Version 2.x

)
)
[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 :
$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.
298

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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
(
[0] => Array
(
[auteur] => Daniel
[post_id] => 1
)
[1] => Array
(
[auteur] => Sam

Pour en savoir plus sur les Models

299

CakePHP Cookbook Documentation, Version 2.x

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

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.

300

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

[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
(
[0] => Array
(
[id] => 22
[post_id] => 3
[author] => Daniel
[email] => dan@example.com

Pour en savoir plus sur les Models

301

CakePHP Cookbook Documentation, Version 2.x

[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(
'fields' => array('id', 'note')
)
)
),
'Tag' => array(
'conditions' => array('Tag.name LIKE' => '%happy%')

302

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

)
)
)
));

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
invalides cause du mlange de champs agrgs et non-agrgs, essayer de dsactiver le paramtre
autoFields :

Pour en savoir plus sur les Models

303

CakePHP Cookbook Documentation, Version 2.x

$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

304

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

305

CakePHP Cookbook Documentation, Version 2.x

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.
class Post extends AppModel {
public $actsAs = array(
'Translate' => array(
'title' => 'titleTranslation'
)
);
}

306

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.
Utiliser la mthode bindTranslation
Vous pouvez aussi rcuprer toutes les traductions seulement quand vous en avez besoin, en utilisant la
mthode bindTranslation.

Pour en savoir plus sur les Models

307

CakePHP Cookbook Documentation, Version 2.x

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 recursive 1 pour que ceci fonctionne

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
308

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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(

Pour en savoir plus sur les Models

309

CakePHP Cookbook Documentation, Version 2.x

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

310

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

311

CakePHP Cookbook Documentation, Version 2.x

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

312

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

`lft`, `rght`)

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

INSERT INTO
`categories` (`id`, `name`, `parent_id`, `lft`, `rght`)
VALUES
(13, 'Trips', 9, 23, 28);
INSERT INTO
`categories` (`id`, `name`, `parent_id`, `lft`, `rght`)
VALUES
(14, 'National', 13, 24, 25);
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
Pour en savoir plus sur les Models

313

CakePHP Cookbook Documentation, Version 2.x

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

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

315

CakePHP Cookbook Documentation, Version 2.x

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

316

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 lments

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, par exemple {n}.Post.id.
$valuePath Chemin du champ utiliser pour le label, par exemple
{n}.Post.title.
Pour en savoir plus sur les Models

317

CakePHP Cookbook Documentation, Version 2.x

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

318

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

319

CakePHP Cookbook Documentation, Version 2.x

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

320

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.
$model->reorder(array(
//id de l'enregistrement utiliser comme noeud haut pour rordonner,
default: $Model->id
'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' =>
));

Pour en savoir plus sur les Models

321

CakePHP Cookbook Documentation, Version 2.x

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 lft``et``rght``pour 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.
322

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

'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] =>
)
[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"

Pour en savoir plus sur les Models

323

CakePHP Cookbook Documentation, Version 2.x

Niveau du Noeud (Profondeur)


Nouveau 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)
Nouveau 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 :
class Category extends AppModel {
public $actsAs = array('Tree' => array(
'left' => 'left_node',
'right' => 'right_node'
));
}

324

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

325

CakePHP Cookbook Documentation, Version 2.x

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

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

326

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

327

CakePHP Cookbook Documentation, Version 2.x

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

328

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.
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 62 .
62. https://github.com/cakephp/datasources/tree/2.0

Pour en savoir plus sur les Models

329

CakePHP Cookbook Documentation, Version 2.x

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

330

de donnes pourrait
mthodes habituelles
va accder une API
allons la placer dans

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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 avec CakeSchema, par exemple
* fixtures et schema de migrations.
*/
protected $_schema = array(
'id' => array(
'type' => 'integer',
'null' => false,
'key' => 'primary',
'length' => 11,
),
'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

Pour en savoir plus sur les Models

331

CakePHP Cookbook Documentation, Version 2.x

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

332

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

* 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
* 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'],

Pour en savoir plus sur les Models

333

CakePHP Cookbook Documentation, Version 2.x

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

334

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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.

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 63 .
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.
63. http://api.cakephp.org/2.4/class-Model.html

Pour en savoir plus sur les Models

335

CakePHP Cookbook Documentation, Version 2.x

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

336

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

class Example extends AppModel {


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

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

337

CakePHP Cookbook Documentation, Version 2.x

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

338

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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

Pour en savoir plus sur les Models

339

CakePHP Cookbook Documentation, Version 2.x

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))'
);
return $this->find('all', compact('conditions'));
}
}

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

340

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$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

341

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 :

342

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 appel nom.
$this->User->hasField('nom', true); // Retournera true puisqu'il y a un champ
virtuel appel nom.

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

343

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

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 :

344

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

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


AS Timelog GROUP BY project_id;");

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 Timelog GROUP BY project_id;");

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

Pour en savoir plus sur les Models

345

CakePHP Cookbook Documentation, Version 2.x

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

346

Chapitre 6. Models (Modles)

CakePHP Cookbook Documentation, Version 2.x

$dataSource->commit();
} else {
$dataSource->rollback();
// Changer quelque chose dans la tche principale
}
$dataSource->commit();

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

347

CakePHP Cookbook Documentation, Version 2.x

348

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 pour
sprintf(). Vous pouvez fournir des arguments supplmentaires pour remplacer les espaces rservs dans votre chane :
349

CakePHP Cookbook Documentation, Version 2.x

__('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
I18n : :LC_TIME - LC_TIME

350

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

351

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

352

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

353

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 retournvoid
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 CommandsApp::uses('AppShell','Console/Command');
Console TasksApp::uses('BakeTask','Console/Command/Task');
ControllersApp::uses('PostsController','Controller');
354

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

ComponentsApp::uses('AuthComponent','Controller/Component');
ModelsApp::uses('MyModel','Model');
BehaviorsApp::uses('TreeBehavior','Model/Behavior');
ViewsApp::uses('ThemeView','View');
HelpersApp::uses('HtmlHelper','View/Helper');
LibsApp::uses('PaymentProcessor','Lib');
VendorsApp::uses('Textile','Vendor');
UtilitiesApp::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/CommentComponent.php
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 retournarray
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 retournarray
Usage Gnral

355

CakePHP Cookbook Documentation, Version 2.x

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)
Type retournarray
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 retournstring
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 retournvoid
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/')))

356

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

Modifi dans la version 2.0 : App::build() ne va plus fusionner les chemins de app avec les
chemins du coeur.
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 retournmixed 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)

Usage Gnral

357

CakePHP Cookbook Documentation, Version 2.x

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

Localiser les thmes


static App::themePath(string $theme)
Type retournstring
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 retournboolean
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.
358

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Usage Gnral

359

CakePHP Cookbook Documentation, Version 2.x

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 :


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 retournvoid
Initialise le cache pour App, enregistre une fonction shutdown (fermeture).
static App::load(string $className)
Type retournboolean
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 retournvoid
Destructeur de lObjet. Ecrit le fichier de cache si les changements ont t faits $_map.
vnements systme
Nouveau 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

360

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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.
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. Typiquement, quand vous nutilisez
pas directement le modle observateur (observer pattern) vous feriez cela en attachant des behaviors la
vole vos models, et peut tre quelques components aux controllers.
A la place, vous pouvez utiliser les vnements pour vous permettre de sparer clairement ce qui concerne
votre code et permettre dajouter des besoins supplmentaires dans votre plugin en utilisant les vnements.
Par exemple dans votre plugin Cart, vous avez un model Order qui gre la cration des commandes. Vous
voulez notifier au reste de lapplication quune commande a t cre. Pour garder votre model Order propre,
vous pouvez utiliser les vnements :
// 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

Usage Gnral

361

CakePHP Cookbook Documentation, Version 2.x

));
$this->getEventManager()->dispatch($event);
return true;
}
return false;
}
}

Le code ci-dessus vous permet de notifier aux autres parties de lapplication quune commande a t cre.
Vous pouvez ensuite faire des tches comme envoyer les notifications par mail, mettre jour le stock, crer
un fichier de log des statistiques pertinentes et dautres tches dans des objets spars qui se focalisent sur
ces proccupations.
Accder aux Gestionnaires dEvent
Dans CakePHP, les vnements sont attraps par les gestionnaires dvnements. Les gestionnaires dvnements sont disponibles dans chaque Table, View et Controller en utilisant getEventManager() :
$events = $this->getEventManager();

Chaque Model a un gestionnaire dvnements spar, alors que View et Controller en partagent un. Cela
permet aux vnements de Model dtre autonomes, et permet aux components ou aux controllers dagir sur
les vnements crs dans la vue si ncessaire.
Le gestionnaire dEvent global
En plus des gestionnaires au niveau des instances dvnement, CakePHP fournit un gestionnaire dvnements global qui vous permet dcouter tout vnement dclench dans une application. Cest utile quand
attacher des couteurs une instance spcifique semble lent ou difficile. Le gestionnaire global est une instance singleton de CakeEventManager qui reoit chaque vnement avant que les gestionnaires dinstance ne le reoivent. En plus de recevoir les vnements en premier, le gestionnaire global maintient aussi
une pile de priorit distincte pour les couteurs. Une fois quun vnement a t dispatch au gestionnaire
global, il sera dispatch au gestionnaire au niveau de linstance. Vous pouvez accder au gestionnaire global
en utilisant une mthode statique :
// 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.

362

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

363

CakePHP Cookbook Documentation, Version 2.x

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

364

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Usage Gnral

365

CakePHP Cookbook Documentation, Version 2.x

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

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 :
// Paramtrage des priorits pour le callback
$callback = array($this, 'doSomething');
$this->getEventManager()->attach($callback, 'Model.Order.afterPlace', array(
'passParams' => true));
// Paramtrage des priorits pour l'couteur (listener)
class UserStatistic implements CakeEventListener {
public function implementedEvents() {
return array(
'Model.Order.afterPlace' => array('callable' =>
'updateBuyStatistic', 'passParams' => true),
);
}
public function updateBuyStatistic($orderData) {
// ...
}

366

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Usage Gnral

367

CakePHP Cookbook Documentation, Version 2.x

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

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

368

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

369

CakePHP Cookbook Documentation, Version 2.x

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

370

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

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

Usage Gnral

371

CakePHP Cookbook Documentation, Version 2.x

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

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

372

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Components (Composants)

373

CakePHP Cookbook Documentation, Version 2.x

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

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

374

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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 :
/**
* 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 :
Components (Composants)

375

CakePHP Cookbook Documentation, Version 2.x

/**
* 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'),
'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
376

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

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;

Components (Composants)

377

CakePHP Cookbook Documentation, Version 2.x

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

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.

378

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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())
Nouveau dans la version 2.7.0 : en replacement de SessionHelper::flash()
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 :
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',

Components (Composants)

379

CakePHP Cookbook Documentation, Version 2.x

'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['email']) ?>.
</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
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
380

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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. :
$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
Components (Composants)

381

CakePHP Cookbook Documentation, Version 2.x

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

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

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Components (Composants)

383

CakePHP Cookbook Documentation, Version 2.x

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

384

Chapitre 7. Librairies du Coeur

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).
recursive La valeur de la cl rcursive pass find(). Par dfaut 0.
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.
Nouveau dans la version 2.2.
passwordHasher Classe de hash de mot de passe. Par dfaut Simple.
Nouveau 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.
Nouveau 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(

Components (Composants)

385

CakePHP Cookbook Documentation, Version 2.x

'controller' => 'users',


'action' => 'login',
'plugin' => 'users'
),
'authError' => 'Pensiez-vous rellement que vous tiez autoriss
voir cela ?',
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'mon_champ_username_personnalise', //
'username' par dfaut
'password' => 'mon_champ_password_personnalise' //
'password' par dfaut
)
)
)
)
);

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

386

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Components (Composants)

387

CakePHP Cookbook Documentation, Version 2.x

}
}

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

388

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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 :
// 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 une partie du site qui est protg.";

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 :

Components (Composants)

389

CakePHP Cookbook Documentation, Version 2.x

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

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

390

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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 64 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 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'], env('SERVER_NAME')
);
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.
64. https://en.wikipedia.org/wiki/Bcrypt

Components (Composants)

391

CakePHP Cookbook Documentation, Version 2.x

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

392

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Components (Composants)

393

CakePHP Cookbook Documentation, Version 2.x

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

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.

394

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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 vousmme 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
AuthComponent::allow(). En marquant les actions comme publique, le component Auth ne vrifiera pas la connexion dun utilisateur, ni nautorisera la vrification des objets :

Components (Composants)

395

CakePHP Cookbook Documentation, Version 2.x

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

396

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

class AppController extends Controller {


public $components = array(
'Auth' => array('authorize' => 'Controller'),
);
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.

Components (Composants)

397

CakePHP Cookbook Documentation, Version 2.x

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

398

flash

avec

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Components (Composants)

399

CakePHP Cookbook Documentation, Version 2.x

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().
AuthComponent::logout()
RetourneUne 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.
Nouveau 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

400

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

$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.
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 65 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.
65. http://en.wikipedia.org/wiki/Cross-site_request_forgery

Components (Composants)

401

CakePHP Cookbook Documentation, Version 2.x

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

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.

402

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Components (Composants)

403

CakePHP Cookbook Documentation, Version 2.x

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

404

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

}
}

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

Components (Composants)

405

CakePHP Cookbook Documentation, Version 2.x

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() 66 . 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 multiutilisation des jetons en paramtrant csrfUseOnce false. Ceci peut tre effectu dans le tableau
components, ou dans la partie beforeFilter de votre controller :
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.
66. http://php.net/manual/en/function.strtotime.php

406

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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.
Nouveau 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 HTTP-XRequested-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');
// 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 :

Components (Composants)

407

CakePHP Cookbook Documentation, Version 2.x

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
Fennec
iPad
iPhone
iPod
J2ME
MIDP
NetFront
Nokia
Opera Mini
Opera Mobi
PalmOS
PalmSource
portalmmm
Plucker

408

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

Components (Composants)

409

CakePHP Cookbook Documentation, Version 2.x

return $rows;
};
$this->RequestHandler->addInputType('csv', array($parser));

Lexemple ci-dessus ncessite PHP 5.3, cependant vous pouvez utiliser nimporte quel callback 67
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
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
67. http://php.net/callback

410

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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.
Profiter du cache de validation HTTP
Nouveau 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.
Components (Composants)

411

CakePHP Cookbook Documentation, Version 2.x

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


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

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.

412

Chapitre 7. Librairies du Coeur

CakePHP Cookbook Documentation, Version 2.x

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

boolean
$httpOnly

false

5
Days

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

Components (Composants)

413

CakePHP Cookbook Documentation, Version 2.x

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