예제 #1
0
 /**
  * STAGE 3: Choose, create, and optionally update models using business logic.
  * STAGE 4: Apply business logic to create a presentation model for the view.
  */
 public function editAction()
 {
     $config = Zend_Registry::get('config');
     // application-wide configuration ini
     if ($config->db->modelSet === 'pdo') {
         $this->renderToSegment('body', 'addedInSectionDb');
         // initiate STAGE 6 in the view template
     }
     /////////////////////////////
     // ==> SECTION: db <==
     // ZFDemoModel_Topics provides static methods that auto-instantiate and manage the model
     $topics = ZFDemoModel_Topics::getDomainModel();
     $deletedRows = array();
     // list of deleted topics indexed by topic id
     $visible = array();
     // visibility settings indexed by topic id
     $changedRows = array();
     // list of altered topic rows
     ZFDemo_Log::log(_('INFO BEGIN editAction()'));
     try {
         // iterate over the form variable, queing actions for each change requested
         foreach ($_POST as $var => $val) {
             if (!strncmp($var, 'delete', 6)) {
                 $id = intval(substr($var, 6));
                 if (isset($topics[$id])) {
                     $deletedRows[$id] = $topics[$id];
                     ZFDemo_Log::log(_('INFO deleting topic id #%1$d', $id));
                 }
             } elseif (!strncmp($var, 'visible', 7)) {
                 $id = intval(substr($var, 7));
                 if (isset($topics[$id])) {
                     $visible[$id] = 1;
                     // ask Zend_Db_Table_Row to delete itself
                 }
             }
         }
         // for every topic, make sure visibility setting matches the selections submitted via the form
         foreach ($topics as $id => $row) {
             if (!isset($deletedRows[$id])) {
                 // don't update a row that will be deleted
                 if (!isset($visible[$id])) {
                     // the checkbox for visibility of this topic was not checked
                     $visible[$id] = 0;
                     // web interface defaults to checking visible topics, so unchecked means not visible
                 }
                 if ($row->is_visible != $visible[$id]) {
                     ZFDemo_Log::log(_('INFO topic id %1$d visibility set to %2$d', $id, $visible[$id]));
                     $row->is_visible = $visible[$id];
                     $changedRows[$id] = $row;
                     // add this row to the list of changed rows
                 }
             }
         }
         // now commit changes to DB
         $registry = Zend_Registry::getInstance();
         if (!$registry['config']->db->transactions) {
             // note: query aggregation would help performance (reader excercise)
             foreach ($deletedRows as $row) {
                 $row->delete();
                 // now do all the deletes at once
             }
             foreach ($changedRows as $row) {
                 $row->save();
                 // now synchronize all the modified rows with the table
             }
         } else {
             // table type supports transactions
             $db = $registry['db'];
             $db->beginTransaction();
             try {
                 // note: query aggregation would help performance (reader excercise)
                 foreach ($deletedRows as $row) {
                     $row->delete();
                     // now do all the deletes at once
                 }
                 foreach ($changedRows as $row) {
                     $row->save();
                     // now synchronize all the modified rows with the table
                 }
                 $db->commit();
             } catch (Exception $exception) {
                 $db->rollBack();
                 // re-throw the exception
                 throw $exception;
                 // allow normal processing by the preDispatch() of the plugin in bootstrap.php
             }
         }
     } catch (Exception $exception) {
         ZFDemo_Log::log(_('ERROR END editAction() - failed'));
         throw $exception;
         // resume normal processing of the exception
     }
     ZFDemo_Log::log(_('NOTICE END editAction() - succeeded'));
     // Controller = 'index', Action = 'index'
     $this->setRedirectCode(303);
     // PRG pattern via http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
     $this->_redirect('forum/admin_topics');
 }
예제 #2
0
 /**
  * Accumulate log messages, but also append them to a running log file for easy viewing.
  */
 public static function log($msg, $before = null)
 {
     static $flushed = false;
     if ($before) {
         self::$_log = "{$msg}\n" . self::$_log;
     } else {
         self::$_log .= "{$msg}\n";
     }
     $registry = Zend_Registry::getInstance();
     // performance is not an issue for this demo, so just sync to disk everytime
     if (isset($registry['config'])) {
         if ($flushed) {
             file_put_contents($registry['config']->log, "{$msg}\n", FILE_APPEND);
         } else {
             file_put_contents($registry['config']->log, self::$_log);
             $flushed = true;
         }
     }
 }
예제 #3
0
 /**
  * Initialize the module by mapping any authentication id into the forum system's user table,
  * and performing access control on forum controllers and actions.
  * @return Zend_Config|null  Zend_Config should contain keys mapping to module/controller/action for a reroute
  */
 public static function moduleAuth(Zend_Config $config, Zend_Controller_Request_Abstract $request)
 {
     // access the session namespace 'auth' to see if user is authenticated
     $authSpace = new Zend_Session_Namespace('auth');
     if (!empty($authSpace->authenticationId)) {
         // try mapping the application's concept of authentication id to this module's authorization id
         self::authenticationId2authorizationId($authSpace->authenticationId);
     }
     /* Variant of "Authenticate #2" ( see "Authenticate Where?" http://framework.zend.com/wiki/x/fUw )
      * This point in the flow of execution also enables us to examine the module's
      * interpretation of the authentication id.
      * If anonymous use has been disabled in this module's settings in "modules.ini",
      * and the user was not recognized by this module's authenticationId2authorizationId(), then
      */
     if (empty($config->allowAnonymousUse) && empty(self::$_authorizationId)) {
         return $config->authenticate;
         // allow front controller plugin to redirect in preDispatch()
         // Reader excercise: redirect to something with a "prettier" explanation message
     }
     if (!$config->acl) {
         // ACL has been enabled in "modules.ini" for this module
         return;
     }
     /////////////////////////////
     // ==> SECTION: acl <==
     require_once 'Zend/Acl.php';
     require_once 'Zend/Acl/Role.php';
     // Use the default ZF "role" class
     require_once 'Zend/Acl/Resource.php';
     // Use the default ZF "resource" class
     /////////////////////////////
     // ==> SECTION: perf <==
     // Create a caching system from a frontend and backend system using options from "modules.ini"
     $back = $config->cache->back->toArray();
     $back['cacheDir'] = Zend_Registry::get('temporaryDir') . DIRECTORY_SEPARATOR . 'modules';
     $cache = Zend_Cache::factory('Core', 'File', $config->cache->front->toArray(), $back);
     // BEWARE!!! If you change something below, *delete* the cache file in temporary/Zend
     if (!($acl = $cache->load(__CLASS__))) {
         /////////////////////////////
         // ==> SECTION: acl <==
         // Reader excercise: load the following from a config file
         $acl = new Zend_Acl();
         $acl->add(new Zend_Acl_Resource('posts'));
         // add() is really addResource()
         $acl->add(new Zend_Acl_Resource('topics'));
         // add resource 'topics' to our ACL
         $acl->add(new Zend_Acl_Resource('submissions'));
         // add resource 'topics' to our ACL
         $acl->addRole(new Zend_Acl_Role('anonymous'));
         // 'anonymous' role does not inherit access controls from any role
         $acl->allow('anonymous', 'posts', 'display');
         // grant "display" privileges on posts
         $acl->allow('anonymous', 'topics', 'display');
         // grant "display" privileges on topics
         // also works:
         // $acl->allow('anonymous', array('posts', 'topics'),  'display');
         // 'member' role inherits from 'anonymous' role
         $acl->addRole(new Zend_Acl_Role('member'), 'anonymous');
         // grant 'member' role ability to add/submit posts
         $acl->allow('member', 'submissions', 'post');
         // 'moderator' role inherits from 'member' role
         $acl->addRole(new Zend_Acl_Role('moderator'), 'member');
         // grant 'moderator' role ability to hide and delete posts
         $acl->allow('moderator', 'posts', array('visible', 'delete'));
         $acl->allow('moderator', null, 'display');
         // moderators can display everything
         $acl->addRole(new Zend_Acl_Role('admin'));
         // inherit no constraints
         $acl->allow('admin');
         // grant all privileges on all resources to 'admin' role
         $acl->add(new Zend_Acl_Resource('sorry'));
         // add resource for the "sorry" controller
         $acl->allow(null, 'sorry', 'display');
         // grant display privilege for "sorry" messages to all roles
         $acl->allow(array('member', 'moderator', 'admin'), 'submissions', null);
         // allow them to add posts
         /////////////////////////////
         // ==> SECTION: perf <==
         $cache->save($acl, __CLASS__);
     } else {
         // $acl is automatically unserialized from the cache hit retrieved from the cache
     }
     /////////////////////////////
     // ==> SECTION: acl <==
     // NORMALIZE information needed for ACL check
     $controller = $request->getControllerName();
     $action = $request->getActionName();
     // map default privilege to correct privilege name
     if ($action === 'index') {
         $action = 'display';
     }
     // map default resource to correct resource name
     if ($controller === 'index') {
         $controller = 'posts';
     }
     // determine the role of the current user
     $role = self::$_user ? self::$_user->role : 'anonymous';
     // if the controller has been defined as a resource in the ACL, then check the ACL
     if ($acl->has($controller)) {
         $isAllowed = $acl->isAllowed($role, $controller, $action);
     } else {
         // allow access by admins for controllers not registered in the ACL
         $isAllowed = $role === 'admin' ? true : false;
     }
     ZFDemo_Log::log("acl->isAllowed(role: {$role}, resource: {$controller}, permission: {$action}) = " . ($isAllowed ? 'true' : 'false') . "\n");
     if (!$isAllowed) {
         // if the request was not allowed, then
         // redirect to this module's "unauthorized" setting in "modules.ini"
         return $config->unauthorized;
         // front controller plugin will perform redirection in preDispatch()
     }
 }
예제 #4
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;
 }
예제 #5
0
 /**
  * logoff, and show logon page
  */
 public function logoutAction()
 {
     ZFDemo_Log::log('logout');
     // STAGE 3: Choose, create, and optionally update models using business logic.
     Zend_Session::namespaceUnset('auth');
     // remove the authentication id and information
     Zend_Registry::set('authenticationId', 0);
     // really need observer pattern
     // STAGE 4: Apply business logic to create a presentation model for the view.
     // STAGE 5: Choose view template and submit presentation model to view template for rendering.
     $this->_forward('index');
     // possibly valid topic, so try to show its posts
 }