Extension des fonctionnalités

Généralités

Le système de plugins est conçu autour du composant Event Dispatcher du framework symfony, basé sur le concept d'Observer pattern.

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)

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.

Extension des fonctionnalités via l'usage de plugins

Il est, via le système de plugins, aisé d'écouter un événement pour exécuter une nouvelle action lors de son appel.

Nous allons par exemple créer un plugin qui logguera chaque tentative d'authentification.

La fonction AuthenthificationProcess() dans le fichier /lib/functions_auth.php déclare l'événement authentication.main_authentication :


function AuthenthificationProcess($login, $pass, $type)
{
    // Notify the beginning of the current method
    global $dispatcher;
    $dispatcher->notify(new sfEvent(__FUNCTION__, 'authentication.main_authentication', array('login' => $login, 'password' => $pass, 'type' => $type)));

       // ..... 
       // Processus d'authentification
}


Le fichier init.php du nouveau plugin devra contenir les instructions suivantes :


// Log de l'authentification dans [path to app]/tmp
function logAction(sfEvent $event) {
    $a[0]= $event['login']. " s'est authentifé le ".date('d/n/Y à H:i:s')." depuis ". $event['type'];
    logfile(SITE_PATH.'/tmp/auth.log', $a);
}

// Execute la fonction logAction lorsque l'événement authentication.main_authentication est notifié
$dispatcher->connect('authentication.main_authentication', 'logAction');


Votre plugin est terminé! Chaque fois qu'un utilisateur s'authentifiera, le fichier auth.log sera renseigné.

Ajout de méthodes grâce à la fonction magique __call()

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.

Remarque : L'événement créé par Linea21 se nomme .extensible_function.

A titre d'illustration, voici un exemple d'implémentation sur le module News (qui gère l'actualité) :


  public function __call($method, $arguments)
  {
    $event = $this->dispatcher->notifyUntil(new sfEvent($this, 'news.extensible_function', array(
      'method'    => $method,
      'arguments' => $arguments
    )));
    if (!$event->isProcessed())
    {
      throw new Exception(sprintf('Call to undefined method %s::%s.', get_class($this), $method));
    }

    return $event->getReturnValue();
  }


Dans le __init__.php de mon plugin :


// 1 -Création de la classe extensibleNews() et ajout des méthodes
class extensibleNews
{
    static public function listenToMethodNotFound(sfEvent $event)
    {

        switch ($event['method'])
        {
            case 'performAction':
                self::doTest($event->getSubject(), $event['arguments']);
                return true;
            default:
                return false;
        }
    }

    static private function performAction($subject, $arguments)
    {
                if(is_string($arguments)) $msg = $arguments;
                if(is_array($arguments))    $msg = join(', ', $arguments);
                mail('info@xxxx.com', 'extension de Linea21', 'Voici les arguments passés à ma fonction : '. $msg);
                _debug('[event/dispatcher] (INTERNAL) - we run ' . __FUNCTION__ . '() function by extensibleFunc() call with arguments : '. $msg);
    }

}

// 2 - On connecte l'événement en précisant la classe et la méthode à appeler
$dispatcher->connect('news.extensible_function', array('extensibleNews', 'listenToMethodNotFound'));

// 3 - Enfin, on appelle la nouvelle méthode depuis l'objet news
// ici après un test conditionnel pour exécuter l'action sur la section 'news' seulement
if(isset($_REQUEST['rub']) && $_REQUEST['rub'] == 'news') {
    include_once '../class/class.news.php';
    $n = new news;
    $n->performAction('arg 1', 'arg 2', 'arg 3');
}


Gestion des événements, téléchargez le plugin d'exemple

Pour mieux comprendre ou pour aller plus loin, essayez vous-même en téléchargeant le plugin suivant : l21_eventDispatcherSample.zip
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.

Modifier la présentation et/ou les traitements

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.

Par exemple, nous pouvons créer l'arborescence /override/news, copier-coller le fichier le fichier list.php à l'intérieur et y faire quelques modifications.

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).

Modification de la consultation des actualités

l21_eventDispatcherSample.zip - Plugin d'exemple (6.32 KB) Simon, 07/04/2012 09:48 AM

demo_plugin.png - Modification de la consultation des actualités (34.3 KB) Simon, 07/04/2012 05:07 PM