En exemple de travail à partir de la section Comment Utiliser des Plugins,
commençons par créer le plugin ContactManager
référencé ci-dessus. Pour commencer, nous allons définir la structure basique
du répertoire. Cela devrait ressembler à ceci:
Notez que le nom du dossier du plugin, “ContactManager”. Il est important
que ce dossier ait le même nom que le plugin.
Dans le dossier plugin, vous remarquerez qu’il ressemble beaucoup à une
application CakePHP, et c’est au fond ce que c’est. Vous n’avez à inclure
aucun de vos dossiers si vous ne les utilisez pas. Certains plugins peuvent
ne contenir qu’un Component ou un Behavior, et dans certains cas, ils peuvent
carrément ne pas avoir de répertoire “View”.
Un plugin peut aussi avoir tous les autres répertoires que votre application a,
comme Config, Console, Lib, webroot, etc…
Note
Si vous voulez être capable d’accéder à votre plugin avec une URL, vous
devrez définir un AppController et un AppModel pour le plugin. Ces deux
classes spéciales sont nommées d’après le plugin, et étendent les
AppController et AppModel de notre application parente. Voilà à quoi cela
devrait ressembler pour notre exemple de ContactManager:
Consultez le chapitre
Génération de code avec Bake si vous avez le moindre
problème avec l’utilisation de la ligne de commande.
Avertissement
Les Plugins ne fonctionnent pas en namespace pour séparer le code.
A cause du manque de namespaces de PHP dans les versions plus vieilles, vous
ne pouvez pas avoir la même classe ou le même nom de fichier dans vos
plugins. Même si il s’agit de deux plugins différents. Donc utilisez des
classes et des noms de fichier uniques, en préfixant si possible la classe
et le nom de fichier par le nom du plugin.
Les controllers pour notre plugin ContactManager seront stockés dans
/app/Plugin/ContactManager/Controller/. Puisque la principale chose que
nous souhaitons faire est la gestion des contacts, nous aurons besoin de créer
un ContactsController pour ce plugin.
Ainsi, nous mettons notre nouveau ContactsController dans
/app/Plugin/ContactManager/Controller et il ressemblerait à cela:
Ce controller étend AppController du plugin (appelé
ContactManagerAppController) plutôt que l’AppController de l’application
parente.
Notez aussi comment le nom du model est préfixé avec le nom du plugin.
C’est nécessaire pour faire la différence entre les models dans les
plugins et les models dans l’application principale.
Dans ce cas, le tableau $uses ne serait pas nécessaire comme dans
ContactManager. Contact sera le model par défaut pour ce controller,
cependant, il est inclu pour démontrer comment faire préceder proprement
le nom du plugin.
Si vous souhaitez accéder à ce que nous avons obtenu jusqu’à présent, visitez
/contact_manager/contacts. Vous devriez obtenir une erreur « Missing Model »
parce que nous n’avons pas un model Contact déjà défini.
Les Models pour le plugin sont stockés dans /app/Plugin/ContactManager/Model.
Nous avons déjà défini un ContactsController pour ce plugin, donc créons le
model pour ce controller, appelé Contact:
Visiter /contact_manager/contacts maintenant (Etant donné, que vous avez une
table dans votre base de données appelée “contacts”) devrait nous donner une
erreur « Missing View ».
Créons la ensuite.
Note
Si vous avez besoin de réferencer un model dans votre plugin, vous avez
besoin d’inclure le nom du plugin avec le nom du model, séparé d’un
point.
Les Vues se comportent exactement comme elles le font dans les applications
normales. Placez-les juste dans le bon dossier à l’intérieur du dossier
/app/Plugin/[PluginName]/View/. Pour notre plugin ContactManager, nous aurons
besoin d’une vue pour notre action ContactsController::index(), ainsi incluons
ceci aussi:
Pour des informations sur la façon d’utiliser les elements à partir d’un
plugin, regardez Elements.
Redéfinition des vues de plugin à partir de l’intérieur de votre application¶
Vous pouvez redéfinir toutes les vues du plugin à partir de l’intérieur de
votre app en utilisant des chemins spéciaux. Si vous avez un plugin appelé
“ContactManager”, vous pouvez redéfinir les fichiers de vue du plugin avec
une logique de vue de l’application plus spécifique, en créant des fichiers en
utilisant le template suivant
« app/View/Plugin/[Plugin]/[Controller]/[view].ctp ». Pour le controller
Contacts, vous pouvez faire le fichier suivant:
Les assets web du plugin (mais pas les fichiers de PHP) peuvent être servis
à travers le répertoire “webroot” du plugin, tout comme les assets de
l’application principale:
Vous pouvez mettre tout type de fichier dans tout répertoire, juste comme
un webroot habituel.
Mais garder à l’esprit que la gestion des assets statiques, comme les images,
le Javascript et les fichiers CSS des plugins à travers le Dispatcher est
incroyablement inefficace. Il est grandement recommandé de les symlinker pour
la production.
Par exemple comme ceci:
Faîtes précéder simplement /nom_plugin/ pour le début d’une requête pour
un asset dans ce plugin, et cela fonctionnera comme si l’asset était dans le
webroot de votre application.
Par exemple, lier le “/contact_manager/js/some_file.js”
servira l’asset
“app/Plugin/ContactManager/webroot/js/some_file.js”.
Note
Il est important de noter le préfixe /votre_plugin/ avant le
chemin de l’asset. Et la magie opére!
Modifié dans la version 2.1: Utilisez la syntaxe de plugin pour accéder aux assets. Par exemple
dans votre View:
Un plugin peut avoir des Components, Helpers et Behaviors tout comme
une application CakePHP classique. Vous pouvez soit créer des plugins
qui sont composés seulement de Components, Helpers ou Behaviors ce qui
peut être une bonne façon de construire des Components réutilisables
qui peuvent être facilement déplacés dans tout projet.
Construire ces components est exactement la même chose que de les construire
à l’intérieur d’une application habituelle, avec aucune convention spéciale
de nommage.
Faire référence avec votre component, depuis l’intérieur ou l’extérieur de
votre plugin nécessite seulement que vous préfixiez le nom du plugin avant le
nom du component. Par exemple:
// Component défini dans le plugin 'ContactManager'classExampleComponentextendsComponent{}// dans vos controllers:public$components=array('ContactManager.Example');
La même technique s’applique aux Helpers et aux Behaviors.
Note
À la création de Helpers, vous verrez que AppHelper n’est pas
automatiquement disponible. Vous pouvez déclarer les ressources dont vous
avez besoin avec les uses:
// Déclarez le use de AppHelper pour le Helper de votre PluginApp::uses('AppHelper','View/Helper');
Cet exemple est un bon début pour un plugin, mais il y a beaucoup plus
à faire. En règle général, tout ce que vous pouvez faire avec votre
application, vous pouvez le faire à l’intérieur d’un plugin à la place.
Continuez, incluez certaines librairies tierces dans “Vendor”, ajoutez
de nouveaux shells à la console de cake, et n’oubliez pas de créer des cas
de test ainsi les utilisateurs de votre plugin peuvent automatiquement tester
les fonctionnalités de votre plugin!
Dans notre exemple ContactManager, nous pourrions créer des actions
add/remove/edit/delete dans le ContactsController, intégrer la validation
dans le model Contact, et intégrer la fonctionnalité à laquelle on
pourrait s’attendre quand on gère ses contacts. A vous de décider ce qu’il
faut intégrer dans vos plugins. N’oubliez juste pas de partager votre code
avec la communauté afin que tout le monde puisse bénéficier de votre
component génial et réutilisable!
Une fois qu’un plugin a été installé dans /app/Plugin/, vous pouvez y accéder
à l’URL /nom_plugin/nom_controller/action. Dans notre exemple de plugin
ContactManager, nous accédons à notre ContactsController à l’adresse
/contact_manager/contacts.
Quelques astuces de fin lorsque vous travaillez avec les plugins dans vos
applications CakePHP:
Si vous n’avez pas un [Plugin]AppController et
[Plugin]AppModel, vous aurez des erreurs de type get missing Controller
lorsque vous essayez d’accéder à un controller d’un plugin.
Vous pouvez définir vos propres layouts pour les plugins, dans le dossier
app/Plugin/[Plugin]/View/Layouts. Sinon, les plugins utiliseront les
layouts du dossier /app/View/Layouts par défaut.
Vous pouvez établir une communication inter-plugin en utilisant
$this->requestAction('/plugin_name/controller_name/action'); dans vos
controllers.
Si vous utilisez requestAction, assurez-vous que les noms des controllers
et des models sont aussi uniques que possibles. Sinon, vous aurez des
erreurs PHP de type « redefined class … ».
Quand vous ajoutez des routes avec des extensions à votre plugin,
assurez-vous d’utilisez Router::setExtensions() pour ne pas devoir
surcharger le routing de l’application.
Aussi, vous pouvez créer un fichier composer.json et publier votre plugin
sur packagist.org.
De cette façon, il peut être facilement utilisé avec Composer.
Choisissez un nom de package avec une sémantique qui a du sens. Il devra
idéalement être préfixé avec la dépendance, dans ce cas « cakephp » comme le
framework.
Le nom de vendor sera habituellement votre nom d’utilisateur sous GitHub.
N’utilisez pas le namespace CakePHP (cakephp) puisqu’il est reservé
aux plugins appartenant à CakePHP.
La convention est d’utiliser les lettres en minuscule et les tirets en
séparateur.
Donc si vous créez un plugin « Logging » avec votre compte GitHub « FooBar », un
bon nom serait foo-bar/cakephp-logging.
Et le plugin « Localized » appartenant à CakePHP peut être trouvé dans
cakephp/localized.
Comment Créer des Plugins¶
En exemple de travail à partir de la section Comment Utiliser des Plugins, commençons par créer le plugin ContactManager référencé ci-dessus. Pour commencer, nous allons définir la structure basique du répertoire. Cela devrait ressembler à ceci:
Notez que le nom du dossier du plugin, “ContactManager”. Il est important que ce dossier ait le même nom que le plugin.
Dans le dossier plugin, vous remarquerez qu’il ressemble beaucoup à une application CakePHP, et c’est au fond ce que c’est. Vous n’avez à inclure aucun de vos dossiers si vous ne les utilisez pas. Certains plugins peuvent ne contenir qu’un Component ou un Behavior, et dans certains cas, ils peuvent carrément ne pas avoir de répertoire “View”.
Un plugin peut aussi avoir tous les autres répertoires que votre application a, comme Config, Console, Lib, webroot, etc…
Note
Si vous voulez être capable d’accéder à votre plugin avec une URL, vous devrez définir un AppController et un AppModel pour le plugin. Ces deux classes spéciales sont nommées d’après le plugin, et étendent les AppController et AppModel de notre application parente. Voilà à quoi cela devrait ressembler pour notre exemple de ContactManager:
Si vous oubliez de définir ces classes spéciales, CakePHP vous donnera des erreurs « Missing Controller » jusqu’à ce que ce soit fait.
Notez que le processus de création de plugins peut être simplifié en utilisant le shell de CakePHP.
Pour cuisiner un plugin, utilisez la commande suivante:
Maintenant vous pouvez cuisiner en utilisant les mêmes conventions qui s’appliquent au reste de votre app. Par exemple - baking controllers:
Consultez le chapitre Génération de code avec Bake si vous avez le moindre problème avec l’utilisation de la ligne de commande.
Avertissement
Les Plugins ne fonctionnent pas en namespace pour séparer le code. A cause du manque de namespaces de PHP dans les versions plus vieilles, vous ne pouvez pas avoir la même classe ou le même nom de fichier dans vos plugins. Même si il s’agit de deux plugins différents. Donc utilisez des classes et des noms de fichier uniques, en préfixant si possible la classe et le nom de fichier par le nom du plugin.
Controllers du Plugin¶
Les controllers pour notre plugin ContactManager seront stockés dans /app/Plugin/ContactManager/Controller/. Puisque la principale chose que nous souhaitons faire est la gestion des contacts, nous aurons besoin de créer un ContactsController pour ce plugin.
Ainsi, nous mettons notre nouveau ContactsController dans /app/Plugin/ContactManager/Controller et il ressemblerait à cela:
Note
Ce controller étend AppController du plugin (appelé ContactManagerAppController) plutôt que l’AppController de l’application parente.
Notez aussi comment le nom du model est préfixé avec le nom du plugin. C’est nécessaire pour faire la différence entre les models dans les plugins et les models dans l’application principale.
Dans ce cas, le tableau $uses ne serait pas nécessaire comme dans ContactManager. Contact sera le model par défaut pour ce controller, cependant, il est inclu pour démontrer comment faire préceder proprement le nom du plugin.
Si vous souhaitez accéder à ce que nous avons obtenu jusqu’à présent, visitez /contact_manager/contacts. Vous devriez obtenir une erreur « Missing Model » parce que nous n’avons pas un model Contact déjà défini.
Models du Plugin¶
Les Models pour le plugin sont stockés dans /app/Plugin/ContactManager/Model. Nous avons déjà défini un ContactsController pour ce plugin, donc créons le model pour ce controller, appelé Contact:
Visiter /contact_manager/contacts maintenant (Etant donné, que vous avez une table dans votre base de données appelée “contacts”) devrait nous donner une erreur « Missing View ». Créons la ensuite.
Note
Si vous avez besoin de réferencer un model dans votre plugin, vous avez besoin d’inclure le nom du plugin avec le nom du model, séparé d’un point.
Par exemple:
Si vous préférez que les clés du tableau pour l’association n’aient pas le préfixe du plugin sur eux, utilisez la syntaxe alternative:
Vues du Plugin¶
Les Vues se comportent exactement comme elles le font dans les applications normales. Placez-les juste dans le bon dossier à l’intérieur du dossier /app/Plugin/[PluginName]/View/. Pour notre plugin ContactManager, nous aurons besoin d’une vue pour notre action ContactsController::index(), ainsi incluons ceci aussi:
Note
Pour des informations sur la façon d’utiliser les elements à partir d’un plugin, regardez Elements.
Redéfinition des vues de plugin à partir de l’intérieur de votre application¶
Vous pouvez redéfinir toutes les vues du plugin à partir de l’intérieur de votre app en utilisant des chemins spéciaux. Si vous avez un plugin appelé “ContactManager”, vous pouvez redéfinir les fichiers de vue du plugin avec une logique de vue de l’application plus spécifique, en créant des fichiers en utilisant le template suivant « app/View/Plugin/[Plugin]/[Controller]/[view].ctp ». Pour le controller Contacts, vous pouvez faire le fichier suivant:
Créer ce fichier vous permettra de redéfinir « /app/Plugin/ContactManager/View/Contacts/index.ctp ».
Assets du Plugin¶
Les assets web du plugin (mais pas les fichiers de PHP) peuvent être servis à travers le répertoire “webroot” du plugin, tout comme les assets de l’application principale:
Vous pouvez mettre tout type de fichier dans tout répertoire, juste comme un webroot habituel.
Mais garder à l’esprit que la gestion des assets statiques, comme les images, le Javascript et les fichiers CSS des plugins à travers le Dispatcher est incroyablement inefficace. Il est grandement recommandé de les symlinker pour la production. Par exemple comme ceci:
Lier aux plugins¶
Faîtes précéder simplement /nom_plugin/ pour le début d’une requête pour un asset dans ce plugin, et cela fonctionnera comme si l’asset était dans le webroot de votre application.
Par exemple, lier le “/contact_manager/js/some_file.js” servira l’asset “app/Plugin/ContactManager/webroot/js/some_file.js”.
Note
Il est important de noter le préfixe /votre_plugin/ avant le chemin de l’asset. Et la magie opére!
Modifié dans la version 2.1: Utilisez la syntaxe de plugin pour accéder aux assets. Par exemple dans votre View:
Components, Helpers et Behaviors¶
Un plugin peut avoir des Components, Helpers et Behaviors tout comme une application CakePHP classique. Vous pouvez soit créer des plugins qui sont composés seulement de Components, Helpers ou Behaviors ce qui peut être une bonne façon de construire des Components réutilisables qui peuvent être facilement déplacés dans tout projet.
Construire ces components est exactement la même chose que de les construire à l’intérieur d’une application habituelle, avec aucune convention spéciale de nommage.
Faire référence avec votre component, depuis l’intérieur ou l’extérieur de votre plugin nécessite seulement que vous préfixiez le nom du plugin avant le nom du component. Par exemple:
La même technique s’applique aux Helpers et aux Behaviors.
Note
À la création de Helpers, vous verrez que AppHelper n’est pas automatiquement disponible. Vous pouvez déclarer les ressources dont vous avez besoin avec les uses:
Etendez votre Plugin¶
Cet exemple est un bon début pour un plugin, mais il y a beaucoup plus à faire. En règle général, tout ce que vous pouvez faire avec votre application, vous pouvez le faire à l’intérieur d’un plugin à la place.
Continuez, incluez certaines librairies tierces dans “Vendor”, ajoutez de nouveaux shells à la console de cake, et n’oubliez pas de créer des cas de test ainsi les utilisateurs de votre plugin peuvent automatiquement tester les fonctionnalités de votre plugin!
Dans notre exemple ContactManager, nous pourrions créer des actions add/remove/edit/delete dans le ContactsController, intégrer la validation dans le model Contact, et intégrer la fonctionnalité à laquelle on pourrait s’attendre quand on gère ses contacts. A vous de décider ce qu’il faut intégrer dans vos plugins. N’oubliez juste pas de partager votre code avec la communauté afin que tout le monde puisse bénéficier de votre component génial et réutilisable!
Astuces pour les Plugins¶
Une fois qu’un plugin a été installé dans /app/Plugin/, vous pouvez y accéder à l’URL /nom_plugin/nom_controller/action. Dans notre exemple de plugin ContactManager, nous accédons à notre ContactsController à l’adresse /contact_manager/contacts.
Quelques astuces de fin lorsque vous travaillez avec les plugins dans vos applications CakePHP:
Si vous n’avez pas un [Plugin]AppController et [Plugin]AppModel, vous aurez des erreurs de type get missing Controller lorsque vous essayez d’accéder à un controller d’un plugin.
Vous pouvez définir vos propres layouts pour les plugins, dans le dossier app/Plugin/[Plugin]/View/Layouts. Sinon, les plugins utiliseront les layouts du dossier /app/View/Layouts par défaut.
Vous pouvez établir une communication inter-plugin en utilisant
$this->requestAction('/plugin_name/controller_name/action');
dans vos controllers.Si vous utilisez requestAction, assurez-vous que les noms des controllers et des models sont aussi uniques que possibles. Sinon, vous aurez des erreurs PHP de type « redefined class … ».
Quand vous ajoutez des routes avec des extensions à votre plugin, assurez-vous d’utilisez
Router::setExtensions()
pour ne pas devoir surcharger le routing de l’application.Publiez votre Plugin¶
Vous pouvez ajouter votre plugin sur plugins.cakephp.org ou le proposer à la liste awesome-cakephp.
Aussi, vous pouvez créer un fichier composer.json et publier votre plugin sur packagist.org. De cette façon, il peut être facilement utilisé avec Composer.
Choisissez un nom de package avec une sémantique qui a du sens. Il devra idéalement être préfixé avec la dépendance, dans ce cas « cakephp » comme le framework. Le nom de vendor sera habituellement votre nom d’utilisateur sous GitHub. N’utilisez pas le namespace CakePHP (cakephp) puisqu’il est reservé aux plugins appartenant à CakePHP. La convention est d’utiliser les lettres en minuscule et les tirets en séparateur.
Donc si vous créez un plugin « Logging » avec votre compte GitHub « FooBar », un bon nom serait foo-bar/cakephp-logging. Et le plugin « Localized » appartenant à CakePHP peut être trouvé dans cakephp/localized.