Example #1
0
/**
 * Find and load the real ZFDemo bootstrap.php file
 */
function ZFDemoGrub($installDir, $configEnv)
{
    error_reporting(E_ALL | E_STRICT);
    // verbose
    $ds = DIRECTORY_SEPARATOR;
    // too much typing ;)
    // where to find this application's configuration (using Conventional Modular Layout)
    if ($installDir[0] === $ds) {
        $tmp = $installDir;
        $appDir = $tmp;
        // skip costly realpath($tmp)
    } else {
        $tmp = dirname(__FILE__) . $ds . '..' . $ds . '..' . $ds . 'zfdemo' . $ds . $installDir;
        $appDir = realpath($tmp) . $ds;
    }
    // show installation help, if loading bootstrap fails
    if ((include $appDir . 'bootstrap.php') === false) {
        $log = "Looking for application directory in:\n    realpath({$tmp}" . $ds . ")\n";
        $log .= "    = {$appDir}bootstrap.php\n";
        $file = __FILE__;
        echo <<<EOD
            <html><head><title>ZFDemo - Installation problem</title></head><body>
            <pre>{$log}</pre>
            <h1>Instructions</h1>
            <p>Check for existence and permissions of the directories above.</p>
            <p>Then edit "\$installDir" in this file ( {$file} ).</p>
            <p>See also: <a href="http://framework.zend.com/wiki/display/ZFDEV/Tutorial"
            >http://framework.zend.com/wiki/display/ZFDEV/Tutorial</a></p>
            </body></html>
EOD;
        exit;
    }
    if (false === ZFDemo::bootstrap($installDir, $appDir, $configEnv)) {
        // Run!
        ZFDemo_log::show();
    }
}
Example #2
0
 /**
  * STAGE 2: Find the right action and execute it.
  */
 public static function stage2($frontController)
 {
     /////////////////////////////
     // ==> SECTION: mvc <==
     $frontController->returnResponse(true);
     // return the response (do not echo it to the browser)
     // show exceptions immediately, instead of adding to the response
     $frontController->throwExceptions(true);
     // without this no exceptions are thrown
     $config = self::$registry['config'];
     require 'lib/Controller/Action.php';
     // ZFDemo's customized Zend_Controller_Action
     require_once 'Zend/Controller/Request/Http.php';
     $request = new Zend_Controller_Request_Http();
     require_once 'Zend/Controller/Response/Http.php';
     $response = new Zend_Controller_Response_Http();
     $response->append('body', '');
     // initialize a body segment
     // safety shutoff, in case controllers are stuck in loop, each calling the other
     $maxDispatches = isset($config->maxDispatches) ? $config->maxDispatches : 5;
     // rerouteTo will designate either an error code (mapped to error controller), or module/controller/action
     $rerouteTo = $didRerouteTo = $rerouteToReason = null;
     if (isset(self::$registry['testDbFailed']) && substr($request->getRequestUri(), -12) !== '/index/reset') {
         // during STAGE 1, sanity check of the DB connection/tables failed, so reroute to informative page
         $rerouteTo = self::reroute($request, self::$registry['config']->testDbFailed, $frontController);
     }
     do {
         if ($rerouteTo) {
             // if a reroute was requested, process it now
             $didRerouteTo = self::reroute($request, $rerouteTo, $frontController, $rerouteToReason);
             $rerouteToReason = $rerouteTo = null;
         }
         /////////////////////////////
         // ==> SECTION: mvc <==
         try {
             // "Run" the configured MVC "program" - the calculated action of the selected controller
             $frontController->dispatch($request, $response);
         } catch (ZFDemo_Exception_Reroute $exception) {
             // action controller requested a reroute form of internal redirection
             $rerouteTo = $exception->getRouteTo();
             $suggestedHttpCode = $exception->getHttpCode();
             $rerouteToReason = 'Reroute: ' . $exception->getMessage() . '; ' . $exception->responseCodeAsText();
         } catch (Exception $exception) {
             // don't allow *any* exceptions to end this script, without handling them properly
             if (!$config->analyzeDispatchErrors) {
                 // we are not analyzing the errors, so
                 self::doExit(404, $exception);
                 // log event and exit
             }
             /////////////////////////////
             // ==> SECTION: except <==
             list($suggestedHttpCode, $rerouteToReason) = self::analyzeError($exception, $request, $response);
             // if we have not already tried dispatching this controller code
             if ($didRerouteTo['code'] !== $suggestedHttpCode) {
                 $rerouteTo = $suggestedHttpCode;
                 #$rerouteToReason = $exception->getMessage();
             } else {
                 // Already tried to dispatch the selected error controller, so now fail hard.
                 ZFDemo_Log::logDispatchFailure($didRerouteTo);
                 if (self::isLocalRequest() && $config->view->showLog) {
                     echo ZFDemo_Log::get($exception);
                 }
                 // Reader excercise: make output "pretty" when dispatching error controller fails
                 self::doExit($suggestedHttpCode, $exception, is_int($didRerouteTo['code']) && $didRerouteTo['code'] > 400 ? _('An additional error occurred while trying to use the error action controller.') : '');
             }
         }
     } while ($rerouteTo && --$maxDispatches);
     // now loop to dispatch the alternative controller (if any)
     if ($maxDispatches === 0) {
         ZFDemo_Log::log(_('ERROR Too many reroutes. Controllers stuck in loop?') . $request->getRequestUri());
     }
     /////////////////////////////
     // ==> SECTION: except <==
     if (isset($suggestedHttpCode) && $suggestedHttpCode != 200) {
         // something unusual happened during dispatch, like a 404 or 500 error
         self::setHeaderStatus($suggestedHttpCode);
     }
     /////////////////////////////
     // ==> SECTION: mvc <==
     $baseUrl = $request->getBaseUrl();
     // save for use in header/footer/site templates
     if (false === strpos($baseUrl, '/index.php')) {
         $baseUrl .= '/index.php';
     }
     self::$view->baseUrl = $baseUrl;
     if (ZFDemo::isLocalRequest()) {
         // Since this is only added for local network requests, this code
         // may remain in production applications to aid in ongoing development.
         // Add some helpful debugging information for inserting into HTML comments:
         self::$view->controller = $request->getControllerName();
         self::$view->module = $request->getModuleName();
         self::$view->action = $request->getActionName();
     }
     return $response;
 }
Example #3
0
 /**
  * Modules are semi-standalone, encapsulated "mini" applications.
  * Thus, there is a need for a global module initialization process,
  * for the dispatched module to provide shared initializations for
  * all controllers within this module.
  */
 public function preDispatch(Zend_Controller_Request_Abstract $request)
 {
     $frontController = Zend_Controller_Front::getInstance();
     $moduleName = $request->getModuleName();
     $registry = Zend_Registry::getInstance();
     $moduleInit = $registry['appDir'] . $moduleName . DIRECTORY_SEPARATOR . $moduleName . '.php';
     $modulesIni = $registry['configDir'] . 'modules.ini';
     // If a module has an initialization / authorization component
     if (is_readable($moduleInit)) {
         include_once $moduleInit;
         if (!isset($registry['config']->cache)) {
             // if caching of module ini files is not enabled, just load it now
             $config = new Zend_Config_Ini($modulesIni, $moduleName);
         }
         /////////////////////////////
         // ==> SECTION: auth <==
         $rerouteTo = null;
         /* Allow modules.ini to disable anonymous access to individual modules.
          * Authenticate #2  ( see "Authenticate Where?" http://framework.zend.com/wiki/x/fUw )
          */
         if (empty($config->allowAnonymousUse)) {
             if (empty($registry['authenticationId'])) {
                 // if not already authenticated
                 $rerouteTo = $config->authenticate;
             }
         }
         if ($rerouteTo === null) {
             // Access control could also be selectively applied to entire modules, instead of inside the module:
             $rerouteTo = call_user_func(array('ZFModule_' . ucfirst($moduleName), 'moduleAuth'), $config, $request);
         }
         if ($rerouteTo) {
             if (--$this->maxDispatches > 0) {
                 if ($rerouteTo == $this->didRerouteTo) {
                     $msg = _('ERROR Looping detected in preDispatch().') . $request->getRequestUri();
                     ZFDemo_Log::log($msg);
                     throw new ZFDemo_Exception_Reroute($msg, 500);
                 }
                 ZFDemo::reroute($request, $rerouteTo, $frontController, null, true);
                 $this->didRerouteTo = $rerouteTo;
             } else {
                 $msg = _('ERROR Too many reroutes in preDispatch(). Looping?') . $request->getRequestUri();
                 ZFDemo_Log::log($msg);
                 throw new ZFDemo_Exception_Reroute($msg, 500);
             }
         }
     }
     // dynamic configurations, DRY, O(1) with respect to number of modules
     // http://framework.zend.com/issues/browse/ZF-1125
     // $frontController->setControllerDirectory(array($moduleName => Zend_Registry::get('appDir')
     //     . $moduleName . $ds . 'controllers'));
     return;
 }
Example #4
0
 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
 }
 /**
  * The default action is "indexAction", unless explcitly set to something else.
  */
 public function indexAction()
 {
     // STAGE 4: Apply business logic to create a presentation model for the view.
     $origRequest = $this->getInvokeArg('origRequest');
     $this->view->rerouteToReason = $this->getInvokeArg('rerouteToReason');
     $this->view->origRequestUri = $origRequest->REQUEST_URI;
     // if no credentials
     if (empty($_REQUEST['username'])) {
         // should be _POST, but this makes demo easier to tweak
         // STAGE 5: Choose view template and submit presentation model to view template for rendering.
         // if an admin area was requested, and authentication has been enabled in config.ini
         if (isset($this->authSpace->authenticationId)) {
             ZFDemo_Log::log(_('already have authentication id, showing logout form'));
             $this->_forward('logoutDecision');
             // show logout form
         } else {
             ZFDemo_Log::log(_('no authentication id, showing login form'));
             $this->renderToSegment('body');
             // show login form
         }
         return;
     }
     // prepare to authenticate credentials received from a form
     require_once 'Zend/Auth/Result.php';
     require_once 'Zend/Auth/Adapter/Digest.php';
     $config = Zend_Registry::get('config');
     $username = trim($_REQUEST['username']);
     // ought to be _POST, but this simplifies experimentation
     $password = trim($_REQUEST['password']);
     // by the reader of the tutorial
     // filtering will be added in a later section
     /////////////////////////////
     // ==> SECTION: filter <==
     require_once 'Zend/Validate/Alnum.php';
     require_once 'Zend/Validate/Regex.php';
     // input filtering is enabled, so ..
     $validator_name = new Zend_Validate_Alnum();
     // alphabetic and numeric characters are permitted
     if (!$validator_name->isValid($username)) {
         $this->renderToSegment('body', 'invalidUsername');
         return;
     }
     // this application has "special" requirements, so we show how to use custom regex:
     $validator_password = new Zend_Validate_Regex('/^[a-z0-9_]{5,16}$/');
     if (!$validator_password->isValid($password)) {
         $this->renderToSegment('body', 'invalidPassword');
         return;
     }
     /////////////////////////////
     // ==> SECTION: auth <==
     $result = false;
     try {
         // try to authenticate using the md5 "digest" adapter
         $filename = $config->authenticate->filename;
         // file containing username:realm:password digests
         if ($filename[0] !== DIRECTORY_SEPARATOR) {
             $filename = Zend_Registry::get('dataDir') . $filename;
             // prepend path, if filename not absolute
         }
         $adapter = new Zend_Auth_Adapter_Digest($filename, $config->authenticate->realm, $username, $password);
         $result = $adapter->authenticate();
         // result of trying to authenticate credentials
         $this->view->resultCode = $result->getCode();
         // allow view to see result status (reason)
     } catch (Exception $exception) {
         $this->view->exception = ZFDemo::filterException($exception);
         // record exception description
         $this->view->resultCode = false;
     }
     if ($result && $result->isValid()) {
         // if successful authentication, save the authentication identity ( http://framework.zend.com/wiki/x/fUw )
         $id = $result->getIdentity();
         Zend_Registry::set('authenticationId', $id);
         // publish the identity (really need Observer pattern)
         $this->authSpace->authenticationId = $id;
         $this->authSpace->date = time();
         // save the timestamp when authenticated successfully
         $this->authSpace->attempts = 0;
         // success, so forget the number of previous login failures
         // @TODO: filter this ...
         $this->_redirect($_REQUEST['origPathInfo']);
         // now return to wherever user came from
     } else {
         $this->authSpace->attempts++;
         // record the authentication failure
         if ($this->authSpace->attempts > $config->authenticate->maxAttempts) {
             // Overly simplistic account "lockout" lasts for at least 10 seconds,
             // but increases with repeated failures.
             $this->view->lockout = 5 * $this->authSpace->attempts;
             // Lockout time will be "forgotten" later, and expired from session, allowing logins.
             $this->authSpace->setExpirationSeconds($this->view->lockout);
             $this->blockHacker();
             // show a view indicating account lockout
             return;
         }
     }
     // STAGE 5: Choose view template and submit presentation model to view template for rendering.
     $this->renderToSegment('body');
 }
Example #6
0
 /**
  * STAGE 2: Find the right action and execute it.
  */
 public static function stage2($frontController)
 {
     /////////////////////////////
     // ==> SECTION: mvc <==
     $frontController->returnResponse(true);
     // return the response (do not echo it to the browser)
     // show exceptions immediately, instead of adding to the response
     $frontController->throwExceptions(true);
     // without this no exceptions are thrown
     $config = self::$registry['config'];
     require 'lib/Controller/Action.php';
     // ZFDemo's customized Zend_Controller_Action
     require_once 'Zend/Controller/Request/Http.php';
     $request = new Zend_Controller_Request_Http();
     require_once 'Zend/Controller/Response/Http.php';
     $response = new Zend_Controller_Response_Http();
     $response->append('body', '');
     // initialize a body segment
     /////////////////////////////
     // ==> SECTION: mvc <==
     try {
         // "Run" the configured MVC "program" - the calculated action of the selected controller
         $frontController->dispatch($request, $response);
     } catch (Exception $exception) {
         // don't allow *any* exceptions to end this script, without handling them properly
         if (!$config->analyzeDispatchErrors) {
             // we are not analyzing the errors, so
             self::doExit(404, $exception);
             // log event and exit
         }
     }
     /////////////////////////////
     // ==> SECTION: mvc <==
     $baseUrl = $request->getBaseUrl();
     // save for use in header/footer/site templates
     if (false === strpos($baseUrl, '/index.php')) {
         $baseUrl .= '/index.php';
     }
     self::$view->baseUrl = $baseUrl;
     if (ZFDemo::isLocalRequest()) {
         // Since this is only added for local network requests, this code
         // may remain in production applications to aid in ongoing development.
         // Add some helpful debugging information for inserting into HTML comments:
         self::$view->controller = $request->getControllerName();
         self::$view->module = $request->getModuleName();
         self::$view->action = $request->getActionName();
     }
     return $response;
 }