Extension de fonctionnalités » History » Version 10
Simon, 07/04/2012 05:07 PM
1 | 1 | Simon | {{>toc}} |
---|---|---|---|
2 | |||
3 | 9 | Simon | h1. Extension des fonctionnalités |
4 | 1 | Simon | |
5 | 9 | Simon | |
6 | 1 | Simon | h2. Généralités |
7 | |||
8 | |||
9 | 6 | Simon | Le système de plugins est conçu autour du composant "Event Dispatcher du framework symfony":http://components.symfony-project.org/event-dispatcher/documentation, basé sur le concept d'"Observer pattern":http://fr.wikipedia.org/wiki/Observateur_%28patron_de_conception%29. |
10 | 1 | Simon | |
11 | A l'exception des classes systèmes externes et dela classe _culture_, les classes peuvent être étendues par le système de plugin et la fonction magique __call(). (voir "documentation":http://components.symfony-project.org/event-dispatcher/trunk/book/02-Recipes#chapter_02_adding_methods_to_a_class) |
||
12 | |||
13 | 9 | Simon | Une utilisation couplée du système de plugins et des templates permettra d'étendre les fonctionnalités de Linea21 à volonté tout en garantissant la possibilité de mettre à jour votre application. |
14 | 1 | Simon | |
15 | 9 | Simon | h2. Extension des fonctionnalités via l'usage de plugins |
16 | |||
17 | 6 | Simon | Il est, via le [[Systeme de Plugins|système de plugins]], aisé d'écouter un événement pour exécuter une nouvelle action lors de son appel. |
18 | 1 | Simon | |
19 | 6 | Simon | Nous allons par exemple créer un plugin qui logguera chaque tentative d'authentification. |
20 | 1 | Simon | |
21 | 6 | Simon | La fonction _AuthenthificationProcess()_ dans le fichier _/lib/functions_auth.php_ déclare l'événement *authentication.main_authentication* : |
22 | |||
23 | <pre> |
||
24 | <code class="php"> |
||
25 | |||
26 | function AuthenthificationProcess($login, $pass, $type) |
||
27 | { |
||
28 | // Notify the beginning of the current method |
||
29 | global $dispatcher; |
||
30 | $dispatcher->notify(new sfEvent(__FUNCTION__, 'authentication.main_authentication', array('login' => $login, 'password' => $pass, 'type' => $type))); |
||
31 | |||
32 | // ..... |
||
33 | // Processus d'authentification |
||
34 | } |
||
35 | |||
36 | </code> |
||
37 | </pre> |
||
38 | |||
39 | Le fichier __init__.php du nouveau plugin devra contenir les instructions suivantes : |
||
40 | |||
41 | <pre> |
||
42 | <code class="php"> |
||
43 | |||
44 | // Log de l'authentification dans [path to app]/tmp |
||
45 | function logAction(sfEvent $event) { |
||
46 | $a[0]= $event['login']. " s'est authentifé le ".date('d/n/Y à H:i:s')." depuis ". $event['type']; |
||
47 | logfile(SITE_PATH.'/tmp/auth.log', $a); |
||
48 | } |
||
49 | |||
50 | // Execute la fonction logAction lorsque l'événement authentication.main_authentication est notifié |
||
51 | $dispatcher->connect('authentication.main_authentication', 'logAction'); |
||
52 | |||
53 | </code> |
||
54 | </pre> |
||
55 | |||
56 | Votre plugin est terminé! Chaque fois qu'un utilisateur s'authentifiera, le fichier _auth.log_ sera renseigné. |
||
57 | 1 | Simon | |
58 | 6 | Simon | |
59 | 9 | Simon | h2. Ajout de méthodes grâce à la fonction magique __call() |
60 | 6 | Simon | |
61 | |||
62 | La fonction magique __call() permet de traiter les méthodes non déclarées dans la classe. Couplée avec le motif de conception observeur/observable, elle va nous permettre d'étendre la classe. |
||
63 | |||
64 | Remarque : L'événement créé par Linea21 se nomme *[nom_de_la_class].extensible_function*. |
||
65 | |||
66 | A titre d'illustration, voici un exemple d'implémentation sur le module News (qui gère l'actualité) : |
||
67 | |||
68 | 1 | Simon | <pre><code class="php"> |
69 | |||
70 | 6 | Simon | public function __call($method, $arguments) |
71 | 1 | Simon | { |
72 | 6 | Simon | $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'news.extensible_function', array( |
73 | 'method' => $method, |
||
74 | 'arguments' => $arguments |
||
75 | ))); |
||
76 | if (!$event->isProcessed()) |
||
77 | { |
||
78 | throw new Exception(sprintf('Call to undefined method %s::%s.', get_class($this), $method)); |
||
79 | } |
||
80 | 1 | Simon | |
81 | 6 | Simon | return $event->getReturnValue(); |
82 | 1 | Simon | } |
83 | 6 | Simon | |
84 | 1 | Simon | </code> |
85 | </pre> |
||
86 | |||
87 | 6 | Simon | |
88 | |||
89 | 1 | Simon | Dans le <code>__init__.php</code> de mon plugin : |
90 | |||
91 | |||
92 | <pre><code class="php"> |
||
93 | |||
94 | 6 | Simon | // 1 -Création de la classe extensibleNews() et ajout des méthodes |
95 | class extensibleNews |
||
96 | 1 | Simon | { |
97 | 6 | Simon | static public function listenToMethodNotFound(sfEvent $event) |
98 | { |
||
99 | 1 | Simon | |
100 | 6 | Simon | switch ($event['method']) |
101 | { |
||
102 | case 'performAction': |
||
103 | self::doTest($event->getSubject(), $event['arguments']); |
||
104 | return true; |
||
105 | default: |
||
106 | return false; |
||
107 | } |
||
108 | } |
||
109 | |||
110 | static private function performAction($subject, $arguments) |
||
111 | { |
||
112 | if(is_string($arguments)) $msg = $arguments; |
||
113 | if(is_array($arguments)) $msg = join(', ', $arguments); |
||
114 | mail('info@xxxx.com', 'extension de Linea21', 'Voici les arguments passés à ma fonction : '. $msg); |
||
115 | _debug('[event/dispatcher] (INTERNAL) - we run ' . __FUNCTION__ . '() function by extensibleFunc() call with arguments : '. $msg); |
||
116 | } |
||
117 | |||
118 | 1 | Simon | } |
119 | 2 | Simon | |
120 | 6 | Simon | // 2 - On connecte l'événement en précisant la classe et la méthode à appeler |
121 | $dispatcher->connect('news.extensible_function', array('extensibleNews', 'listenToMethodNotFound')); |
||
122 | |||
123 | // 3 - Enfin, on appelle la nouvelle méthode depuis l'objet news |
||
124 | // ici après un test conditionnel pour exécuter l'action sur la section 'news' seulement |
||
125 | if(isset($_REQUEST['rub']) && $_REQUEST['rub'] == 'news') { |
||
126 | include_once '../class/class.news.php'; |
||
127 | $n = new news; |
||
128 | $n->performAction('arg 1', 'arg 2', 'arg 3'); |
||
129 | } |
||
130 | 1 | Simon | |
131 | </code> |
||
132 | </pre> |
||
133 | 7 | Simon | |
134 | |||
135 | 10 | Simon | h3. Gestion des événements, téléchargez le plugin d'exemple |
136 | 1 | Simon | |
137 | Pour mieux comprendre ou pour aller plus loin, essayez vous-même en téléchargeant le plugin suivant : attachment:l21_eventDispatcherSample.zip |
||
138 | Installez-le et assurez-vous qu'il soit bien activé. Vous pourrez observer son comportement via la barre de debug et en analysant son code source. |
||
139 | 9 | Simon | |
140 | |||
141 | 10 | Simon | h2. Modifier la présentation et/ou les traitements |
142 | 1 | Simon | |
143 | 10 | Simon | Depuis la version 1.6, vous pouvez ajouter des informations (champ de formulaire, titre, avertissement, ...), les modifier, les supprimer en surchargeant votre plugin. Pour cela, rien de plus simple, copiez les fichiers natifs du module concerné dans le dossier _override_ de votre plugin et faites vos modifications. |
144 | 1 | Simon | |
145 | 10 | Simon | Par exemple, nous pouvons créer l'arborescence _[plugin_name]/override/news_, copier-coller le fichier le fichier _list.php_ à l'intérieur et y faire quelques modifications. |
146 | |||
147 | La capture d'écran ci-dessous illustre l'ajout d'un titre et le passage des actions en colonne gauche (alors qu'elles sont situées à droite par défaut). |
||
148 | |||
149 | !demo_plugin.png! |