Extension de fonctionnalités » History » Version 9
Simon, 07/04/2012 11:43 AM
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 | 9 | Simon | h2. Plugins, téléchargez le module 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 | h3. L'utilisation couplée des plugins et des templates : la possibilité de surcharger l'application |
||
142 | |||
143 | Depuis la version 1.6, il est possible de surcharger l'application, grâce au système de [[Personnalisation_de_l'interface#Les-templates-et-loverride|templates et à l'override]] désormais implémenté sur la partie administration. |
||
144 | |||
145 | A COMPLETER |