Project

General

Profile

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