/** * STAGE 1: Initializations / Loading Configuration */ public static function stage1($installDir, $appDir, $configEnv) { ///////////////////////////// // ==> SECTION: mvc <== $ds = DIRECTORY_SEPARATOR; // too much typing ;) ZFDemo_Log::log('$appDir =' . $appDir); self::$registry = Zend_Registry::getInstance(); // the "master" registry ///////////////////////////// // ==> SECTION: mvc <== self::$registry['appDir'] = $appDir; // add the application-specific source file path to PHP's include path for the Conventional Modular Layout set_include_path($appDir . PATH_SEPARATOR . get_include_path()); ZFDemo_Log::log("PHP Include Path = \n " . str_replace(':', "\n ", ini_get('include_path'))); // this application's configuration information $configDir = $appDir . 'config' . $ds; self::$registry['configDir'] = $configDir; ZFDemo_Log::log('$configDir =' . $configDir); // persistent dynamic data, like log files or SQLite files $dataDir = $appDir . 'data' . $ds; self::$registry['dataDir'] = $dataDir; ZFDemo_Log::log('$dataDir =' . $dataDir); ///////////////////////////// // ==> SECTION: session <== // place for temporary files, like session data, cached data, compiled templates $temporaryDir = $appDir . 'temporary' . $ds; self::$registry['temporaryDir'] = $temporaryDir; ZFDemo_Log::log('$temporaryDir =' . $temporaryDir); ///////////////////////////// // ==> SECTION: mvc <== self::$environment = $configEnv; // after this point, all defaults come from config files require 'Zend/Config/Ini.php'; $config = new Zend_Config_Ini($configDir . 'config.ini', self::$environment, true); ZFDemo_Log::log("config.ini=" . print_r($config->toArray(), true)); if (strpos($config->log, '/') !== 0) { $config->log = $dataDir . $config->log; } self::$registry['config'] = $config; // application configuration array date_default_timezone_set($config->timezone); // application default timezone // setup DB adapter for use by all models using "raw" SQL via PHP's PDO extension if ($config->db->modelSet === 'pdo') { $dsn = $config->db->dsn->toArray(); foreach (array_diff_key($dsn, array('username', 'password')) as $key => $val) { $connect[] = "{$key}={$val}"; } $db = new PDO($config->db->type . ':' . implode(';', $connect), $dsn['username'], $dsn['password']); $db->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); } ///////////////////////////// // ==> SECTION: mvc <== if (self::testDb($db) === false) { // sanity check of connection and zfdemo tables using Zend Db Adapter failed self::$registry['testDbFailed'] = true; } self::$registry['db'] = $db; // save for future reference within model classes require 'Zend/Controller/Front.php'; $frontController = Zend_Controller_Front::getInstance(); // manages the overall workflow $frontController->setControllerDirectory(array('default' => $appDir . 'default' . $ds . 'controllers', 'forum' => $appDir . 'forum' . $ds . 'controllers')); // Initialize views require 'Zend/View.php'; self::$view = new Zend_View($config->view->toArray()); self::$view->strictVars(); // enables tracking/detection of typos and misspelled variables in views // do not show sensitive logs to requests from non-local networks if (self::isLocalRequest()) { self::$view->showLog = $config->view->showLog; } self::$view->sectionName = basename($installDir); // e.g. "section4_mvc" self::$view->viewSuffix = 'phtml'; // file name suffix for view script // default location shared by all modules self::$view->setScriptPath($appDir . 'default' . $ds . 'views' . $ds . 'scripts'); ZFDemo_Log::log("scriptPaths=\n " . implode("\n ", self::$view->getScriptPaths())); self::$view->timezone = $config->timezone; // default timezone self::$view->now = $now = date('Y-m-d H:i:s'); ///////////////////////////// // ==> SECTION: mvc <== // Cause controllers to use private views, but with inheritance (i.e. defaults in self::$view) $frontController->setParam('view', clone self::$view); // make private presentation model for controller $frontController->setParam('registry', self::$registry); // alternative to Zend_Registry::getInstance() ////////////////////////////// // ==> SECTION: session <== // Enable tracking of all user sessions $sessionConfig = new Zend_Config_Ini($configDir . 'Zend_Session.ini', self::$environment, true); $sessionConfig->save_path = $temporaryDir . $sessionConfig->save_path; ZFDemo_Log::log("Zend_Session.ini=" . print_r($sessionConfig->toArray(), true)); require 'Zend/Session.php'; Zend_Session::setOptions($sessionConfig->toArray()); Zend_Session::start(); // configure the zfdemo session namespace container $zfSpace = new Zend_Session_Namespace('zfdemo'); $time = time(); if (!isset($zfSpace->startTime)) { Zend_Session::regenerateId(); // security feature $zfSpace->startDate = $now; $zfSpace->startTime = $time; $zfSpace->requests = 1; } else { if (isset($zfSpace->lastVisit)) { $zfSpace->priorVisit = $zfSpace->lastVisit; } else { $zfSpace->priorVisit = $time; } $zfSpace->lastVisit = $time; // hours since last request self::$view->welcomeBackHours = floor(($zfSpace->lastVisit - $zfSpace->priorVisit) / 36); ZFDemo_Log::log("welcomeBackHours = " . self::$view->welcomeBackHours); $zfSpace->requests++; // side-effect: our session data-store modification time stays current with last visit } return $frontController; }
public static function bootstrap($installDir) { if (self::testEnvironment() === false) { echo 'Environment fails to meet minimum requirements for this demo tutorial.'; return; } // where to find this application's configuration (using Conventional Modular Layout) $ds = DIRECTORY_SEPARATOR; // too much typing ;) if ($installDir[0] === '/') { $tmp = $installDir; } else { $tmp = dirname(__FILE__) . $ds . '..' . $ds . '..' . $ds . 'zfdemo' . $ds . $installDir; } // STAGE 0: Initializations / Loading Configuration ZFDemo_Log::log("looking for application directory in: realpath({$tmp}" . $ds . ')'); $appDir = realpath($tmp) . $ds; ZFDemo_Log::log('$appDir =' . $appDir); self::$registry = Zend_Registry::getInstance(); self::$registry['appDir'] = $appDir; if (!is_readable($appDir)) { ZFDemo_Log::log("ERROR: Application directory is not readable (path problem).\n", true); return false; } // this application's configuration information $configDir = realpath($appDir . $ds . 'config' . $ds) . $ds; self::$registry['configDir'] = $configDir; ZFDemo_Log::log('$configDir =' . $configDir); if (!is_readable($configDir)) { ZFDemo_Log::log("ERROR: Application configuration directory 'config' is not readable (path problem).\n", true); return false; } // persistent dynamic data, like log files or SQLite files $dataDir = realpath($appDir . $ds . 'data' . $ds) . $ds; self::$registry['dataDir'] = $dataDir; ZFDemo_Log::log('$dataDir =' . $dataDir); if (!is_readable("{$dataDir}")) { ZFDemo_Log::log("ERROR: Application 'data' directory is not readable (path problem).\n", true); return false; } // temporary data, like PHP session state files $temporaryDir = realpath($appDir . $ds . 'temporary' . $ds) . $ds; self::$registry['temporaryDir'] = $temporaryDir; ZFDemo_Log::log('$temporaryDir =' . $temporaryDir); if (!is_readable("{$temporaryDir}")) { ZFDemo_Log::log("ERROR: Application 'temporary' directory is not readable (path problem).\n", true); return false; } // add the application-specific source file path to PHP's include path for the Conventional Modular Layout set_include_path($appDir . PATH_SEPARATOR . get_include_path()); ZFDemo_Log::log("PHP Include Path = \n " . str_replace(':', "\n ", ini_get('include_path'))); self::$environment = 'sandbox'; // after this point, all defaults come from config files require 'Zend/Config/Ini.php'; $config = new Zend_Config_Ini($configDir . 'config.ini', self::$environment, true); ZFDemo_Log::log("config.ini=" . print_r($config->asArray(), true)); if (strpos($config->log, '/') !== 0) { $config->log = $dataDir . $config->log; } self::$registry['config'] = $config; // application configuration array date_default_timezone_set($config->timezone); $sessionConfig = new Zend_Config_Ini($configDir . 'Zend_Session.ini', self::$environment, true); $sessionConfig->save_path = $temporaryDir . $sessionConfig->save_path; ZFDemo_Log::log("Zend_Session.ini=" . print_r($sessionConfig->asArray(), true)); require 'Zend/Session.php'; Zend_Session::setOptions($sessionConfig->asArray()); Zend_Session::start(); /* * The zfdemo will not work unless the following code results creates a session file * in your save_path folder, * with file contents like: * foo|a:2:{s:3:"bar";s:5:"apple";s:4:"time";s:19:"2007-02-20 21:30:36";} */ $testSpace = new Zend_Session_Namespace('spaceFoo'); $testSpace->keyBar = 'valueBar'; $testSpace->time = time(); $testSpace->date = date('Y-m-d H:i:s'); // preemptively write session file now Zend_Session::writeClose(); self::testPdo($config); // sanity check connection and zfdemo tables using PDO // Now test using ZF's MySQL PDO DB adapter: require 'Zend/Db.php'; require 'Zend/Db/Adapter/Pdo/Mysql.php'; // setup our DB adapter $db = new Zend_Db_Adapter_Pdo_Mysql($config->db->asArray()); self::$registry['db'] = $db; self::testDb($db); // sanity check connection and zfdemo tables using Zend Db Adapter // STAGE 1: Prepare the front (primary) controller. require 'Zend/Controller/Front.php'; $frontController = Zend_Controller_Front::getInstance(); // manages the overall workflow $baseUrl = substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], '/index.php')); ZFDemo_Log::log("baseUrl={$baseUrl}"); //$frontController->setBaseUrl($baseUrl); $frontController->setControllerDirectory(array('default' => $appDir . 'default' . $ds . 'controllers', 'forum' => $appDir . 'forum' . $ds . 'controllers')); // Initialize views require 'Zend/View.php'; self::$view = new Zend_View(); self::$view->sectionName = basename($installDir); // e.g. "section1_install" self::$view->setScriptPath($appDir . 'default' . $ds . 'views'); self::$view->showLog = true; ZFDemo_Log::log("scriptPaths=\n " . implode("\n ", self::$view->getScriptPaths())); $frontController->setParam('view', self::$view); // STAGE 2: Find the right action and execute it. // Use routes to calculate controllers and actions to execute // Dispatch calculated actions of the selected controllers $frontController->returnResponse(true); // return the response (do not echo it to the browser) // Use UTF-8. See "1. Content-type, Charset, DOCTYPE" in NOTES.txt require_once 'Zend/Controller/Response/Http.php'; $response = new Zend_Controller_Response_Http(); $response->setHeader('Content-type', 'text/html; charset=utf-8', true); $response->setBody(self::$view->render('header.php')); try { require_once 'Zend/Controller/Request/Http.php'; $request = new Zend_Controller_Request_Http(); // show exceptions immediately, instead of adding to the response $frontController->throwExceptions(true); // without this no exceptions are thrown // similar to "running" the configured MVC "program" $frontController->dispatch($request, $response); } catch (Zend_Controller_Dispatcher_Exception $exception) { self::analyzeError($frontController->getDispatcher(), $exception, $request, $response); return false; } // STAGES 3 to 5 occur in an action controller: /zfdemo/forum/*/controllers/*Controller.php // STAGE 6 occurs in a view template: /zfdemo/forum/*/views/*.phtml /** * STAGE 7: Render results in response to request. */ $response->renderExceptions(true); // show any excpetions in the visible output (i.e. debug mode) // OR: Handle exceptions thrown in the dispatch loop. // Examine the exception type, and then redirect to an error page. ksort($_SERVER); self::$view->SERVER = $_SERVER; self::$view->log = ZFDemo_Log::get(); $response->appendBody(self::$view->render('footer.php'), 'footer'); //Zend::debug($frontController->getRequest());exit // debug the request object //Zend_Debug::dump($response);exit; // examine the inner details of the response object $response->sendResponse(); // send final results to browser, including headers }