Project

General

Profile

Actions

Extension de fonctionnalités » History » Revision 9

« Previous | Revision 9/10 (diff) | Next »
Simon, 07/04/2012 11:43 AM


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');
}


Plugins, téléchargez le module 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.

L'utilisation couplée des plugins et des templates : la possibilité de surcharger l'application

Depuis la version 1.6, il est possible de surcharger l'application, grâce au système de templates et à l'override désormais implémenté sur la partie administration.

A COMPLETER

Updated by Simon over 12 years ago · 9 revisions