Project

General

Profile

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!