lunes, 4 de mayo de 2009

Zend_Application and Autoload Modules

UPDATE: if you're using SVN, you need to update to a later revision (after 15357, mandatory) due to a bug

La liberación de la versión 1.8 del Zend Framework deja mucho que desear en cuanto a documentación. Erratas y omisiones parecen ser los principales problemas con los que nos encontramos los usuarios. Además, no se ha publicado el API 1.8 para su descarga (sólo consulta online). Sin embargo, los test sobre el código cubren el 100% y hacen más llevadera la interpretación del código.

Otro de los problemas con el que nos encontramos es cómo configurar nuestra aplicación modular para que se beneficie del componente Zend_Application y la carga dinámica de los recursos mediante Zend_Application_Module_Bootstrap. Por eso hemos decidido escribir este post y ofrecer como ejemplo una sencilla aplicación modular que se representa en el siguiente árbol:

En primer lugar creamos nuestro public/index.php

// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(dirname(__FILE__) . '/../library'),
get_include_path()
)));

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

// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()->run();

A continuación añadimos los datos de configuración de nuestra aplicación en: /application/configs/application.ini

[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0

bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"

autoLoaderNameSpaces.0 = "Scienta"

resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_PATH "/layout/scripts"

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.plugins.debug = "Scienta_Controller_Plugin_Debug"


resources.modules[] =

[staging : production]

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

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

En tercer lugar, acondicionamos nuestro /application/Bootstrap.php



class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
/**
* @var Zend_Log
*/
protected $_logger;

protected function _initLogging()
{
$this->bootstrap('frontcontroller');
$logger = new Zend_Log();

$writer = 'production' == $this->getEnvironment() ?
new Zend_Log_Writer_Stream(APPLICATION_PATH . '/../var/logs/app.log') :
new Zend_Log_Writer_Firebug();
$logger->addWriter($writer);

if ('production' == $this->getEnvironment()) {
$filter = new Zend_Log_Filter_Priority(Zend_Log::CRIT);
$logger->addFilter($filter);
}

if($writer instanceof Zend_Log_Writer_Firebug)
{
$writer-> setPriorityStyle(8, 'TABLE');
$logger->addPriority('TABLE', 8);
}


$logger->info($this->bootstrap('frontcontroller'));
$logger->info($this->getPluginResourceNames());
$logger->info($this->getApplication());
Zend_Registry::set('logger', $logger);

/*
* Set _logger for use with other methods
*/
$this->_logger = $logger;
}
protected function _initView()
{
// Initialize view
$view = new Zend_View();
$view->doctype('XHTML1_STRICT');
$view->headTitle('My First Zend Framework Application');
// set the content type and language
$view->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8');
$view->headMeta()->appendHttpEquiv('Content-Language', 'en-US');

$view->headLink()->appendStylesheet('/css/basic.css');
$view->headLink()->appendStylesheet('/css/jquery-ui-themeroller.css');

// Add it to the ViewRenderer
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper(
'ViewRenderer'
);
$viewRenderer->setView($view);

// Return it, so that it can be stored by the bootstrap
return $view;
}

}


Y, finalmente, en cada uno de nuestros módulos, añadimos un archivo que instancie el module bootstrap:



Puedes descargar el código fuente de este pequeño ejemplo aquí:

Download Source Code.

2 comentarios:

  1. En el ejemplo donde dice

    bootstrap('frontcontroller');

    no entiendo si ahy un error, o si la función 'bootstrap' se define en espacio global, o qué

    En todo caso te agradece este servidor

    ResponderEliminar
  2. Hola David,

    Efectivamente, era una omisión. Ya está corregido.

    Gracias!

    ResponderEliminar