Présentation PTT

Report
CakePHP 2.x
CakePHP 2.x
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
Présentation framework et philosophie
Arborescence, architecture et installation
Les conventions de CakePHP
Le Router
La couche MVC
Le pattern ActiveRecord et le CRUD de CakePHP
Evénements, Collections et Objets
Les exceptions
Les librairies intégrées
La Console et la Bakery
Le Scaffolding
Présentation framework et philosophie
• Projet initié en 2005 par Michal Tatarynowicz sous licence MIT.
• Le projet a été vite repris par la « Cake Software Foundation »,
fondée par Larry E. Masters et Garrett J. Woodworth. Elle se
compose de quelques developeurs comme Nate Abele (fondateur
de Lithium, autre framework), John Anderson (fondateur du
Cookbook, espace de documentation du framework) ou Mark Story
(actuellement le lead dev sur le projet).
• Lorsqu’on regarde les commits on constate aujourd’hui que
plusieurs personnes d’origines très différentes (USA, Espagne,
Japon, Pays-pays, UK, etc…) participent activement au projet sous la
houlette de la « Cake Software Foundation », il s’agit donc là d’un
vrai projet participatif et collaboratif organisé autour d’une même
communauté.
• CakeDC est l’agence fondée par Larry E. Masters, le SensioLab de
CakePHP en quelques sortes.
Présentation framework et philosophie
• CakePHP est présenté comme l’adaptation en
PHP des principes qui ont fait le succès de Ruby
On Rails.
• Le principal patron de conception est ModèleVue-Controleur c’est pourquoi on dit qu’il s’agit
d’un framework MVC.
• La version stable actuelle est 2.1.1.
• Il est disponible sur PEAR pour les dernières
versions stables ou Github pour les 13 branches
en cours.
Présentation framework et philosophie
• CakePHP est l’expression de « convention au
lieu de configuration ».
• La priorité de CakePHP est le développement
rapide en utilisant des paradigmes bien
définis.
• Dans CakePHP chaque fonctionnalité se code
d’une façon particulière, le framework impose
une architecture et un best practice.
Arborescence, architecture et
installation
|-|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app
|-|
|-|
|
|-|
|-|-|-|
|
|
|
|-|-|
|--
Config
|-- Schema
Console
|
|-- Command
|
`-- Task
Controller
`-- Component
Lib
Locale
Model
|-- Behavior
|
`-- Datasource
|
Plugin
Test
|
Vendor
->
->
->
->
->
->
->
->
->
->
->
->
->
->
->
->
Dossier des fichiers de l'application
Dossier des fichiers de configuration
Fichiers SQL nécessaires à l'initialisation du projets
Dossier des scripts console
Dossier des commandes shell
Dossier des commandes réutilisables
Dossier des contrôleurs
Dossier des components, librairies de factorisation de code
Dossier des librairies internes au projet
Dossier des locales pour l'internationalisation
Dossier des modèles
Dossier des Behaviors, comportements câblés sur les événements
d'édition de données
Dossier des Datasources, Adpaters particuliers pour accéder à
une API par exemple
Dossier des Plugins, sous-modules MVC
Dossier des Tests, pour faire du développement piloté par les
tests (Avec PHPUnit)
Dossiers des librairies extérieurs
Arborescence, architecture et
installation
|
|
|
|
|
|
|
|
|
|
|
|
|
|-|
|
|
|
|
|
|
|
|
|
|
|
par
View
|
|-- Elements
|-- Emails
|
|-- html
|
`-- text
|-- Errors
|-- Helper
|
|-- Layouts
|
|-- Pages
|-- Scaffolds
exemple
-> Dossier des vues, pour chaque controleur un dossier de vue est
associé
-> Dossier des Elements, sous-vues réutilisables
-> Dossier déstinés aux templates d'e-mails
-> Cas HTML
-> Cas texte
-> Dossiers des vues des pages d'erreur comme 404
-> Dossiers des Helpers de vue du projet, routines de rendus comme
le Helper de formulaires
-> Dossier des layouts, fichier de vue principal comportant
généralement le header et le footer
-> Pages ne nécessitants pas de contrôleurs
-> Dossiers des Scaffolds du projet, vues génrériques pour un BO
Arborescence, architecture et
installation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|-|
|
|
|
|
|
|
|
`--
tmp
|-- cache
|
|-- models
|
|
|
|-- persistent
|
`-- views
|-- logs
|-- sessions
`-- tests
webroot
|-- css
|-- files
|-- img
`-- js
-> Dossiers des fichiers temporaires
-> Dossier de cache
-> Cache de la couche modèle (de la configuration, pas des données
en base), automatique en prod
-> Cache requêtes donc des données en base (modèles persistants)
-> Cache des vues ou de parties de vues
-> Dossier de logs
-> Dossier contenant les sessions
-> Fichiers temporaires issues des tests
-> Document Root
-> Fichiers CSS
-> Uploads
-> Images
-> Javascripts
Arborescence, architecture et
installation
|-- lib
|
`-- Cake
|
|-- Cache
|
|-- Config
|
|-- Configure
|
|-- Console
|
|-- Controller
|
|
`-- Component
|
|-- Core
|
|
|
|-- Error
|
|-- Event
|
|
|
|
|
|-- I18n
|
|-- Log
|
|
`-- Engine
-> Dossier des librairies Cake
-> Readers de fichiers de config (PHP ou INI)
-> Librairies les plus bas niveaux de CakePHP avec notamment App et
Object (beaucoup de composants héritent d'Object)
-> Tous les composants qui ont des callbacks comme les Contrôleurs,
les Components ou les Behaviors implémentent une interface de
listener d'events
Arborescence, architecture et
installation
|
|-|
|
|
|
|
|
|
|
|
|
|
|-|
|
|
|
|
|-|
|
|
|-|
|-|
|-|
|
|
`-|
|
|
|
|-- plugins
`-- vendors
Model
|-- Behavior
`-- Datasource -> CakePHP est livré avec un Adapter de Base de données et de
Session
|-- Database
`-- Session
Network
|-- Email
`-- Http
Routing
`-- Route
Test
TestSuite
Utility -> Classes indépendantes utilisées dans l'ensemble des librairies de
CakePHP
View
|-- Elements
|-- Errors
|-- Helper
`-- Scaffolds
-> Il est possible d’avoir plusieurs « app » partageant le même Core.
Dans ce cas il est également possible d’avoir des plugins et librairies
partagés entre tous les projets.
Arborescence, architecture et
installation
Détail d’une requête CakePHP
Arborescence, architecture et
installation
• L’installation de CakePHP est très simple, il y a plusieurs solutions.
• Un .htaccess se situe à la racine de CakePHP, dans le dossier
« app » et dans le dossier « app/webroot ».
• Même si la convention voudrait qu’on situe le DocumentRoot sur
« app/webroot », grâces aux mutiples .htaccess il est possible de le
positionner sur « app » ou même de mettre l’ensemble des fichiers
de CakePHP.
• Il faudra activer la réécriture d’url et le support des .htaccess (sinon
ajouter dans la configuration serveur le contenu du .htaccess
correspondant).
• Au pire, CakePHP peut très bien fonctionner sans réécriture d’url.
Dans ce cas il faut mettre le DocumentRoot sur « app/webroot »
• CakePHP peut également très bien se mettre dans un dossier
indépendant.
Arborescence, architecture et
installation
Premier écran de CakePHP une fois les fichiers installés correctement
Arborescence, architecture et
installation
• Il faut remplacer le « salt », utilisé par le hashing
et le « cypher seed » utilisé pour l’encryption.
Vous pouvez aller à cette adresse pour obtenir les
bons codes:
http://www.sethcardoza.com/tools/random_password_generator/
• Il faut ensuite configurer la base de données dans
le fichier database.php. Il est possible de ne pas
avoir de DB en utilisant un DataSource
personnalisé qui ne pointe vers aucune base:
http://bakery.cakephp.org/articles/Primordial/2012/01/19/cakephp_v2_w
ithout_a_database_fixed
Les conventions de CakePHP
• Les noms de fichiers et de dossier sont généralement en CamelCase
sauf pour les fichiers de templates (vues).
• Les classes sont en CamelCase.
• Les modèles s’écrivent au singulier, il y a un modèle par table et ces
dernières n’ont qu’une clé primaire (en auto-incrément
généralement).
• Les contrôleurs s’écrivent au pluriel.
• Les actions s’écrivent en lowerCamelCase.
• Les dossiers des vues on les noms des Contrôleurs, donc au pluriel.
Les fichiers sont le nom des actions en minuscule traduit avec des
underscores.
• Les actions du back-office son précédées par « admin_ »
• Les noms de tables sont en minuscule et séparés par des
underscores.
Le Router
• La route par défaut de CakePHP est la suivante:
« /controler/action/param1:test/param2:test2 ».
• L’ensemble des routes se trouvent de le fichier
« app/Config/routes.php ».
• Toutes les routes peuvent être créés grâce à la méthode
« Router::connect() ».
• Le premier argument de « Router::connect() » est la chaine de
la route, elle contient des clés préfixées par « : », on peut
utiliser les wildcards « * » afin que le reste de l’url soit
considéré comme des paramètres de l’action.
• Dans le deuxième argument on définit les clés de la route.
• Dans le troisième argument on définit les options dont le
format des valeurs des clés.
Le Router
• Les clés « controller », « action » positionnent ces deux
paramètres.
Elles peuvent être fixées en dur dans le deuxième argument
s’ils n’apparaissent pas dans la chaine de la route.
• La clé « filter » permet de définir les paramètres nommées
autorisés, c’est-à-dire généralement les paramètres d’une
action.
• Le paramètre « admin » permet de créer des routes de
Backoffice et ne prend que les actions préfixées par
« admin_ ».
• Il est également possible de contrôler les paramètres
nommées avec « Router::connectNamed() » et d’y associer
des règles comme pour les paramètres normaux.
Le Router
• « Router::url » permet de faire du reverse
routing, c’est-à-dire regénérer l’url suivant ses
composantes.
• « Router::redirect » permet de mettre en place
des règles de redirection.
• « Router::mapResources » permet de définir un
contrôleur REST.
• « Router::parseExtentions » permet de définir les
formats qu’accepte l’application (html, rss, json,
xml, etc).
Le Router – La routeClass
• La routeClass, qui est définie dans les options de
« Router::connect() » permet de définir une
classe de routing particulière dans laquelle il sera
possible de faire tous les traitements voulus.
• Dans cette classe custom qui devra être insérée
avant le « Router::connect() », il y a deux
méthodes qui peuvent être implémentées:
– « parse() » appelé lorsqu’on envoie la requête HTTP
– « match() » appelé lorsqu’on fait l’inverse, c’est-à-dire
qu’on recompose l’url d’après ses paramètres.
La couche MVC
• Dans CakePHP, bien que dans la plupart des cas
un modèle, un contrôleur et une vue doivent être
ajoutées, le modèle et la vue ne sont pas
obligatoires.
• Pour ne pas avoir de vue on ajoute
« $this->autoRender = false; » dans le contrôleur.
• Pour ne pas avoir de modèle on initialise
l’attribut « uses » à null dans la classe contrôleur.
• On peut même avoir un modèle sans DataSource,
on utilise l’attribut « useTable » qu’on initialise à
false dans la classe modèle.
La couche MVC – Le modèle
• La classe de modèle hérite de AppModel.
• Le paramètre « primaryKey » permet de définir le nom
de la clé primaire de la table.
• Le paramètre « validate » permet d’ajouter des
validateurs sur chaque champ.
• Le paramètre « hasOne » permet de définir une
relation de type 1-1 -> 1-1. On y détermine notamment
la clé étrangère ou les conditions de relation.
A noter que si on a respecté les conventions de
nommage de CakePHP pour la clé étrangère(« tablecible_id »), il suffit uniquement d’ajouter le nom de la
table cible.
La couche MVC – Le modèle
• Le paramètre « belongsTo » permet de définir une relation
de type 0-n -> 1-1. Idem à « hasOne » sauf qu’on peut
définir l’ordre et la limite qui seront appliqués lors de la
jointure.
• Le paramètre « hasMany » permet de définir une relation
de type inverse,
c’est-à-dire 1-1 -> 0-n.
• Le paramètre « hasAndBelonsToMany » permet de définir
une relation de type 0-n -> 0-n, donc une association.
Dans ce cas la configuration contient les informations de la
table d’association en plus de la clés étrangère. Cela évite
de faire des modèles pour des associations.
La couche MVC – Le contrôleur
• Tous les contrôleurs de l’application héritent de
« AppConroller » qui hérite lui-même de « Controller ».
• Ainsi toutes les actions, attributs, callbacks, etc.
communs peuvent être mis dans « AppController ».
• Les méthodes du contrôleur sont les actions, pour
accéder à chaque action en passant des paramètres, il
suffit d’appeler :
« /controler/action/param1:test/param2:test2 »
• L’objet « request » contient toutes les informations de
la requête et les paramètres passés, il est obligatoire
de passer par cet objet.
La couche MVC – Le contrôleur
• L’argument « uses » permet d’ajouter un ou plusieurs modèles ou
librairies du dossier « Lib », l’argument « conponents » permet de
définir les composants qui seront utilisés, idem pour l’argument
« helpers » avec les helpers de vue.
• Chaque contrôleur dispose de 3 callbacks:
– « Controller::beforeFilter» qui est déclenché avant toute action,
– « Controller::beforeRender» qui est déclenché avant tout rendu,
– « Controller::afterFilter» qui est déclenché après toute action.
• La méthode « set » sert à affecter des valeurs à la vue, on lui passe
soit deux arguments clé et valeur soit un tableau de clés/valeurs.
• La méthode « render » permet de déclencher le rendu avec la vue
passée en paramètre.
Cette méthode est exécutée automatiquement avec la vue
logiquement associée dans l’arborescence.
La couche MVC – La vue
• Il s’agit de fichier avec l’extension *.ctp
• Des blocs et une hiérarchisation des vues qui en découle
peuvent être définis.
• Un bloc permet en d’autres termes de définir des zones
d’un Layout ou la vue parente dans la vue enfant.
• Les vues peuvent en étendre d’autres, par défaut les vues
étendent le Layout, mais ce principe peut être appliqué à
des vues grâce à la méthode « extend ».
• Le principal bloc est « content », il contient tout ce qui est
affiché dans la vue.
• Les blocs « script » et « css » sont liés au Helper HTML et à
ses méthodes. L’affectation du bloc peut être surchargée.
La couche MVC – La vue
• On peut définir d’autres blocs en encadrant leur code par
les méthodes « start » et « end » dans la vue.
• La méthode « fetch » dans la vue est un appel de bloc:
– « echo $this->fetch(‘content’); » appelle le bloc principal,
– « echo $this->fetch(‘sidebar’); » appelle un bloc sidebar défini
dans la vue fille,
– « echo $this->fetch(‘css’); » insère toutes les feuilles de styles
ajoutées avec le Helper Html :
« $this->Html->css('carousel', null, array('inline' => false)); »
la dernière option spécifie que les balises doivent être ajoutées
au bloc du même nom, ici il s’agit du bloc « css »,
– Il est possible d’ajouter les balises à un autre bloc:
« $this->Html->script('carousel', array('block' => 'scriptBottom')); ».
La couche MVC – La vue
• Il est possible de définir des thèmes avec l’attribut
« theme » dans le contrôleur. Les vues et les assets se
trouvent donc dans un dossier correspondant au nom du
thème.
• Il existe des vues Media qui permettent de rendre des
fichiers binaires. Cette vue sert principalement à servir des
fichiers qui nécessitent une authentification ou une
vérification particulière. Pour les utiliser il faut assigner le
paramètre « viewClass » à « Media » dans l’action du
contrôleur.
• Avec la clé « _serialize » dans la méthode « set » du
contrôleur, les données seront automatiquement
sérialisées dans le format demandé grâce à
« Router::parseExtensions() »
Le pattern ActiveRecord et le CRUD de
CakePHP
Représentation en digramme de classe du design ActiveRecord
Le pattern ActiveRecord et le CRUD de
CakePHP
• ActiveRecord est la représentation en classe d’une
table, ses attributs sont les champs et ses méthodes
permettent les différentes requêtes de sélection,
d’ajout ou de suppression.
• Lorsqu’on veut traiter plusieurs enregistrements, donc
plusieurs instances de classes ActiveRecord, il est
nécessaire d’avoir des Collections de ces instances pour
pouvoir les traiter.
• Il existe un lien très fort entre les données des l’objets
ActiveRecord et ceux de la base, l’enregistrement, la
ligne de la table est réellement un tuple, une copie de
l’objet.
Le pattern ActiveRecord et le CRUD de
CakePHP
• Le CRUD de CakePHP reprend de façon très
proche le patron ActiveRecord de Ruby on Rails.
• Cette implémentation diffère quelque peut du
design pattern initial présenté précédemment.
• Pour éviter de gérer des collections et des
instanciations issues des tuples de la table, la
couche modèle contient des assesseurs qui vont
retourner des tableaux simples.
• Il est d’ailleurs possible d’utiliser les assesseurs
sans ActiveRecord, c’est-à-dire sans que les
données soient représentées dans la classe.
Le pattern ActiveRecord et le CRUD de
CakePHP
• Les méthodes « set », « read » et « create »
permettent cependant de faire de l’ActiveRecord,
« read » permet de charger un enregistrement depuis
la base dans l’objet Modèle et « set » depuis le
contrôleur. Si un « save » sans paramètres est fait
ensuite, les données ajoutées dans l’objet seront
utilisées pour faire l’INSERT ou l’UPDATE. « create »
permet de réinitialiser les données de l’objet.
• L’ActiveRecord dans CakePHP ne concerne que les
enregistrements uniques car les modèles sont des
Singletons et sert surtout lors de l’enregistrement des
données.
Le pattern ActiveRecord et le CRUD de
CakePHP - Find
• La méthode « find » permet de rechercher des
enregistrements sans ActiveRecord:
–
–
–
–
« find(‘first’) récupère le premier enregistrement,
« find(‘count’) récupère le nombre de lignes,
« find(‘all’) récupère tous les enregistrements,
« find(‘list’) récupère tous les enregistrements sous forme
de tableaux simple dont les index sont les id,
– « find(‘threaded’) » récupère tous les enregistrements
sous forme de tableaux imbriqués, dans les clés
« children » se trouvent les données enfants, utile pour les
catégories hiérarchisées par exemple.
– « find(‘neighbors’) » récupère l’enregistrement précédent
et suivant du first, pratique pour les pagers next/prev.
Le pattern ActiveRecord et le CRUD de
CakePHP - Find
• Le deuxième paramètre, la « query », permet d’ajouter:
– les champs qui seront sélectionnés,
– les conditions,
– la récursivité; il s’agit de prendre les n tables associées. Pour ne
prendre que les données de la table la récursivité à valeur « -1 »,
pour prendre le premier niveau de tables liées, elle aura la
valeur « 0 », etc.
• On peut également utiliser les « Magic Find Types ». Ils vont
vous permettre de rechercher par un ou plusieurs champs
directement depuis l’appel de la méthode. Par exemple la
méthode « findAllByLastName(‘jack’) » va nous permettre
de chercher tous les enregistrement avec les champs
« last_name » « jack ». Il est possible de chercher sur
plusieurs champs avec les opérateurs « Or » ou « And ».
Le pattern ActiveRecord et le CRUD de
CakePHP - Find
• Il est possible de faire ses propres « find », tout
simplement en ajoutant des méthodes dans l’attribut
« findMethods » du modèle et de définir la méthode:
« protected _findMaMethode($state, $query, $result) ».
Les arguments sont:
– « state », « before » ou « after », définit si le traitement
concerne la « query » ou le « result ». Dans le premier cas
on retourne la « query » et elle est éxécutée, dans le
second on retourne le « result »,
– « query » est la requête demandée, le deuxième
paramètre du find,
– « result » est le résultat de la requête.
Le pattern ActiveRecord et le CRUD de
CakePHP - Save
• Avec le fonction d’enregistrement on peut tirer
partie de l’ActiveRecord avec « set() », « read() »
et « create() ».
• Si on initialise l’attribut « id » et qu’un save est
ensuite exécuté alors il s’agira d’un UPDATE. On
remarque ici que le mécanisme offert par
ActiveRecord est plutôt pratique.
• La méthode « save() » prend en premier
paramètre le tableau de données à sauvegarder,
si celui est null alors « save() » rentrera dans un
fonctionnement ActiveRecord.
Le pattern ActiveRecord et le CRUD de
CakePHP - Save
• Voici les autres méthodes d’enregistrement:
– « saveField() », enregistre uniquement un champ, il faut
initialiser l’id avant de lancer cette méthode,
– « updateAll() », enregistre plusieurs enregistrements en
fonction des conditions passées dans le 2ème paramètre,
– « saveMany() », enregistre plusieurs lignes en même temps, il
est possible d’activer les transactions avec « atomic » et/ou
enregistrer les données associées avec « deep », des options qui
peuvent être ajoutées en 2ème paramètre,
– « saveAssociated() », enregistre l’ensemble des données
imbriquées, la méthode dispose des même options que
saveMany() mais son option « deep » est plus forte car elle peut
enregistrer toutes les données imbriquées et pas seulement les
données associées,
– « saveAll() » est un Wrapper de « saveMany() » et
« saveAssociated() ».
Le pattern ActiveRecord et le CRUD de
CakePHP - Delete
• La méthode « delete() » va supprimer l’enregistrement
ayant l’id précisé en premier argument. « delete() »
fonctionne également en ActiveRecord et peut
supprimer la donnée active si on ne lui précise pas de
paramètre.
Le 2ème paramètre, s’il est à « true » va activer la
cascade, c’est-à-dire que toutes les données
imbriquées vont être également supprimées, cela évite
d’avoir des fantômes en base de données.
• Une méthode « deleteAll() » existe aussi, au lieu de
prendre l’id en paramètre elle prend un condition.
Objets, Collections et Evénements
• Cette partie va aborder l’architecture interne de
CakePHP afin de comprendre ses principaux
mécanismes et voir comment en utiliser certains
dans nos applications.
• L’Object est un élément de base CakePHP dont
beaucoup de composants héritent comme la
classe Controler, Model ou View.
• Ces trois classes MVC sont des Singletons, elles
ne sont donc instanciées qu’une seule fois lors de
l’exécution d’une requête serveur.
Objets, Collections et Evénements
• D’autres composants CakePHP comme le Behavior ou
le Component peuvent avoir plusieurs instances, leurs
Factories sont les Collections ou plutôt même des
« ObjectCollection ». C’est-à-dire que ce sont ces
classes de Collection qui s’occupent d’y accéder.
• Toute Collection peut être chargée avec « load() » ou
déchargée avec « unload() ».
• On peut également déclencher manuellement tous les
callbacks sur une collection grâce à « trigger() ».
• Les callbacks d’un élément d’une Collection peuvent
être désactivés avec « disable() » et réactivée avec
« enable() ».
Objets, Collections et Evénements
Représentation en digramme de classe des Collections CakePHP
Objets, Collections et Evénements
• Cela leur permet d’avoir tous un système de
callbacks (vu précédemment) et
accessoirement de pouvoir déclencher ou
« trigguer » un certain nombre d’événements.
• Le déclenchement et la création d’événements
permet notamment de garder un minimum de
couplage entre les classes de CakePHP qui
interagissent.
Objets, Collections et Evénements
• La plupart des composants visibles, que ce soit
des Singletons ou des Collections implémentent
une Interface d’écouteur d’événements
(Observer), « CakeEventListener ».
Le rôle d’un écouteur est d’implémenter la
méthode « implemetedEvents » qui est rien que
la liste des événements écoutés avec leurs
Callbacks.
• Il est tout a fait possible d’utiliser ce mécanisme
dans nos propres classes, notamment dans les
Plugins qui nécessitent une vraie indépendance.
Objets, Collections et Evénements
• On pourra propager n’importe où dans le code un
événement grâce au gestionnaire d’événements
« CakeEventManager ».
A noter qu’on peut également attacher un
Callback particulier lors du déclenchement.
• On pourra attacher un écouteur d’événement
(action de Dispatch) à un autre endroit du code,
on créera ainsi un Hook.
• Comme n’importe quels Hooks il est également
possible de définir leur priorité dans CakePHP.
Les exceptions
• CakePHP possède une liste de classes d’Exceptions issues
de CakeException.
• Il est possible de créer ses propre classes d’Exception en les
faisant hériter de CakeException.
• CakePHP Try l’ensemble du code et a son propre Handler
pour gérer les exceptions.
• Pour rester dans cette logique et si on désire faire un
traitement particulier des exceptions il est possible de faire
son propre Handler:
« Configure::write('Exception.handler', 'AppExceptionHandler::handle');»
• De la même façon on peut uniquement personnaliser le
Renderer, c’est-à-dire les messages affichés:
« Configure::write('Exception.renderer', 'AppExceptionHandler::handle');»
Les librairies intégrées
• Nous n’allons pas énumérer toutes les libraires mais
uniquement celles qui vous permettrons
d’architecturer votre code et celles incontournables en
terme de fonctionnalités.
• Les Paradigmes d’architectures: Component, Element,
Helper, Behavior, Plugin. Il est également possible
d’avoir des librairies de code sans architecture
particulière, elle s’ajouteront dans le dossier « Lib ».
• Les librairies utiles: Authentification, ACL, Translate,
Security, Email, Cache, Form, Paginator et Containable.
Les librairies intégrées –
Component (composant):
• Son but est de factoriser du code entre plusieurs
Contrôleurs, on peut le voir comme une librairie de
traitement qui leur est destinée.
• Un Component se charge grâce à l’attribut
« components » ajouté dans le contrôleur.
• Il existe des Components intégrés mais il est tout à fait
possible d’en créer des nouveaux.
• Un Component implémente l’écouteur d’événements, il
est donc pourvu de callbacks comme le contrôleur.
• Au lieu d’avoir un callback « beforeFilter() » il a
« startup() » qui est appelé entre le « beforeFilter() »
du contrôleur et l’exécution de l’action.
Les librairies intégrées –
Element (élément)
• Un Element permet de factoriser du code de vue très
simplement.
• Il s’agit d’une mini-vue auquel on va transmettre des
variables.
• On utilise les Elements en lieu et place des blocs pour
principalement 2 raisons:
– lorsqu’il s’agit de quelque chose de très récurent et de
plutôt général, qu’on pourrait réutiliser dans un autre
projet,
– lorsqu’on veut un bloc « cachable », un Element peut
effectivement prendre en compte des options de caching.
Les librairies intégrées –
Helper (assistant)
• Le Helper est à la vue ce qu’est le Conponent au contrôleur.
• Il permet de factoriser du code de vue mais est
généralement destiné aux opérations plus complexes et se
structure en module. Il s’agit généralement d’une boite à
outil proposant un panel d’assistants sur un objet
particulier. On va par exemple avoir un Helper de
formulaires qui va nous offrir toutes les méthodes pour
construire un form HTML.
• Le Helper dispose de callbacks particuliers ciblés sur le
rendering.
• L’utilisation d’un Helper se déclare dans le contrôleur grâce
à l’attribut « helpers ».
Les librairies intégrées –
Behavior (comportement)
• Le Behavior est au modèle ce qu’est le Conponent au
contrôleur.
• Un Behavior implémente l’écouteur d’événements, il
est donc pourvu de callbacks comme le Component.
• Les callbacks sont liées aux actions sur les données:
–
–
–
–
–
« beforeValidate() »
« beforeFind() » / « afterFind() »
« beforeSave() » / « afterSave() »
« beforeDelete() » / « afterDelete() »
« setup() » / « cleanup() »: ces hooks sont déclenchés lors
de l’attachement / détachement au modèle.
• Les behaviors s’attachent au modèle grâce à l’attribut
« actsAs ».
Les librairies intégrées –
Plugin (greffon)
• Un Plugin est un module complet indépendant, reprenant
l’architecture d’une application et utilisant les mêmes Paradigmes
que cette dernière.
• Un Plugin est comparable à un module dans Zend.
• Un Plugin se charge dans le bootstrap (dans « Config ») grâce à
« CakePlugin::load() »
• Un Plugin peut également avoir ses propres routes dans son dossier
« Config ».
• Il peut également avoir son propre bootstrap pour initialiser les
composants dont il a besoin.
• Pour charger les routes et le bootstrap du plugin dans l’application:
CakePlugin::load(myPlugin', array('bootstrap' => true, 'routes' => true));
-> A noter qu’un tableau de nom de fichiers peut être passés à la place du
booléen.
Les librairies intégrées –
Authentification
• Il s’agit d’un Meta Component « AuthComponent » (Ce
composant utilise d’autres classes spécifiques, d’où le
terme « Meta »).
– Le composant gère uniquement la couche métier de
l’authentification, il utilise le modèle, le contrôleur et les
vues « User » de l’application.
– Le composant gère les méthodes de connexion Basics et
Digests pour les services.
– Pour l’authentification en mode Digest, une méthode
statique « password() » de la classe « DigestAuthenticate »
permet de générer le Hash (clé).
– La connexion n’est pas automatique, elle se fait grâce à la
méthode « login() » du composant.
Les librairies intégrées – ACL
• Il s’agit d’un Behavior de modèle et il permet de gérer les
listes de contrôle d’accès.
• Il s’agit donc d’une couche de contrôle qui va vérifier les
accès aux ressources de données.
• Il y a trois acteurs dans une stratégie ACL:
– les AROs - Access Role Object, les rôles,
– les ACOs – Access Controm Object, les ressources,
– les AROsACOs – les permissions.
• CakePHP permet de gérer ces 3 notions soit:
– en bases avec 3 tables différentes (pouvant être générées avec
les outils de Console),
– en fichier INI,
– dans la configuration générale avec l’objet de configuration.
Les librairies intégrées - ACL
• Un Behavior de type ARO peut être attaché à
un modèle de la façon suivante (sur un
modèle User par exemple):
« public $actsAs = array('Acl' => array('type' => 'requester')); »
• Un Behavior de type ACO peut également être
attaché à un modèle de la façon suivante (sur
un modèle Post par exemple):
« public $actsAs = array('Acl' => array('type' => controlled')); »
• Il peut être les deux avec le type « both ».
Les librairies intégrées - ACL
• Chaque modèle doit être qui intègre le
Behavior ACL doit avoir une méthode
« parentNode() ».
• Cette méthode sert à construire une stratégie
hiérarchique d’ARO ou d’ACO, on doit y
retourner le nom du node parent.
• Dans le cas d’une stratégie simple, on fait
retourner « null » à cette méthode.
Les librairies intégrées - Translate
• En plus d’intégrer gettext (fonction « __() ») et
l’internationalisation basé sur les locales,
CakePHP propose le Behavior Translate.
• Une fois le comportement attaché au Modèle et
la table de traduction créée (grâce à l’outil
Console), certains champs pourront être définis
comme devant être traduits, par exemple:
« public $actsAs = array( 'Translate' => array( 'fieldOne', 'fieldTwo') ); »
• Le Behavior se base sur la locale globale définie
dans le Bootstrap. Elle peut être surchargée grâce
à l’attribut « locale » du modèle.
Les librairies intégrées - Security
• Security est un Component.
• Il permet de parer efficacement et simplement un ces failles connues et
identifiées:
– le Cross-Site Request Forgery – avec un système de jeton temporaire
(Nécessite l’utilisation du Form Helper),
– la falsification de formulaires – en injectant des données cachées avant le
POST et en vérifiant leur intégrité à la soumission (Nécessite l’utilisation du
Form Helper),
• Et permet certaines restrictions comme:
– celle d’être en SSL,
– celle d’accepter que certaines méthodes HTTP,
– et la limitation des communications croisée dans le contrôleur.
• Security permet également de gérer les exceptions de sécurité grâce à un
Black Hole.
• A noter que dés son activation la protection contre les CSRF et les
falsifications de formulaires sont actives (avec le Form Helper).
Les librairies intégrées - CakeEmail
• Remplace le Component Email dans la version 2.x.
• Il s’agit d’une librairie plus indépendante qui peut être utilisée aussi
bien dans un contrôleur ou dans un composant mais également
dans un modèle.
• La librairie peut se configurer à n’importe quel moment, cependant
il existe une classe « EmailConfig » dans le dossier « Config ». Ses
attributs sont les différentes configurations qui pourront être
utilisées.
• Il est notamment très facile de configurer un Transport SMTP pour
envoyer un mail via un compte Google par exemple.
• Il est également possible de créer des Transports spécifiques en
étendant la classe abstraite « AbstractTransport » et en
implémentant la méthode « send() ».
Les librairies intégrées - CakeEmail
• Il est possible de créer des templates pour les mails:
– On utilise le dossier « Email » de « View » pour mettre le vues,
– On dépose les gabarits dans « Layout/Email » de « View ».
• Pour attacher un template à un email il suffit d’utiliser la
méthode « template() » de l’objet instance de CakeEmail.
Le premier argument est sa vue, le second son gabarit.
• Le format peut également être défini grâce à la méthode
« emailFormat() ». On peut utiliser le format texte, HTML
ou les deux.
Dans ce cas les fichiers de rendus se trouvent dans les sousdossiers « text » et « html ».
• Pour passer des variables aux templates la méthode
« viewVars() » est nécessaire.
Les librairies intégrées - Cache
• Il s’agit d’une librairie commune, elle peut être utilisée
aussi bien dans un contrôleur que dans un modèle.
• Plusieurs moteurs de cache peuvent être utilisées
comme: File, Apc, Wincache (IIS), Xcache, Memcache,
REDIS.
• Plusieurs politiques de caching peuvent être définies
grâce à la méthode statique « Cache::config ».
• Il est également possible de créer des moteurs de
cache personnalisées en étendant « CacheEngine » et
en implémentant plusieurs méthodes abstraites
comme « write() », « read() » ou « clear() ».
Les librairies intégrées - Cache
• Il existe principalement deux types de cache, du cache requête ou
du cache de rendu.
• Pour du cache requête, les options de cache peuvent être activé
dans chaque « find »:
« find('list', array('cache' => 'countryList', 'cacheConfig' => 'long')); »
• Cela peut également se faire manuellement pour des requêtes
spécifiques du modèle avec les méthodes « read() » et « write() ».
• Pour le cache de rendu, on utilisera le Helper CacheHelper.
• Grâce à l’attribut « cacheAction », il est possible de définir la liste
des actions dont les rendus seront cachés.
• Il est ensuite possible de ne pas activer le cache pour certaines
zones grâce aux commentaires « <!--nocache--> <!--/nocache--> »
Les librairies intégrées - Cache
• Il existe principalement deux types de cache, du
cache requête ou du cache de rendu.
• Pour du cache requête, les options de cache
peuvent être activé dans chaque « find »:
« find('list', array('cache' => 'countryList', 'cacheConfig' => 'long')); »
• Cela peut se faire manuellement pour des
requêtes spécifiques du modèle avec les
méthodes « read() » et « write() ».
• Les éléments de vue (Element), peuvent
également avoir du cache.
Les librairies intégrées - Form
• L’outil Form est un Helper de vue.
• Il permet de créer des formulaires HTML de manière uniforme et
permet de gérer automatiquement certaines fonctionnalités de
CakePHP comme certaines politiques de sécurité (Component
Security).
• Par rapport à ZendForm, le Helper CakePHP prend le parti de ne
gérer que le code HTML de chaque champs, ce qui en fait un outil
plus simple à manier car sans Decorator.
• FormHelper gère également les validations définies dans le modèle
et permet de d’afficher une erreur sur un champs grâce à sa
méthode « error() », le premier argument est le nom du champs.
• L’erreur est affichée par défaut dans le cas où on utilise des
« inputs ».
Les librairies intégrées – Paginator
• Paginator est un Component (PaginatorComponent) et un
Helper (PaginatorHelper).
• Dans le contrôleur, une fois le Component attaché, on va
définir les jeux de pagination avec l’attribut « paginate ».
Ces jeux seront composés des ressources concernées, du
nombre d’ éléments par page de chacune d’elle et d’un
ensemble de paramètres comme l’odre ou les conditions.
• Une fois les jeux définis, il suffira d’utiliser la méthode
« paginate() » du contrôleur au lieu de « find() » du
modèle: « $this->paginate('Recipe'); ».
En deuxième paramètre il est tout a fait possible de passer
un tableau de conditions, limites, etc qui surchargera ce qui
a été défini dans les jeux.
Les librairies intégrées – Paginator
• Le Helper lui va se concentrer sur la génération HTML du pager.
• Il possible de générer plusieurs types de pager:
– « sort() » - permet de créer un lien de tri, pratique pour ordonner des
colonnes dans un BO,
– « numbers() » - créé un pager composé de nombres, il prend
beaucoup d’options et permet d’ailleurs de gérer m’ellipsis c’est-à-dire
les ‘…’ entre les nombres dans les cas avec des résultats importants,
– « prev() », « next() », « first() », « last() », « current() » - pour les liens
de sauts.
• Les paramètres nommés « page », « dir » et « sort » seront utilisés
pour la pagination.
• Il est possible de passer d’autres paramètres où une Querystring
dans le Component afin de garder d’autres paramètres durant la
pagination. Le Helper prendra automatiquement en compte ces
paramètres additifs.
Les librairies intégrées – Containable
• Containable est un Behavior.
• Avec le CRUD de CakePHP, il est possible d’avoir
beaucoup de données d’association, bien que cela soit
très utile il en reste que cette masse de données peut
poser des problèmes de performances.
• Containable sert à limiter relativement simplement la
profondeur et la somme de données requêtées.
• Un appel d’un « contain() » sans paramètre sur la
ressource, avant le « find() », va limiter la requête sur
la ressource. Cela équivaut à mettre un « recursive » à
« -1 »
Les librairies intégrées – Containable
• Containable va également nous permettre de
pouvoir conditionner sur les tables associées:
« $this->Post->contain('Comment.author = "Daniel"'); »
Ici, bien que la ressource soit « Post », on peut
émettre une condition sur un champs « author »
qui n’appartient qu’à la table de commentaires.
• Il est possible d’ajouter une option « contain »
directement dans le « find() » au lieu de le définir
avant.
• L’option « contain » est également disponible
dans le Component Paginator.
La Console et la Bakery
• Un ensemble d’outils Core sont prévus dans un script
shell « sh app/Console/cake » ou
« app\Console\cake.bat » sur Windows.
• Un ensemble de fonctionnalités sont alors proposées
comme « acl », « api », « i18n », « upgrade », etc.
• Ces commandes vous permettrons de créer des
architectures en base de données, de générer du code,
de la doc ou bien de faire des mises à jour de CakePHP
ou de ses Plugins officiels.
• Pour accéder à une commande il suffit de taper:
« app\Console\cake.bat command args».
La Console et la Bakery
Menu présentant les différentes commandes de la console CakePHP
La Console et la Bakery
• Il est également possible d’ajouter nos propres
routines, elles seront alors automatiquement visibles
dans le menu.
• Il suffit alors d’ajouter un fichier de classe dans le
dossier « app/Console/Command ». La classe héritera
de « AppShell », sa méthode « main() » sera la
commande par défaut et ses autres méthodes seront
les sous-commandes:
« app/Console/cake.bat my-command my-sub-command my-arg»
• Vous pourrez ajouter des Task (Tâches) dans le dossier
« app/Console/Command/Task/ ».
Il s’agit de librairies destinées aux scripts console
comme sont les Components aux contrôleurs.
La Console et la Bakery
• Une tâche est une classe qui hérite de « Shell » et qui a
au moins une méthode qui s’appelle « execute() ».
• Il est possible d’invoquer d’autres Shell grâce à la
méthode « dispatchShell ».
• Vous pourrez afficher des informations grâce à la
méthode « out() » et gérer son niveau de verbosité
(« QUIET », « NORMAL », « VERBOSE »).
• Des styles peuvent être ajoutés sous forme de balise:
« $this->out(‘<warning>Pay attention</warning>’); ».
• Ces styles sont prédéfinis mais il est possible d’en ajouter
avec la méthode « styles() » de l’objet « stdout » du shell.
La Console et la Bakery
• Afin de pouvoir gérer les arguments et les options des
commandes nous avons à dispositions les méthodes
« addArguments() » et « addOptions() ».
• Les arguments sont des valeurs ajoutées à la suite, les
options ne sont souvent pas obligatoires et nécessitent un
nom, comme « -p password ».
• Ces méthodes vont nous permettre de configurer les
entrées, c’est-à-dire:
–
–
–
–
–
Leur message d’aide,
Si elle sont requises ou pas,
Leurs différentes valeurs (yes/no par exemple),
Leur valeur par défaut,
Un nom d’option pour cette dernière.
La Console et la Bakery
• Si vous désirez lancer des scripts console en
CRON il faudra créer un script Shell qui
positionnera les PATH du PHP CLI et de la
Console CakePHP.
Un exemple est donné dans le CookBook:
http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html
La Console et la Bakery
• La Bakery est une commande Core de la console
« cake », positionné à la racine, il suffit d’exécuter cette
commande:
« app\Console\cake.bat bake ».
• Sa principale fonction va être de générer:
–
–
–
–
–
–
–
le fichier de configuration de la base,
les modèles et les validateurs,
les contrôleurs et les contrôleurs d’admin,
les vues,
les fixtures (données de test),
les classes de tests unitaires,
les fichiers de base d’un nouveau Plugin.
La Console et la Bakery
• Une dernière option « project » permet de
notamment spécifier une architecture
d’application différente. On le fait avec
l’option « --skel » (skeletor):
« app\Console\cake.bat bake project --skel
app\Console\Templates\skel ».
• Vous pourrez également modifier le code
généré par la Bakery en ajoutant des
Templates de contrôleur/modèle/vues dans
« app/Console/Templates/my-template ».
La Console et la Bakery
La Bakery – Exemple de génération des modèles
Le Scaffolding
• CakePHP offre la possibilité d’avoir un espace
d’administration très rapidement, dés la fin de la
conception DB.
• Scaffold veut dire échafaudage, il s’agit donc là d’avoir
un outil temporaire dans l’élaboration du projet. Cet
outil là sert à saisir les données.
• Pour activer le Scaffold il suffit d’ajouter un attribut
« scaffold » dans le contrôleur.
• Si on désire avoir un Scaffold admin:
– Il faut activer le routing admin dans la configuration:
« Configure::write('Routing.prefixes', array('admin')); »
– Puis affecter la valeur « admin » à l’attribut « scaffold »
Le Scaffolding
• Il est possible de surcharger les actions du
Scaffolding en déclarant la méthode concernée. Si
on désire surchargée la vue liste, il suffit d’ajouter
la méthode « admin_list() » dans le contrôleur.
• On peut également surcharger les vues afin
d’avoir des rendus personnalisés, avec Bootstrap
de twitter par exemple. On peut surcharger par
contrôleur ou pour tous les contrôleurs.
• Il n’est cependant pas conseillé de trop surchargé
car cela reviendrait à faire un BO spécifique et
cela n’est pas le but du Scaffold.

similar documents