Je vais essayer d'être le plus claire possible:
Le index.php situé à la racine:
<?php
/**
* File index
*
* Fichier de controlleur d'application chargant le bootstrap afin de
* securiser ce dernier.
*
* @version 1.0
* @since PHP 5
* @filename index.php
*/
/**
* On redéfinit les chemins d'inclusions pour le framework
* (racine, chemin du framework, inclusion des models)
*/
set_include_path('../0_toolbox/tools/'
. PATH_SEPARATOR . './application/'
. PATH_SEPARATOR . './application/commonsPlugins/'
. PATH_SEPARATOR . './application/modules/default/models/'
. PATH_SEPARATOR . './application/modules/default/plugins/'
. PATH_SEPARATOR . './application/modules/default/forms/'
. PATH_SEPARATOR . get_include_path()
);
/**
* on inclus la classe de bootstrap et on lance l'application
*/
require_once 'bootstrap.php';
bootstrap::run();
Le boostrap:
<?php
/*
* Class bootstrap.
*
* Classe de bootstrap redirigant le index.php vers celle-ci
* et ce pour des raisons de sécurité.
*
* @version 1.0
* @since PHP 5
* @name bootstrap
*/
require_once "Zend/Loader/Autoloader.php";
$autoloader = Zend_Loader_Autoloader::getInstance()->setFallbackAutoloader(true)
->registerNamespace('Brts_');
class bootstrap
{
/*
* frontControlleur
*
* @access private
* @var object Zend_Controller_Front object
*/
private static $frontController = null;
/*
* Registry
*
* @access private
* @var object Zend_Registry object
*/
private static $registry = null;
/*
* object de session pour le nom d'espace system
*
* @access private
* @var object Zend_Session_Namespace object
*/
private static $systemNamespace = null;
/*
* object de session pour le nom d'espace system
*
* @access private
* @var object Zend_Session_Namespace object
*/
private static $userNamespace = null;
/*
* Demarrage de l'application
*
* @name run
* @access public static
* @return void
*/
public static function run()
{
// on paramètre le server
self::setPhpEnvironment();
// on initialise l'objet de registre
self::initRegistry();
// on recupere en registre la ref client
self::addRefClient();
// on initialise les sessions
self::setSession();
// on sauve en registre un objet de données pour config.ini
self::addConfigIni();
// on sauve en registre un objet de données pour system.ini
self::addSystemIni();
// on paramètre l'horloge (timezone) pour le server
self::setEnvironment();
// on definit les deux adapter de base de données
self::setDatabasesAdapters();
// récupèration des infos webmaster et client
self::getWebmasterInfos();
self::getClientInfos();
// on instancie et l'on paramètre le controlleur frontale
self::setControllerFront();
// on instancie et l'on paramètre la vue
self::setView();
// on envoie les headers de non mise en cache et de definition de l'encodage html
self::sendDefaultHeaders();
// on lance l'application
try{
$response = self::$frontController->dispatch();
}
catch(Exception $exception){
exit($exception->getMessage().' at line '.$exception->getLine().', in file '.$exception->getFile());
}
}
/*
* Paramètrage de l'environnement server (php)
*
* @name setPhpEnvironment
* @access private
* @return void
*/
private static function setPhpEnvironment()
{
error_reporting(E_ALL|E_STRICT); // E_ALL uniquement pour PHP6
ini_set('display_errors', 'on');
set_time_limit(10);
ini_set("magic_quotes_runtime", '0');
ini_set('upload_max_filesize', '3M');
ini_set('post_max_size', '8M');
ini_set('memory_limit', '128M');
ini_set('max_input_time', '-1');
ini_set('max_input_time', '-1');
}
/*
* Initialisation de l'object de registre
*
* @name initRegistry
* @access private
*/
private static function initRegistry()
{
self::$registry = new Zend_Registry(array(), ArrayObject::ARRAY_AS_PROPS);
Zend_Registry::setInstance(self::$registry);
}
/*
* Recupération de la reference client depuis sont url et mise en registre
* (initialisation du registre)
*
* @name addRefClient
* @access private
*/
private static function addRefClient()
{
$exploded_domaine = explode(".", $_SERVER['HTTP_HOST']);
$ref_client = $exploded_domaine[1];
Zend_Registry::set('ref_client', $ref_client);
}
/*
* Paramètrage et instanciation de l'objet Zend_Session
*
* @name setSession
* @access private
* @return object Zend_Session object
*/
public static function setSession()
{
$sessionOptions = array(
'bug_compat_42' => 0,
'bug_compat_warn' => 1,
'cache_expire' => 180,
'cache_limiter' => 'nocache',
'cookie_domain' => '',
'cookie_lifetime' => 0,
'cookie_secure' => 0,
'cookie_path' => '/',
'entropy_file' => '',
'entropy_length' => 0,
'gc_divisor' => 1000,
'gc_maxlifetime' => 1440,
'gc_probability' => 1,
'hash_bits_per_character' => 5,
'hash_function' => 1,
'name' => self::$registry->ref_client.'SessionID',
'referer_check' => '',
'save_handler' => 'files',
'serialize_handler' => 'php',
'use_cookies' => 1,
'use_only_cookies' => true,
'use_trans_sid' => 0,
// zend_framework values
'remember_me_seconds' => 0,
'strict' => 'on'
);
Zend_Session::setOptions($sessionOptions);
Zend_Session::start();
// on initialise les namespaces de session system et user
self::$systemNamespace = new Zend_Session_Namespace('system');
self::$userNamespace = new Zend_Session_Namespace('user');
// on regenere si besoin l'id de session toute les 30 seconde pour des raisons évidante
// de sécurité et on pose un verrou sur l'espace de nom system afin de protéger ce dernier
if(isset(self::$systemNamespace->session_regenerate_time) && self::$systemNamespace->session_regenerate_time < time() - 30)
{
// on redefinit session_regenerate_time pour controle du temps entre chaque regeneration
self::$systemNamespace->session_regenerate_time = time();
Zend_Session::regenerateId();
}
else self::$systemNamespace->session_regenerate_time = time();
}
/*
* On recupere les données de configuration application en fichier ini
* suivant si server de "developpement" ou de "production" et on les
* passe en registre
*
* @name addConfigIni
* @access private
*/
private static function addConfigIni()
{
if($_SERVER['HTTP_HOST'] == '127.0.0.1' || $_SERVER['HTTP_HOST'] == 'localhost' || preg_match("#.loc#", $_SERVER['HTTP_HOST']))
{
$configIni = new Zend_Config_ini('application/data/system/config.ini', 'developpement');
}
else $configIni = new Zend_Config_Ini('application/data/system/config.ini', 'production');
Zend_Registry::set('configIni', $configIni);
}
/*
* On recupere les données de configuration system en fichier ini
* suivant si server de "developpement" ou de "production" et on les
* passe en registre
*
* @name addSystemIni
* @access private
* @return object Zend_Config_ini object
*/
private static function addSystemIni()
{
if($_SERVER['HTTP_HOST'] == '127.0.0.1' || $_SERVER['HTTP_HOST'] == 'localhost' || preg_match("#.loc#", $_SERVER['HTTP_HOST'])) {
$systemIni = new Zend_Config_ini('../0_toolbox/webmasterIncludes/infos/system.ini', 'developpement');
}
else $systemIni = new Zend_Config_Ini('../0_toolbox/webmasterIncludes/infos/system.ini', 'production');
Zend_Registry::set('systemIni', $systemIni);
}
/*
* Paramètrage de l'environnement
*
* @name setEnvironment
* @access private
* @return void
*/
private static function setEnvironment()
{
date_default_timezone_set(Zend_Registry::get('configIni')->locale->timezone);
mb_internal_encoding(Zend_Registry::get('configIni')->locale->encoding);
}
/*
* Envoi des headers de l'encodage et de la mise en cache par les proxys et navigateurs
*
* @name sendDefaultHeaders
* @access private
*/
private static function sendDefaultHeaders()
{
$response = new Zend_Controller_Response_Http();
$response->setHeader('Content-Type', 'text/html; charset='.Zend_Registry::get('configIni')->locale->encoding, true);
$response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
$response->setHeader('Expires', 'Mon, 01 Jan 1980 05:00:00 GMT', true);
Zend_Registry::set('response', $response);
}
/*
* Mise en place d'une instance d'adaptateur de base de données
* pour les db client et webmaster et sauvegarde en registre
*
* @name setDatabasesAdapters
* @access private
* @return object Zend_Db_Adapter
*/
private static function setDatabasesAdapters()
{
// on instancie les objets adapter des divers db
$client_adapter = Zend_Db::factory(Zend_Registry::get('configIni')->db->driver, array(
'host' => Zend_Registry::get('configIni')->db->host,
'username' => Zend_Registry::get('configIni')->db->user,
'password' => Zend_Registry::get('configIni')->db->password,
'dbname' => 'MVC_'.Zend_Registry::get('configIni')->client->id.'_db',
'charset' => 'utf8',
'options' => array(
Zend_Db::CASE_FOLDING => Zend_Db::CASE_NATURAL,
Zend_Db::AUTO_QUOTE_IDENTIFIERS => true
)
));
$webmaster_adapter = Zend_Db::factory(Zend_Registry::get('configIni')->db->driver, array(
'host' => Zend_Registry::get('configIni')->db->host,
'username' => Zend_Registry::get('configIni')->db->user,
'password' => Zend_Registry::get('configIni')->db->password,
'dbname' => 'MVC_'.Zend_Registry::get('systemIni')->webmaster->id.'_db',
'charset' => 'utf8',
'options' => array(
Zend_Db::CASE_FOLDING => Zend_Db::CASE_NATURAL,
Zend_Db::AUTO_QUOTE_IDENTIFIERS => true
)
));
Zend_Registry::set('client_adapter', $client_adapter);
Zend_Registry::set('webmaster_adapter', $webmaster_adapter);
}
/*
* Récuperation des infos webmaster
* Si non definit en session, on ce connecte à la DB pour récupération
* et on sauve en session et au registre. Sinon on passe de session vers registre
*
* @name getWebmasterInfos
* @access private
* @return Zend_Db_table object
*/
private static function getWebmasterInfos()
{
if(!isset(self::$systemNamespace->webmaster))
{
// on recupère l'adapter en registre et l'on établie la connection à la base de données
$webmaster_adapter = Zend_Registry::get('webmaster_adapter');
$webmaster_adapter->getConnection();
// on créé une instance de l'objet table
$webmaster = new WebmasterModel(array('db' => $webmaster_adapter));
// on recupère les infos contenu dans l'enregistrement unique d'id=1 (retourne un Rowset)
$webmasterInfos = $webmaster->getInfos();
$webmaster_adapter->closeConnection();
// on sauve en registre
Zend_Registry::set('webmasterInfos', $webmasterInfos);
// on serialise et sauve en session pour eviter de redefinir les infos webmaster à chaque page
self::$systemNamespace->webmaster = serialize(Zend_Registry::get('webmasterInfos'));
}
else
{
// on serialise et sauve en session pour eviter de redefinir les infos webmaster à chaque page
$webmasterInfos = unserialize(self::$systemNamespace->webmaster);
// on sauve en registre
Zend_Registry::set('webmasterInfos', $webmasterInfos);
}
}
/*
* Récuperation des infos client
* Si non definit en session, on ce connecte à la DB pour récupération
* et on sauve en session et au registre. Sinon on passe de session vers registre
*
* @name getClientInfos
* @access private
* @return Zend_Db_table object
* @throw Hoa_Acl_Exception
*/
private static function getClientInfos()
{
if(!isset(self::$systemNamespace->client))
{
// on recupère l'adapter en registre et l'on établie la connection à la base de données
$client_adapter = Zend_Registry::get('client_adapter');
$client_adapter->getConnection();
// on créé une instance de l'objet table
$client = new ClientModel(array('db' => $client_adapter));
// on recupère les infos contenu dans l'enregistrement unique d'id=1 (retourne un Rowset)
$clientInfos = $client->getInfos();
$client_adapter->closeConnection();
// on sauve en registre
Zend_Registry::set('clientInfos', $clientInfos);
// on serialise et sauve en session pour eviter de redefinir les infos webmaster à chaque page
self::$systemNamespace->client = serialize(Zend_Registry::get('clientInfos'));
}
else
{
// on serialise et sauve en session pour eviter de redefinir les infos webmaster à chaque page
$clientInfos = unserialize(self::$systemNamespace->client);
// on sauve en registre
Zend_Registry::set('clientInfos', $clientInfos);
}
}
/*
* instanciation et paramètrage de Zend_Controller_Front (singleton de contrôleur frontale)
*
* @name setControllerFront
* @access public
* @return object Zend_Controller_Front object
*/
public static function setControllerFront()
{
self::$frontController = Zend_Controller_Front::getInstance();
self::$frontController->throwExceptions(Zend_Registry::get('configIni')->settings->throwexeptions); // true en developpement et false en production
self::$frontController->setBaseUrl('/');
self::$frontController->addModuleDirectory('application/modules');
self::$frontController->registerPlugin(new saveVisitorPathPlugin());
self::$frontController->registerPlugin(new setModularIncludePathPlugin());
self::$frontController->registerPlugin(new setLanguagePlugin());
self::$frontController->registerPlugin(new setModularLayoutPlugin());
self::$frontController->registerPlugin(new setHeadLayoutVarsPlugin());
if(!isset(self::$userNamespace->browserInfos)) self::$frontController->registerPlugin(new getBrowserInfosPlugin());
self::$frontController->setRouter(self::setRouter());
}
/*
* instanciation et paramètrage du Zend_Controller_Router_Rewrite
*
* @name setRouter
* @access public
* @return object Zend_Controller_Router_Rewrite object
*/
public static function setRouter()
{
$router_ini = new Zend_Config_Ini('application/data/system/router.ini', 'router_rules');
$router = new Zend_Controller_Router_Rewrite();
$router->removeDefaultRoutes();
$router->addConfig($router_ini, 'routes');
$router->setGlobalParam('langue', self::$userNamespace->langue);
return $router;
}
/*
* instanciation et paramètrage de la vue
*
* @name setView
* @access public
* @return object Zend_View object
*/
public static function setView()
{
// on instancie l'objet de requète pour avoir la methode d'aquisition pour le nom de module
$request = new Zend_Controller_Request_http();
$module = ($request->getModuleName() != null) ? $request->getModuleName() : 'default';
// on instancie la vue, son encodage et le dossier des helpers
$view = new Zend_View();
$view->setEncoding(Zend_Registry::get('configIni')->locale->encoding);
$view->addHelperPath('application/modules/'.$module.'/views/helpers/');
// on instancie viewrender pour le rendu de la vue
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
$viewRenderer->setView($view);
$viewRenderer->view->doctype(Zend_Registry::get('configIni')->locale->doctype);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
}
Un controlleur exemple (celui de mon formulaire fonctionnel):
<?php
/*
* Class alternatestylesheetController.
*
* Classe controlleur d'application alternateStylesheet contenant
* un formulaire de selection de style CSS
*
* @version 1.0
* @since PHP 5
* @name alternatestylesheetController
*/
class alternatestylesheetController extends Zend_Controller_Action
{
/*
* object de session pour le nom d'espace user
*
* @access private
* @var object Zend_Session_Namespace object
*/
private static $userNamespace = null;
/*
* object de session pour le nom d'espace system
*
* @access private
* @var object Zend_Session_Namespace object
*/
private static $systemNamespace = null;
/*
* Liste des langues disponibles pour l'application
*
* @access private
* @var string liste des langues disponibles
*/
private static $listLangue = null;
/*
* on definit les variables de vue commune à toute les actions de ce controller
*
* @name init
* @access public
* @return void
*/
public function init()
{
// definition des variables de session et registre
self::$userNamespace = new Zend_Session_Namespace('user');
self::$systemNamespace = new Zend_Session_Namespace('system');
// definition des variables de layout et partial
$this->_helper->layout->setLayout('defaultLayout');
$this->view->headLayoutVars = Zend_Registry::get('headLayoutVars');
$this->view->headLayoutVars['addJsFile'] = array(
'appendfile' => array(
),
'prependfile' => array(
'/js/taille_police.js'
)
);
$this->view->headLayoutVars['addMootools'] = true;
// on recupère les données du config.ini pour utilisation
$this->configIni = Zend_Registry::get('configIni');
// on compte le nombre de langue disponible pour le site
self::$listLangue = explode("/", $this->configIni->locale->langueListe);
}
/*
* definition de l'action pour la page index.phtml
*
* @name indexAction
* @access public
* @return void
*/
public function indexAction()
{
/*
* Si mode manu ou auto, on traite l'envoi du formulaire.
* On forward vers la premiere action de ce controller (getBrowserInfos).
* Sinon on redirige vers le controller pager à l'index
*/
if($this->configIni->options->styleSheetMode != 'fixe') $this->_forward("show", "alternatestylesheet", "default");
else $this->_redirect('/'.self::$listLangue[0].'/default/pager/index');
}
/*
* definition de l'action pour la page show.phtml
*
* @name showAction
* @access public
* @return void
*/
public function showAction()
{
// definition des différentes variable à assigner à la vue
$this->view->headLayoutVars['titrePage'] = 'Changer l\'apparence du site';
// on créé l'objet formulaire pour la vue
$form = new alternatestylesheetForm();
$this->view->form = $form;
}
/*
* definition de l'action submit qui traite POST et redirige vers l'action show
* pour formulaire/boucle via cookie
*
* @name submitAction
* @access public
* @return void
*/
public function submitAction()
{
// on créé l'objet formulaire pour la vue
$form = new alternatestylesheetForm();
$this->view->form = $form;
// si les données envoyées sont valident
if($this->getRequest()->isPost() && $form->isValid($this->getRequest()->getPost()))
{
// on recupere la valeur de POST
$formData = $this->_request->getPost();
if($form->isValid($formData))
{
// on recupère le style choisi
$style_post = isset($formData['stylesheet']) ? $formData['stylesheet'] : "";
// si le style choisi differt de default
if($style_post != 'default')
{
// on envoi un cookie de style au navigateur pour memoriser le style choisi
//setcookie('BRTS__style', $formData['stylesheet'], time()+604800, '/', $_SERVER['HTTP_HOST'], false, false);
$cookie = new Zend_Http_Cookie('BRTS__style', $formData['stylesheet'], $_SERVER['HTTP_HOST'], time()+604800, Zend_Controller_Front::getInstance()->getBaseURL(), false);
}
else
{
// on envoi un cookie vide
//setcookie('BRTS__style', '', time()+604800, '/', $_SERVER['HTTP_HOST'], false, false);
$cookie = new Zend_Http_Cookie('BRTS__style', '', $_SERVER['HTTP_HOST'], time()+604800, Zend_Controller_Front::getInstance()->getBaseURL(), false);
}
// on envoi le cookie
$response = Zend_Registry::get('response');
$response->setHeader('Set-Cookie', $cookie, false);
$response->sendResponse();
// on redirige vers l'action show
$this->_redirect('/'.self::$listLangue[0].'/default/alternatestylesheet/show');
}
}
else
{
// on leve une exception pour valeur de POST invalide
require_once 'Zend/Form/Exception.php';
throw new Zend_Form_Exception("POST value is not valid but no validator require in file ".__FILE__." at line ".__LINE__);
}
}
}
le router.ini
Code : Tout sélectionner
[router_rules]
;;
;; controlleur pager
;;
routes.pager.type = "Zend_Controller_Router_Route"
routes.pager.route = "/:langue/:module/:controller/:action/*"
routes.pager.defaults.langue = "fr"
routes.pager.defaults.module = "default"
routes.pager.defaults.controller = "pager"
routes.pager.defaults.action = "index"
;;
;; controlleur alternateStylesheet
;;
routes.alternateStylesheet.type = "Zend_Controller_Router_Route"
routes.alternateStylesheet.route = "/:langue/:module/:controller/:action/*"
routes.alternateStylesheet.defaults.langue = "fr"
routes.alternateStylesheet.defaults.module = "default"
routes.alternateStylesheet.defaults.controller = "alternateStylesheet"
routes.alternateStylesheet.defaults.action = "index"
;;
;; controlleur authenticate
;;
routes.authenticate.type = "Zend_Controller_Router_Route"
routes.authenticate.route = "/:langue/:module/:controller/:action/*"
routes.authenticate.defaults.langue = "fr"
routes.authenticate.defaults.module = "default"
routes.authenticate.defaults.controller = "authenticate"
routes.authenticate.defaults.action = "index"
;;
;; controlleur index
;;
routes.index.type = "Zend_Controller_Router_Route"
routes.index.route = "/:langue/:module/:controller/:action/*"
routes.index.defaults.langue = "fr"
routes.index.defaults.controller = "index"
routes.index.defaults.action = "index"
Je ne vous soumet pas les codes de layout, partial, vue, plugin, formulaire... pour le moment. J'aimerai déjà voir ce que vous en penser. Touts conseils au niveau de la methodologie de programmation sera bon à prendre. Si vous noté des oublies, de même...
Mon problème est donc que j'ai un rendu de mon layout avec la partie "content" corespondant à la vue vide de code htlm pour des url du style /fr/module/controlleurInexistant/ActionInexistante . Je ne comprend pas pourquoi je n'est pas de message d'erreur genre page blanche plus message pour ces routes non definit.
Merci d'avance
