application controller and application initializer
Posted: Wed Sep 19, 2007 6:30 pm
I'm writing an application right now with the Zend Framework. I'm having a very difficult time deciding what should go in my application initialization class (basically the bootstrap) and what should go in my application controller (extends Zend_Controller_Action and is extended by all of my controllers within the app). For instance, the session. Should it start in the bootstrap? How about the database initialization? My bootstrap file looks like this...
MC2_Bag basically just contains all of the initialization that normally would happen in index.php. I don't really like having all of that stuff just out in the index file. I don't really know my reasoning for that. app/MC2/Bag.php looks like this:
And then I have my application controller which is just a controller that all of my controllers extend. It looks like this:
It just seems that the two do a lot of the same kind of stuff. Should I be initializing everything in the bootstrap class and then passing it in via $front->setParam()?
Code: Select all
<?php
require_once 'app/MC2/Bag.php';
MC2_Bag::run(__FILE__);Code: Select all
<?php
/**
* Disable this in production environments
*/
error_reporting(E_ALL^E_NOTICE);
ini_set('display_errors', 'on');
define('DS', DIRECTORY_SEPARATOR);
define('PS', PATH_SEPARATOR);
define('BP', dirname(dirname(__FILE__)));
/**
* The library directory should always be directly under this file, but if
* for some reason it isn't, you'll need to add its location to the path
*/
set_include_path('./library' . PS . './app' . PS . get_include_path());
require_once 'functions.php';
require_once 'Zend/Debug.php';
/**
* Contains some of the most low-level operations necessary
* for this application
*/
class MC2_Bag
{
/**
* This is the directory in which the application resides
* not the url, but the directory
*/
protected static $basedir = null;
public static function run($bootstrap)
{
self::setBaseDir( dirname($bootstrap) );
// initialize configuration information
$config = self::initConfig();
// connect to the database
$db = self::connect($config->database->toArray());
/*require_once 'Zend/Registry.php';
$registry = Zend_Registry::getInstance();*/
$view = self::initView();
/**
* Front controller pattern
*/
require_once 'Zend/Controller/Front.php';
$front = Zend_Controller_Front::getInstance();
$router = self::initRoutes($front);
/**
* Inject db connection and other necessities into the front controller
*/
$front->setParam('db', $db);
$front->setParam('config', $config);
/**
* Now we set up the front controller to accept multiple modules. This is
* a modular front controller set up.
*/
//$front->addControllerDirectory(self::getBaseDir() . DS . 'modules' . DS . 'default', 'default');
$front->setModuleControllerDirectoryName('')
->addModuleDirectory(self::getBaseDir() . DS . 'modules')
// @todo: find out what this actually does and possibly just enable it when debug is on
->throwExceptions( (bool) $config->throwexceptions )
->dispatch();
}
public static function setBaseDir($dir)
{
self::$basedir = $dir . DS . 'app';
}
public static function getBaseDir()
{
return self::$basedir;
}
/**
* Initialize the configuration information and return it as a Zend_Config
* object
*
* @returns Zend_Config
*/
public static function initConfig()
{
require_once 'Zend/Config.php';
require_once 'config.php';
$config = new Zend_Config($configArray);
return $config;
}
public static function initView()
{
/**
* Prepare custom view
*/
require_once 'Zend/View.php';
require_once 'Zend/Controller/Action/HelperBroker.php';
require_once 'Zend/Controller/Action/Helper/ViewRenderer.php';
$view = new Zend_View;
// add common directories for all Views; always "add", never "set"
$view ->addScriptPath(MC2_Bag::getBaseDir() . DS . 'views/common/_elements')
->addScriptPath(MC2_Bag::getBaseDir() . DS . 'views')
->addHelperPath(MC2_Bag::getBaseDir() . DS . 'views/common/_helpers')
->addFilterPath(MC2_Bag::getBaseDir() . DS . 'views/common/_filters');
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer;
$viewRenderer->setView($view);
// set the Module specific ScriptPath syntax; The Module name is substituted and add to
// as an additional View ScriptPath when a Controller is executed
$viewRenderer->setViewScriptPathSpec(':module/:controller/:action.:suffix');
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
return $view;
}
public static function initRoutes(Zend_Controller_Front $front)
{
$router = $front->getRouter();
require_once 'routes.php'; // defines $routes
foreach ($routes as $key => $route)
{
$router->addRoute($key, $route);
}
return $router;
}
public static function getBaseUrl()
{
return Zend_Controller_Front::getInstance()->getRequest()->getBaseUrl();
}
// @todo: move this out of here and into the Application controller (like it is on luke's laptop)
public static function connect(Array $parameters)
{
require_once 'Zend/Db.php';
require_once 'Zend/Db/Table/Abstract.php';
mysql_connect($parameters['host'], $parameters['username'], $parameters['password']);
mysql_select_db($parameters['dbname']);
try {
$db = Zend_Db::factory('Pdo_Mysql', $parameters);
Zend_Db_Table_Abstract::setDefaultAdapter($db);
} catch (Zend_Db_Adapter_Exception $e) {
// @todo: handle this exception
echo $e;
// maybe a failed login credential, or perhaps the RDBMS is not running
} catch (Zend_Exception $e) {
// @todo: handle this exception
echo $e;
// maybe factory() failed to load the specified Adapter class
}
return $db;
}
}Code: Select all
<?php
require_once 'Zend/Controller/Action.php';
class MC2_Controller_Action extends Zend_Controller_Action
{
/**
* Database connection (retrieved from front injection in bootstrap index.php)
*/
protected $db = null;
/**
* Configuration object
*/
protected $config = null;
/**
* By setting these variables, I am making them available to all of my controllers
* It is not necessary to call parent::init() because nothing is in it
*/
public function init()
{
$front = Zend_Controller_Front::getInstance();
$this->db = $front->getParam('db');
$this->config = $front->getParam('config');
$this->initView();
}
/**
* This may not be the correct way to do this. I am not sure exactly
* what initview does and if I should be initializing my view variables
* here or not.
*/
public function initView()
{
parent::initView();
$this->view->MEDIA = MC2_Bag::getBaseUrl() . '/' . $this->config->view->media_url;
$this->view->BASEURL = MC2_Bag::getBaseUrl();
$this->view->DEBUG = $this->config->debug;
$this->view->HEAD = '';
$this->view->config = $this->config->view;
// if debug is on, let's show the developer their environment
if ($this->config->debug)
{
$this->view->POST = $_POST;
$this->view->GET = $_GET;
$this->view->SESSION = $_SESSION;
$this->view->COOKIE = $_COOKIE;
}
}
// @todo: move this out of the controller... this is view helper logic
protected function includeJquery()
{
$this->view->javascript($this->config->view->jquery);
}
/**
* This is a function that is used by form methods to generically process
* a form. It takes a Zend_Filter_Input instance as its argumnent, checks
* the input's validity, and if it is invalid, it sets all the necessary
* view variables so that error messages are populated etc. and returns
* false. Otherwise, it returns true
*/
protected function processInput(MC2_Input $input)
{
$input->filter();
if ($input->isValid())
{
return $input->getData();
}
else
{
foreach ($input->getMessages() as $element => $messages)
{
foreach ($messages as $message)
{
$this->view->formSetError($element, $message);
}
}
}
return false;
}
}
?>