Tag Archives

2 Articles
Complément Zend_Auth et Zend_Session

Complément Zend_Auth et Zend_Session

Je viens de voir que j’ai oublié de vous parler de la variable de session créée lors de l’identification. Il faut savoir que Zend gère les variables de session de façon sécurisée. Autant vous pouvez en PHP standard modifier vos données avec un $_SESSION[“foo“], autant avec Zend, ces données sont sauvegardées dans un objet protégé qui lui, est stocké dans $_SESSION.

Pour vous faire une idée, vous ne pouvez pas modifier accidentellement une donnée. Il faudra absolument passer par la classe Zend_Session pour les modifier.

Enfin, ici je vais vous montrer comment modifier le contenu di site en fonction de la connexion d’un visiteur. S’il est connecté, des menus apparaîtrons, sinon, d’autres seront présents.

Maintenant que l’introduction est finie, je vais juste vous faire faire une chose supplémentaire au tutoriel d’identification.

Quand le visiteur est déconnecté, le lien ‘identifiez-vous’ apparaît. Quand il est connecté, ce lien sera remplacé par ‘déconnexion’. Tout ceci va se jouer dans la fichier header.phtml qui compose notre Layout. Au final, il devrait ressembler juste à ceci : /application/layout/header.phtml

<div id="header">Tutoriel ZF</div>
<div id="liensheader">
    <a href="<?php echo $this->BaseUrl(); ?>"><span>Accueil</span></a>
    <?php 
        $auth = $this->getAuth('admin');
        if($auth)
        {
    ?>
    <a href="<?php echo $this->url(array('module' => 'admin' ,'controller' => 'index', 'action' => 'logout'), "", true); ?>">
        <span>Déconnexion</span>
    </a>

    <?php 
        }else{
    ?>
    <a href="<?php echo $this->url(array('module' => 'admin' ,'controller' => 'index', 'action' => 'index'), "", true); ?>">
        <span>Identifiez-vous</span>
    </a>
    <?php  } ?>
</div> 
Attention, ici je fais les tests avec une aide de vue personnalisée. Je vais comme ça vous apprendre à rajouter une nouvelle Library en plus de Zend. La Library s’appellera App. Elle s’agrandira au fur et à mesure de l’avancé des tutoriels.

Tout d’abord, allez modifier le bootstrap en ajoutant la fonction suivante : /application/Bootstrap.php

protected static function _initNamespaces() 
{
    $autoloader = Zend_Loader_Autoloader::getInstance();
    $autoloader->registerNamespace('App_');
}

Ensuite, pour que Zend_View trouve nos différentes aides de vue automatiquement, nous allons rajouter la ligne suivante dans _initView() :

$view->addHelperPath('App/View/Helper/', 'App_View_Helper');

Voilà. Maintenant que notre Library App existe, voici la première classe présente : /library/App/View/Helper/GetAuth.php :

class App_View_Helper_GetAuth
{
    function getAuth($namespace=null)
    {
        $auth = Zend_Auth::getInstance()->setStorage(new Zend_Auth_Storage_Session($namespace));
        return $auth->getInstance()->getIdentity();
    }
}

Cette classe va nous retourner les informations e la personne authentifiée.

Comme indiquée dans le précédent article, à la fin Zend_Auth va stocker, dans une variable de session, toutes les informations du membre mis à par son mot de passe. Comme ceci, nous testons si la variable est vide ou pas. Si elle est vide, l’utilisateur n’est pas connecté, sinon, il est bien présent.

Vu que nous demandons de stocker les informations dans le Namespace de session admin, nous le renseignons dans les paramètres de getAuth().

Voilà, j’espère que ce complément vous a été utile.

Création du Bootstrap

Aujourd’hui, on va s’attaquer à une partie très importante du framework. D’ailleurs depuis la 1.8, cette partie a évolué. Je veux bien évidemment parler des fichiers d’amorçages de Zend et plus particulièrement de la classe bootstrap. Je vais vous parler ici des étapes à mettre en œuvre pour pouvoir mener son projet à travers une architecture modulaire. Attention tout de même, je vous parlerai de la partie fonctionnelle du site, pas de celle réservée aux tests unitaires.

A vous de voir après comment découper votre site. Donc voici tout d’abord l’architecture du site que je vais vous commenter + en détail : – Application : contient toute la partie applicative du site : contrôleurs, bootstrap, modules, fichiers de configuration, … – Library : dossier contenant votre bibliothèque personnelle, la library Zend et ZendX. J’y ai aussi placé la Library html2pdf pour générer mes propres pdf. – Public : contient tous les fichiers d’apparence et de confort du site, entre autre vous trouverz vos images, feuilles de style, fichiers à télécharger, scripts javascript, … Deux des fichiers qu’il contient sont importants : index.php permettant d’amorcer le site et le fichier .htaccess contenant les règles de redirection pour le bon fonctionnement du framework Zend. Maintenant que j’ai survolé les dossiers principaux, je vais continuer avec les dossiers à l’intérieur d’application. L’organisation de cette partie est un choix personnel, vous pouvez le modifier : – Configurations : contient tous mes fichiers de configuration .ini pour le bon fonctionnement du site. – Layouts : contient le gabarit (layout) du site. – Modules : contient les différents modules du site. Chaque module contient un fichier bootstrap que je vous expliquerai plus bas et est organisé comme un dossier application standard (dossier controller, forms, models et view). – Le fichier le plus important du site : Bootstrap.php que je vais vous commenter juste en dessous. Maintenant que vous avez eu une présentation de l’organisation choisie pour le site, il faut s’attaquer au fichier public/index.php qui ressemble à ceci :
/**
* Fichier index.php permettant de lancer le bootstrap
*
*/

//Définition du chemin vers le dossier application
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH',
realpath(dirname(__FILE__) . '/../application'));

//Définition de la variable de d'application (utile pour les fichiers de configuration
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV',
(getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV')
: 'production'));

//Partie permettant d'inclure les différentes librairies
//du dossier library (en théorie).
//Nécessite un complément côté bootstrap.
set_include_path(implode(PATH_SEPARATOR, array(
dirname(dirname(__FILE__)) . '/library',
get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Créer l'application, le bootstrap et démarre
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configurations/app.ini'
);
$application->bootstrap()
->run();

Ensuite on s’attaque au fichier .htaccess:
php_value include_path "./../library/"
php_value max_execution_time 36000
php_value memory_limit 128M

# The rules below basically say that if the file exists in the tree, just
# serve it; otherwise, go to index.php. This is more future-proof for your
# site, because if you start adding more and more content types, you don't
# need to alter the .htaccess to accomodate them.
# This is an important concept for the Front Controller Pattern which the
# ZF MVC makes use of.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ /toithistoire/index.php [NC,L]

Comme vous pouvez le constater, on voit que l’on inclut ici aussi le dossier Library. Effectivement, sans cette ligne, le fichier index.php n’arrive pas à le trouver et nous retourne une Exception comme quoi Zend/Application.php ne peut être trouvé. Les lignes du temps d’exécution et de la mémoire allouée ne sont pas obligatoires. Elles ont été rajoutées pour éviter les erreurs de surcharge de la mémoire sur le serveur. Maintenant on s’attaque à la partie la plus importante du projet : la classe Bootstrap. Elle se présente tout d’abord comme ceci :
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}

Que met-on dedans ? Et bien tout ce qui doit être initialisé. C’est-à-dire la base de donnée, les aides d’action, la vue, la pagination, la partie Zend_Config et le chargement des modules. Ceci n’est pas une liste exhaustive, par la suite vous pouvez rajouter le lancement de Zend_Log, Zend_Translate, …

Les fonctions utilisées sont toutes de cette forme :
protected function _initXXX() //XXX le nom de la fonction
Ces fonctions sont toutes exécutées automatiquement à la création du bootstrap. Malgré tout, je vais vous présenter deux fonctions presque obligatoires : _initAutoLoad() et _initView(). La première permettant d’initialiser ce qui se charge automatiquement à savoir ici les modules et ensuite la vue avec tout ce qui y est associé

Pour que votre bibliothèque soit rajoutée dans les classes chargées automatiquement par Zend, vous devez l’indiquer. Moi j’utiliser la fonction _initNamespaces() mais vous pouvez l’appeler autrement ou indiquer son contenu dans _initAutoLoad().. Après avoir rajouté tout ceci, voici à quoi devrai ressembler votre Bootstrap :
/**
* Classe de bootstrap
*
*/
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
/**
* Fonction de chargement
*/
protected function _initAutoload()
{
//on configure le module par défaut avec son namespace,
//son chemin et les ressources associées
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Default_',
'basePath' => APPLICATION_PATH . '/modules/default'));
$moduleLoader->addResourceType('Models', 'models', 'Models');
$moduleLoader->addResourceType('Forms', 'forms', 'Forms');
Zend_Session::start();
return $moduleLoader;
}

/**
* Fonction servant à initialiser la vue
*/
protected function _initView()
{
// Initialize view
$view = new Zend_View();
$view->doctype('XHTML1_STRICT');
$view->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
$view->addHelperPath('App/View/Helper/', 'App_View_Helper');
$view->addHelperPath('ZendX/JQuery/View/Helper', 'ZendX_JQuery_View_Helper');
Zend_Dojo::enableView($view);
Zend_View_Helper_PaginationControl::setDefaultViewPartial('pagination.phtml');
// Add it to the ViewRenderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$viewRenderer->setView($view);
ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();
// Return it, so that it can be stored by the bootstrap
return $view;
}

protected static function _initNamespaces()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('App_');
}
}

Ceci ne suffit pas à tout faire marcher, vous devez toucher aux fichiers de configuration. Ils sont rangés dans le dossier configuration. Il devra contenir le code suivant pour faire fonctionner un minimum votre application (architecture modulaire et lancement du site) :
[production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"

; Configuration de la gestion des modules
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[] = ""

; ADD THE FOLLOWING LINES
resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_PATH "/layouts"

; Base de donnée
resources.db.adapter = PDO_MYSQL
resources.db.params.charset = UTF8
resources.db.params.host = localhost
resources.db.params.username = root
resources.db.params.password =
resources.db.params.dbname = nombdd
resources.db.isDefaultTableAdapter = true

[staging : production]

[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

Vous devrez ensuite initialiser la lecture de ces fichiers. Pour ce faire, j’utilise la fonction _initconfigs(). Ensuite, je met dans une variable globale au bootstrap toutes les données de la base de donnée pour l’initialiser dans la fonction _initDatabase(). Après ceci, vous devriez avoir le bootstrap suivant. La partie _initRouter elle sert à initialiser la route pour aller au sitemap.xml expliqué dans un articlé précédent.
/**
* Classe de bootstrap
*
*/
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
public static $registry;
public static $db;

/**
* Fonction de chargement
*/
protected function _initAutoload()
{
//on configure le module par défaut avec son namespace, son chemin et les ressources associées
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Default_',
'basePath' => APPLICATION_PATH . '/modules/default'));
$moduleLoader->addResourceType('Models', 'models', 'Models');
$moduleLoader->addResourceType('Forms', 'forms', 'Forms');
Zend_Session::start();
return $moduleLoader;
}

/**
* Fonction servant à initialiser la vue
*/
protected function _initView()
{
// Initialize view
$view = new Zend_View();
$view->doctype('XHTML1_STRICT');
$view->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');
$view->addHelperPath('App/View/Helper/', 'App_View_Helper');
$view->addHelperPath('ZendX/JQuery/View/Helper', 'ZendX_JQuery_View_Helper');
Zend_Dojo::enableView($view);
Zend_View_Helper_PaginationControl::setDefaultViewPartial('pagination.phtml');
// Add it to the ViewRenderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
$viewRenderer->setView($view);
ZendX_JQuery_View_Helper_JQuery::enableNoConflictMode();
// Return it, so that it can be stored by the bootstrap
return $view;
}

/**
* Fonction d'initialisation du Routeur
*/
protected function _initRouter()
{
$this->bootstrap('frontController');
$front = $this->getResource('frontController');

$router = $front->getRouter();
$router->addRoute(
'manageSitemap',
new Zend_Controller_Router_Route('sitemap.xml', array('module' => 'sitemap', 'controller'=>'index','action'=>'index'))
);
return $router;
}

/**
* Fonction servant à charger le fichier de configuration
*/
protected static function _initConfig()
{
$config = new Zend_Config_Ini(APPLICATION_PATH . '/configurations/app.ini',APPLICATION_ENV);
self::$db = $config->resources->toArray();
}

/**
* Fonction servant à initialiser la base de donnée
*/
protected static function _initDatabase()
{
$config = self::$db;
$db = Zend_Db::factory($config["db"]["adapter"], $config["db"]["params"]);
Zend_Db_Table::setDefaultAdapter($db);
}

protected static function _initNamespaces()
{
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace('App_');
}
}

Attention, le travail ne s’arrête pas là, dans chaque module (mis à par le module default), il vous faut un bootstrap pour initialiser les ressources du module.

Ce bootstrap est dérivé de Zend_Application_Module_Bootstrap. Vous n’avez besoin ici de redefinir que _initAutoLoad(). Tout le reste est hérité de votre bootstrap principal. Voici le contenu type du bootstrap d’un module :
/**
* Classe de bootstrap
*
*/
class Sitemap_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAutoload()
{
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Sitemap_',
'basePath' => APPLICATION_PATH . '/modules/sitemap'));
$moduleLoader->addResourceType('Models', 'models', 'Models');
$moduleLoader->addResourceType('Forms', 'forms', 'Forms');
return $moduleLoader;
}
}

Voilà, maintenant vous avez tout en main pour lancer votre projet Zend. Si vous avez un problème n’hésitez pas à poser des questions, j’y répondrait le plus rapidement possible.