Category Archives

30 Articles
Utilisation de Zend REST : Partie 2

Utilisation de Zend REST : Partie 2

Comme promis, voici la partie 2 du tutoriel sur Zend REST. Dans celui-ci, nous allons aborder les choses suivantes :

  • Création et Utilisation d’une APIKEY
  • Utilisation des différentes méthodes http et test des retours JSON avec CURL.
  • Mise en place de codes retours http pour dire s’il y a eu une erreur ou non

Sachez que ce tutoriel est le dernier concernant Zend REST. Le prochain touchera à l’accès sur notre plateforme REST via Android.

I- Création et utilisation d’une APIKEY :

1 – Introduction :

L’APIKEY sert aux utilisateurs à s’authentifier sur votre application simplement, sans avoir quelque chose à taper. Vous pouvez avoir une APIKEY globale (ce que l’on va voir ici), une par utilisateurs, une par plateforme ou un mélange de tout ceci à la fois. A vous de voir ce qui vous convient le mieux. Pour notre exemple, nous allons choisir le plus simple, une APIKEY gobale. Si la requête n’est pas envoyée avec cette APIKEY, elle renverra une erreur. L’APIKEY de notre example sera la suivante :

6a0071dbe561c89581c56d1ecf3a4f54

Pour ceux qui aimeraient savoir ce que c’est, cette APIKEY n’est qu’un simple MD5 de throrinstudio. 

2 – Mise en place :

Maintenant, il faut peut-être dire à Zend que nous voulons utiliser cette APIKEY et, si elle est mauvaise, refuser la requête. Nous allons donc créer un plugin pour notre Controller. Si vous ne savez pas ce que c’est, voici un petit rappel de la documentation :

L’architecture MVC de Zend Framework propose l’injection de plugins de code, qui vont intervenir à différents niveaux dans le processus complet. Le contrôleur frontal enregistre des plugins, et utilise un gestionnaire de plugins (« plugin broker »), qui va se charger de faire intervenir chaque plugin, à chacun des instants clés à votre disposition.

Donc, nous allons créer le plugin RestAuth suivant :

class App_Controller_Plugin_RestAuth extends Zend_Controller_Plugin_Abstract{

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $apiKey = $request->getHeader('Api-Key');

        //on récupère notre fichier de configuration
        //car notre apikey est stoquée dedans
        $config = Zend_Registry::get('config'); 


        //Si notre apikey est mauvaise alors qu'on essaie d'accéder à notre module rest et qu'on est pas sur la page d'erreur, 
        //on renvoie vers la page d'erreur
        if($apiKey != $config['tutorest']['apikey'] && $request->getModuleName() == "rest" && $request->getControllerName() != "error") {
            //Ici, on met le code 403 ACCES_DENIED à notre réponse HTTP
            $this   ->getResponse()
                    ->setHttpResponseCode(403);
            //Et on redirige vers le controller d'erreur
            $request->setModuleName('rest')
                    ->setControllerName('error')
                    ->setActionName('api')
                    ->setDispatched(true);
        }

    }
}

Comme on peut le voir, on redirige en cas d’erreur sur un controller d’erreur créé pour l’occasion. Voici son code :

class Rest_ErrorController extends Zend_Controller_Action{

    public function init()
    {
        $bootstrap = $this->getInvokeArg('bootstrap');
        $options = $bootstrap->getOption('resources');

        $contextSwitch = $this->_helper->getHelper('contextSwitch');
        $contextSwitch  ->addActionContext('api', array('json'))
                        ->initContext('json');
    }

    public function apiAction(){
        $this->view->error = "APIKEY is wrong";
    }
}

Et maintenant, nous allons dire à Zend de charger notre plugin pour faire le test. Nous allons l’initialiser dans le Bootstrap de notre module Rest :

class Rest_Bootstrap extends Zend_Application_Module_Bootstrap
{
    protected function _initAutoload()
    {
            $moduleLoader = new Zend_Application_Module_Autoloader(array(
            'namespace' => 'Rest',
            'basePath' => APPLICATION_PATH . '/modules/rest'));
            return $moduleLoader;
    }

    protected function _initPlugins(){
        $bootstrap = $this->getApplication();
        $bootstrap->bootstrap('frontcontroller');
        $front = $bootstrap->getResource('frontcontroller');

        $front->registerPlugin(new App_Controller_Plugin_RestAuth());
    }
}

Maintenant, si vous essayez d’accéder au site via http://votresite/rest/ vous devriez avoir le JSON suivant :

{"error":"APIKEY is wrong"}
Attention, il se peut qu’à la place vous ayez le message suivant :  Fatal error: Uncaught exception ‘Zend_Exception’ with message ‘No entry is registered for key ‘config »… Si vous avez ce message, rien de grave, c’est que vous n’avez pas initialisé la variable de registre config à partir du Bootstrap principal. Si c’est votre cas, voici la fonction à rajouter :

protected function _initConfig()
{
Zend_Registry::set(‘config’, $this->getOptions());
}

Maintenant que nous avons mis en place l’apikey, nous allons voir comment la renseigner à notre requête.

3 – Utilisation :

Pour cette partie, nous allons effectuer nos requêtes via curl en ligne de commande linux. Ici j’utilise putty connecté sur mon serveur de test. Avant de pouvoir utiliser CURL, vous devez l’avoir d’installé sur votre machine. Si ce n’est pas le cas, faites le :

sudo apt-get install curl

Ensuite pour interroger le serveur comme le fait votre navigateur, vous aurez juste à taper la commande suivante. Attention, elle vous retournera la même erreur que par le navigateur.

curl http://localhost/tutosite/rest/tuto -v

Si vous avez bien regardé le plugin de vérification de l’apiKey, vous pouvez voir que l’on récupère cette clé directement dans le header HTTP de la façon suivante :

$apiKey = $request->getHeader('Api-Key');

Nous allons donc dire à CURL de rajouter une nouvelle en-tête à la requête HTTP du nom ‘Api-Key’ et contenant notre clé :

curl http://localhost/tutosite/rest/tuto -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

En retour vous devriez avoir le bon JSON. Voilà, maintenant vous savez comment renseigner votre api-key directement dans les headers HTTP. Maintenant nous allons passer aux différents types de requête.

II- Méthodes HTTP et REST :

1 – index et GET :

C’est la méthode la plus courante pour demander une ressource. Une requête GET est sans effet sur la ressource, il doit être possible de répéter la requête sans effet. la méthode getAction() sera appelée lorsque l’on cherche à récupérer une ressource en particulier. Si nous ne demandons rien de particulier, c’est la méthode indexAction() qui est appelée à la place. Par exemple pour récupérer une liste, on va dans index, pour récupérer un livre en particulier, on va dans get. 

La commande curl précédente nous permettait d’aller dans notre méthode index. Pour accéder dans la méthode get, il suffit juste d’effectuer la commande suivante en renseignant dans le lien l’id de l’élément à chercher :

curl http://localhost/tutosite/rest/tuto/1 -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

En réponse vous devriez avoir le JSON correspondant à celui de getAction.

2 – POST :

Cette méthode doit être utilisée pour soumettre des données en vue d’un traitement à une ressource (typiquement depuis un formulaire HTML). L’URI fournie est l’URI d’une ressource à laquelle s’appliqueront les données envoyées.

Le résultat peut être la création de nouvelles ressources ou la modification de ressources existantes. À cause de la mauvaise implémentation des méthodes HTTP par les navigateurs, cette méthode est souvent utilisée en remplacement de la requête PUT, qui devrait être utilisée à la fois pour la création et la mise à jour de ressources.

Voici la commande permettant de tester le POST :

curl -d "article=myarticle"   http://localhost/tutosite/rest/tuto/ -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

3 – PUT :

Cette méthode permet de remplacer ou d’ajouter une ressource sur le serveur. L’URI fourni est celui de la ressource en question. PUT et POST pourraient être tous les deux utilisés pour effectuer la même chose. Normalement j’utilise POST pour la création et PUT pour la modification. Après à vous de voir ce que vous préférez. Voici la commande permettant de tester le PUT:

curl -d "article=myarticle" -X PUT  http://localhost/tutosite/rest/tuto/ -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54 -v

4 – DELETE :

Cette méthode permet de supprimer une ressource du serveur. Normalement, après exécution de cette requête il ne devrait pas y avoir de réponse HTTP mis à par le status HTTP. Ici nous allons avoir un retour car nous n’avons pas établis les codes retours :

curl -X DELETE  http://localhost/tutosite/rest/tuto -H Api-Key:6a0071dbe561c89581c56d1ecf3a4f54

III- Codes retours :

Afin de savoir si nos requêtes se sont bien passées ou pas, nous regarderont le code retour HTTP avant de traiter le JSON de retour. Comme cela, nous saurons s’il s’agit d’un JSON de ressources à traiter, de confirmation, d’erreur, … Pour faire ceci, nous rajouterons à chacune de nos fonction la commande suivante :

$this->getResponse()->setHttpResponseCode($code);

Nous nous baserons sur les codes retour HTTP. Ce sera plus simple pour les traiter et en même temps ça servira de piqûre de rappel pour certains 😉 :

  • 200 : Requête traitée avec succès (utilisée pour index et GET
  • 201 : Requête traitée avec succès avec création d’un document (utilisée pour PUT et POST)
  • 204 : Requête traitée avec succès mais pas d’information à renvoyer (utilisée par DELETE)
  • 400 : La syntaxe de la requête est erronée (peut être utilisée si vous passez les mauvais paramètres de recherche et/ou d’ajout)
  • 403 : L’authentification est refusée. (utilisée quand APIKEY est invalide)
  • 404 : Ressource non trouvée (peut être utilisée dans GET et PUT/POST quand la ressource à récupérer/modifier n’existe pas)
  • 500 : Erreur interne du serveur (utilisée pour toute erreur PHP ou tests invalides autre que ceux gérés au dessus)
Après à vous de décider. Je n’ai pas mis toute la liste mais seulement l’énumération et les Use Cases des principaux codes de retour.

Le code de retour 204 ne retournera aucun contenu même si vous en renseignez un. Donc pour vérifier que l’action DELETE s’est effectuée avec succès, testez juste le code de retour. Si c’est 204, tout s’est bien passé.

Conclusion Partie 2.

Dans cette partie vous aurez vu comment toucher au header HTTP, comment modifier le code de retour et comment vérifier tout ceci sous Zend. Vous aurez aussi appris à vous servur de curl en ligne de commande (peut être un tutoriel sur curl et Zend dans un prochain tutoriel ?). Avec ceci vous avez toutes les bases pour créer votre propre service REST. La prochaine fois nous verrons comment consommer ce service grâce à une application Android. Sur ce, je vous souhaite une bonne fin de semaine.

Utilisation de Zend REST : Partie 1

Utilisation de Zend REST : Partie 1

Bonjour, aujourd’hui nous allons voir comment créer un service REST avec Zend et comment signaler à Zend que nous attendons la réponse dans le format JSON.

Ce tutoriel n’est que le premier d’une série d’autres tutoriels permettant d’aller plus loin dans Zend REST à savoir :

  • Présentation de REST et configuration de Zend
  • Utilisation d’une APIKEY et des différentes méthodes HTTP
  • Utilisation de notre service REST à partir d’Android

Comme vous devez vous en douter, aujourd’hui nous allons attaquer Présentation de REST et configuration de Zend.

I- Présentation de REST :

Et nous allons commencer par une petite définition Wikipedia de ce qu’est un service REST :

REST (Representational State Transfer) est une manière de construire une application pour les systèmes distribués comme le World Wide Web.

L’application de cette architecture au Web se comprend sur quelques principes simples :

  • l’URI est important : connaître l’URI doit suffire pour nommer et identifier une ressource
  • HTTP fournit toutes les opérations nécessaires (GET, POST, PUT et DELETE, essentiellement) 
  • chaque opération est auto-suffisante : il n’y a pas d’état ;
  • utilisation des standards hypermedia : HTML ou XML qui permettent de faire des liens vers d’autres ressources et d’assurer ainsi la navigation dans l’application REST sont souvent utilisés. Néanmoins, l’utilisation d’autres formats comme JSON ou autres est possible.

Nous allons donc utiliser cette architecture afin de, au final, proposer un service Web pour une application Android. En fonction des choses demandées par notre application, nous effectuerons l’une des requêtes http existantes (GET, PUT, POST, DELETE) afin d’accéder à l’une de nos actions. Lorsqu’une action est effectuée, notre application recevra une réponse au format JSON.

II- Configuration de votre projet Zend :

Je pars du principe que vous avez un projet Zend existant et modulaire. Si vous n’avez pas cela, je vous invite à suivre ma suite de tutoriels sur Zend : Introduction au Framework Zend – Partie 1.

Nous allons placer toute la partie REST dans un module du même nom et nous allons créer le controller TutoController :

class Rest_TutoController extends Zend_Rest_Controller
{
    public function init(){
        $bootstrap = $this->getInvokeArg('bootstrap');
        $options = $bootstrap->getOption('resources');

        $contextSwitch = $this->_helper->getHelper('contextSwitch');
        $contextSwitch  ->addActionContext('index', array('json'))
                        ->addActionContext('get', array("json"))
                        ->addActionContext('post', array("json"))
                        ->addActionContext('put', array("json"))
                        ->addActionContext('delete', array("json"))
                        ->initContext('json');
    }

    public function deleteAction() {
        $this->view->retour = "deleteAction";
    }

    public function getAction() {
        $this->view->retour = "getAction";
    }

    public function indexAction() {
        $this->view->retour = "indexAction";
    }

    public function postAction() {
        $this->view->retour = "postAction";
    }

    public function putAction() {
        $this->view->retour = "putAction";
    }
}

Comme vous pouvez le voir, notre Controller n’étend pas du tout de Zend_Controller_Action mais de Zend_Rest_Controller. Ce controller marche pareil que Zend_Controller_Action à la différence près qu’il implémente chaque action utile à chaque requête HTTP.

Faire ce controller ne suffit pas à faire que Zend_Rest marche. Normalement, en saisissant simplement l’adresse suivante : http://votresite/rest/tuto et en fonction de la requête que vous avez (POST, …) vous devez tomber automatiquement sur l’action associée. Pour que Zend fasse justement le routage adéquat, nous devons le lui signaler dans le Bootstrap principal :

protected function _initRestRoute()
{
    $this->bootstrap('Request');
    $front = $this->getResource('FrontController');
    $restRoute = new Zend_Rest_Route($front, array(), array(
        'rest' => array(
                    'tuto',
                  )
    ));
    $front->getRouter()->addRoute('routerest', $restRoute);
}  

Comme vous pouvez le voir, on demande de charger la fonction initRequest de notre Bootstrap grâce à la commande 

$this->bootstrap('Request');

Et si vous essayez d’accéder à votre site, vous devriez avoir l’erreur suivante si vous n’avez pas défini la fonction initRequest :

Fatal error: Uncaught exception 'Zend_Application_Bootstrap_Exception' with message 'Resource matching "Request" not found' in ...

Pour remédier à cela, voici une la fonction initRequest que j’utilise, elle me permet d’avoir tout le temps un objet Zend_Controller_Request_Http dans mon entité $this->_request de mes controllers :

protected function _initRequest()
{
    $this->bootstrap('FrontController');
    $front = $this->getResource('FrontController');
    $request = $front->getRequest();
    if (null === $front->getRequest()) {
        $request = new Zend_Controller_Request_Http();
        $front->setRequest($request);
    }
    return $request;        
}

Bien, maintenant toute la configuration dite, de base, a été faite. Maintenant, si vous essayez d’accéder à votre action index (appelée par défaut si aucun paramètre GET et si requête de type GET), vous devriez avoir une erreur typique de vue non existante sur votre serveur. C’est normal, nous allons justement voir comment obliger un retour JSON grâce aux Contextes.

III – Les Contextes :

Afin d’expliquer ce que sont les contextes, je vous invite à lire le paragraphe associé dans la documentation Zend :

Les Contextes sont des conditions de formatage pour une ou plusieurs requêtes en fonction de leur type (requête AJAX ou non) le retour des actions appelées. Zend fournit deux aides d’action afin de nous simplifier la tâche : ContextSwitch et AjaxContext. Voici ce que nous dit justement la documentation Zend :

L’aide d’action ContextSwitch est destinée à faciliter le retour de différents formats de réponse à une requête.L’AjaxContext est une aide spécialisée de ContextSwitch qui permet le renvoi de réponses à XmlHttpRequest.

Pour l’activer, vous devez indiquer à votre contrôleur quelles actions répondent à quel contexte. Si une requête d’entrée indique un contexte valide pour une action, alors l’aide d’action en charge :

  • Va désactiver les layouts, si elles sont activées.
  • Va changer le suffixe de la vue à rendre, il faudra donc créer une vue par contexte.
  • Va envoyer les bons en-têtes de réponse en fonction du contexte désiré.
  • Va éventuellement en option appeler des fonctions pour configurer le contexte, ou des fonctions de post-processing.

Normalement, nous devons signaler dans l’url le format de retour de la requête entre JSON et XML de la façon suivante : /module/controller/action//format/<json|xml>. Je vais vous montrer comment configurer nos Contextes pour qu’ils prennent toujours le format JSON par défaut.

Vu que nous allons requêter directement via une application Android (et notre navigateur pour les tests de départ), nous allons utiliser l’aide de vue ContextSwitch. AjaxContext ne nous sert à rien ici car il regarde si la requête est une requête AJAX pour utiliser les contextes alors que ContextSwitch le fait tout le temps.

Pour ce faire, nous allons définir tout ceci dans la fonction init() de notre controller de la façon suivante :

public function init(){
    $bootstrap = $this->getInvokeArg('bootstrap');
    $options = $bootstrap->getOption('resources');

    $contextSwitch = $this->_helper->getHelper('contextSwitch');
    $contextSwitch  ->addActionContext('index', array('json'))
                    ->addActionContext('get', array("json"))
                    ->addActionContext('post', array("json"))
                    ->addActionContext('put', array("json"))
                    ->addActionContext('delete', array("json"))
                    ->initContext('json');
}

La seule contrainte de ces aides de vue, c’est qu’il faut renseigner les formats possibles pour chaque action concernée grâce à la fonction addActionContext() et nous définissons le format choisi par défaut grâce à initContext().

Maintenant, si vous allez sur votre site http://votresite/rest/tuto vous devriez avoir la réponse suivante au format JSON :

{"retour":"indexAction"}

En fonction de votre navigateur il vous sera demandé soit de télécharger un fichier JSON, soit le résultat sera affiché directement dedans.

Le retour JSON n’est qu’une sérialisation PHP vers JSON de toutes vos variables de vues. Si vous avez des tableaux, ils seront convertis en tableau JSON, des objets PHP : en objet JSON si c’est possible. Pour plus d’information, regardez comment marche Zend_JSON_Encode car c’est basé dessus.

Conclusion de la partie 1 :

Voilà, ici nous avons pu voir comment utiliser les contextes, configurer Zend pour REST. Vous pouvez dès maintenant créer une application Zend basique utilisant les contextes. Mais pour ce qui est de REST, il nous manque à voir les différentes requêtes HTTP ainsi que l’utilisation d’une APIKEY pour sécuriser à minima tout ça. Mais pour ceci, nous le verrons dans le prochain tutoriel. 

Sur ce, je vous souhaite de bonnes fêtes de fin d’année et surtout, profitez bien.

Introduction à Zend Framework 2.0

Cela fait un moment que je vous ai parlé de Zend Framework 2.0 en vous disant qu’il allait arriver.

Ces derniers jours je me suis demandé où ils en étaient et il faut dire que cette version avance bien. Pour le moment le framework Zend en version 2.0 n’en est encore qu’au stade de développement (version 2.0dev4 exactement) ce qui la rend impropre à l’utilisation dans un environnement de production mais pas aux différents tests.

Nous allons donc voir comment créer un projet basique avec cette version. Tout d’abord, il faut savoir que ZF2.0 utilise les namespaces introduits dans PHP 5.3 ce qui veut dire que si vous avez un serveur en 5.2.X, vous pouvez passer votre chemin ou bien mettre votre serveur à jour vers la version requise qui se trouve être la version 5.3.1

Voici la liste des nouveautés de cette version :

  • Utilisation des namespaces de PHP 5.3
  • Suppression des require_once et include_once
  • Remplacement des singletons par des classes statiques
  • Optimisation des performances
  • Ajout d’interfaces derrière chaque classe abstraite
  • Réécriture de la partie MVC

Les présentations étant faites, nous pouvons passer à la partie pratique. Vous trouverez le framework Zend à la dervière versionen date (2.0dev4) sur le GIT officiel du projet à cette adresse. Ensuite, sachez que pour ces tests, j’utilise un environnement Linux Ubuntu 11.04.

Bien, maintenant que tout est prêt nous allons regarder ce que comporte l’archive de la realease :

  • /bin : exécutables pour créer un projet de base => nous allons utiliser ceci dans un premier temps
  • /demos : contiens différentes démos des classes => ne nous intéressera pas
  • /documentation : contient la doc de ZF 2.0
  • /library : contient le framework => très important
  • /resources : contient les traductions des validateurs
  • /test : contient les tests unitaires du framework
  • /working : ?????

Donc pour créer un projet rien de plus simple. Il vous suffit d’aller dans le répertoire bin, de mettre les droits nécéssairessur zf.sh et de lancer la commande suivante :

./zf.sh create project <path vers votre projet>
Attention : Lors de la création du projet, Zend ne copie pas le framework dans le dossier library, vous devez soit le faire vous même, soit le rajouter à l’include_path PHP

Etant dans un environnement de test et voulant faire marcher ce framework, je créer un alias du nom de zf2 pointant vers le dossier public. Je dois donc modifier le fichie /public.htaccess comme suit :

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /NOMALIAS/index.php [NC,L]

Maintenant en me rendant sur l’alias contenant mon projet : http://local/zf2, j’obtiens la page suivante :

En regardant la composition du framework Zend, nous observons qu’il a toujours la même répartition par rapport aux versions précédentes. La seule chose frapante par rapport aux anciennes sont le remplacement du nommage Pear (Nom_Classes) par les namespaces (Nom\Classes). Le IndexController.php en est un bon exemple :

<?php

class IndexController extends \Zend\Controller\Action
{

    public function init()
    {
        /* Initialize action controller here */
    }

    public function indexAction()
    {
        // action body
    }
}

Maintenant que nous avons un projet ZF 2.0 prêt à être commencé, nous pouvons faire ce que nous voulons. Par exemple, nous allons créer une nouvelle action du nom de test et affichant seulement un « Essaie d’ajout de l’action test ».

Pour ce faire, nous allons juste rajouter la fonction testAction() à L’indexController comme suit :

<?php

class IndexController extends \Zend\Controller\Action
{

    public function init()
    { 
        /* Initialize action controller here */
    }

    public function indexAction()
    {
        // action body
    }

    public function testAction()
    {

    }
}

Puis maintenant nous allons créer notre vue associée : /application/views/scripts/index/test.phtml :

<?php echo "Essaie d'ajout de l'action test";

Maintenant rendez vous à l’adresse http://local/zf2/index/test et vous devriez avoir la page suivante :

Voilà, maintenant vous savez comment réaliser un projet basic avec le framework Zend 2.0. Je n’ai pas abordé les différents helpers et les différents modules du framework car je n’ai pas encore eu le temps de les tester. Si je tombe sur quelque chose d’intéressant je n’hésiterai pas à le publier sur le blog.

Initiation aux ViewScripts de Zend_Form

Pour la reprise des tutoriels, nous allons voir comment créer un formulaire d’authentification via le système de ViewScripts.

Les ViewScripts, c’est quoi? Et bien, c’est une vue dédiée au formulaire, c’est elle qui va permettre de faire la partie design de votre formulaire sans devoir passer par les décorateurs.

Nous allons donc reprendre le formulaire d’identification de notre turoriel afin de lui faire utiliser les viewScripts :

Pour ce faire, reprenez la classe du formulaire suivante (la complète du tutoriel sur l’identification) :

class Admin_Forms_Identification extends Zend_Form { 
    public function init() { 
      $this->setMethod('post') ->setName('identification');

      $login = new Zend_Form_Element_Text('login');
      $login->setRequired(TRUE)
            ->addFilters(array('StringTrim', 'StripTags'))
            ->addValidators(array( array('validator' => 'StringLength', 'options' => array(0, 20))))
            ->getDecorator('label')->setOption('tag', null);

      $passwd = new Zend_Form_Element_Password('password');
      $passwd->setRequired(TRUE)
             ->addFilters(array('StringTrim', 'StripTags'))
             ->addValidators(array( array('validator' => 'StringLength', 'options' => array(0, 20))))
             ->getDecorator('label')->setOption('tag', null);

      $submit = new Zend_Form_Element_Submit('submit');
      $submit->setIgnore(true);

      $this->addElement($login);
      $this->addElement($passwd);
      $this->addElement($submit);

      $this->setDecorators(array(
          array('ViewScript', array('viewScript' => 'index/forms/identification.phtml'))
      ));
  }
}

Ici, la ligne qui nous intéresse est la suivante :

$this->setDecorators(array(
    array('ViewScript', array(
        'viewScript' => 'index/forms/identification.phtml')
    )
));

On indique qu’on met un décorateur global à notre formulaire et il se situe dans /application/modules/admin/views/index/forms/. Le décorater en question contient la vue propre à notre formulaire :

  <form action="<?php echo $this->escape($this->element->getAction()); ?>"
        method="<?php echo $this->escape($this->element->getMethod()); ?>"
        class="formident"></p>
        <p>
         Vous devez vous identifier pour accéder au backoffice.
        </p>
        <div>
              <span class="labelform"><label>Login</label></span><br />
              <span><?php echo $this->element->login->renderViewHelper(); ?></span>
        </div>
        <div>
              <span class="labelform"><label>Mot de Passe :</label></span><br />
              <span><?php echo $this->element->password->renderViewHelper(); ?></span>
        </div>
        <p><?php echo $this->element->submit->renderViewHelper(); ?></p>
  </form>

Comme vous le voyez, on habille notre formulaire comme l’on veut.

Afin d’appeler l’élément que l’on souhaite sans utiliser les décorateurs par défaut, nous utilisons la fonction renderViewHelper().

Maintenant, il ne vous reste plus qu’à utiliser un peu de CSS et vous pouvez obtenir le formulaire dont vous rêvez.  

Utiliser une Library Externe : Html2Pdf

Aujourd’hui nous allons voir comment implanter HTML2PDF à Zend. Cet article m’a été demandé par quelques personnes ces derniers jours et justement, je pensais en parler.

HTML2PDF ainsi que d’autres libraries PHP disponibles sur internet comme PHPThumb n’utilisent pas la convention PEAR. Leur inclusion ainsi que leur utilisation ne s’effectuera pas comme les libraries utilisant la convention PEAR.

Afin d’utiliser facilement la library html2pdf, nous allons passer par une aide d’action Zend, permettant de faire la transition (Vous pouvez faire une aide de vue ou autre chose utilisant la même logique).

Pour ce faire, nous allons créer une nouvelle classe PHP dans notre library perso App. Elle s’appellera App_Helper_Html2Pdf.

/**
 * Ligne nous permettant d'utiliser la classe HTML2PDF dans souci avec Zend
 */
require_once LIBRARY_PATH.'/html2pdf/html2pdf.class.php';

class App_Helper_Html2Pdf extends Zend_Controller_Action_Helper_Abstract{

    /**
     * @var Zend_Loader_PluginLoader
     */
    public $pluginLoader;

    /**
     * Constructeur: initialisee le chargeur de classes d'aides ou plugins
     *
     * @return void
     */
    public function __construct()
    {
        $this->pluginLoader = new Zend_Loader_PluginLoader();
    }

    /**
     * Constructeur
     *
     * @param string sens portrait ou landscape
     * @param string format A4, A5, ...
     * @param string langue : fr, en, it...
     * @param boolean $unicode TRUE means that the input text is unicode (default = true)
     * @param  String $encoding charset encoding; default is UTF-8
     * @param array marges par defaut, dans l'ordre (left, top, right, bottom)
     * @return null
     */
    public function instanceClass($sens = 'P', $format = 'A4', $langue='fr', $unicode=true, $encoding='UTF-8', $marges = array(5, 5, 5, 8)){
        $html2pdf = new HTML2PDF($sens, $format, $langue, $unicode, $encoding, $marges);

        return $html2pdf;
    }

    /**
     * Fonction permettant d'appeler directement instanceClass
     */
    public function direct($sens = 'P', $format = 'A4', $langue='fr', $unicode=true, $encoding='UTF-8', $marges = array(5, 5, 5, 8)){
        return $this->instanceClass($sens, $format, $langue, $unicode, $encoding, $marges);
    }
}

Pour que Html2Pdf marche ici, nous utilisons, à la première ligne de notre fichier, un require_once pointant sur la classe principale. De là, nous sommes tranquille pour la suite, PHP va se débrouiller. Pour utiliser votre aide d’action, n’oubliez pas de rajouter la partie suivante dans votre Bootstrap.

protected function _initHelpers(){
    Zend_Controller_Action_HelperBroker::addPrefix('App_Helper');
}

Pour finir, pour récupérer votre objet PDF, vous n’aurez plus qu’à faire ceci dans un controller et vous pourrez manipuler votre objet Html2Pdf :

$html2pdf = $this->_helper->Html2Pdf('P','A4','fr', false, 'ISO-8859-15');

Maintenant vous savez comment rajouter une library externe n’utilisant pas la convention PEAR au sein d’un projet Zend. Malheureusement, avec l’arrivée de ZF2 et de PHP5.3 avec les namespaces, cela risque encore de changer.