/ */ class User_Module extends P4Cms_Module_Integration { /** * Subscribe to the relevant topics. */ public static function init() { // add default roles when site is created. P4Cms_PubSub::subscribe('p4cms.site.created', function(P4Cms_Site $site, P4Cms_User $administrator) { $adapter = $administrator->getPersonalAdapter(); $systemUser = $site->getConnection()->getUser(); // create author and editor roles $roles = array('author', 'editor'); foreach ($roles as $id) { $role = new P4Cms_Acl_Role; $role->setAdapter($adapter) ->setId($id) ->addOwner($systemUser) ->save(); } } ); // update acl when a site is created. P4Cms_PubSub::subscribe('p4cms.site.created', function(P4Cms_Site $site, P4Cms_User $admin) { $acl = $site->getAcl(); // need an admin adapter to write to acl // when a site is created, arg 2 is the admin user // when a module is enabled, the active user is admin $acl->getRecord()->setAdapter($admin->getPersonalAdapter()); $acl->installDefaults(); // on a P4 server using external authentication, remove the // 'Add User' privilege for other users except for administrator if ($site->getConnection()->hasExternalAuth()) { $nonAdminRoles = array_diff($acl->getRoles(), array('administrator')); $acl->removeAllow($nonAdminRoles, 'users', 'add'); } $acl->save(); } ); // update acl when a module is enabled. P4Cms_PubSub::subscribe('p4cms.site.module.enabled', function(P4Cms_Site $site, P4Cms_Module $module) { $acl = $site->getAcl(); $acl->installModuleDefaults($module)->save(); } ); // update acl when a module is disabled P4Cms_PubSub::subscribe('p4cms.site.module.disabled', function(P4Cms_Site $site, P4Cms_Module $module) { $acl = $site->getAcl(); $acl->removeModuleDefaults($module)->save(); } ); // provide dynamic user-based menu items P4Cms_PubSub::subscribe('p4cms.navigation.dynamicHandlers', function() { // expand the 'login' / 'logout' menu item $handler = new P4Cms_Navigation_DynamicHandler; $handler->setId('user.login-logout') ->setLabel('Login/Logout') ->setExpansionCallback( function($item, $options) { // add login or logout link as appropriate. if (P4Cms_User::fetchActive()->isAnonymous()) { $item = array( 'label' => 'Login', 'module' => 'user', 'controller' => 'index', 'action' => 'login', 'onClick' => 'p4cms.user.login(this); return false;', 'class' => 'p4cms-user-login user-login', 'order' => 10 ); } else { $item = array( 'label' => 'Logout', 'module' => 'user', 'controller' => 'index', 'action' => 'logout', 'class' => 'p4cms-user-logout user-logout', 'order' => 10 ); } return array($item); } )->setFormCallback( function(Zend_Form $form) { $form->removeElement(P4Cms_Menu::MENU_MAX_DEPTH); $form->removeElement(P4Cms_Menu::MENU_MAX_ITEMS); $form->removeElement(P4Cms_Menu::MENU_ROOT); return $form; } ); return array($handler); } ); // provide 'user' macro. P4Cms_PubSub::subscribe('p4cms.macro.user', function($params, $body, $context) { $field = isset($params[0]) ? $params[0] : 'id'; $user = P4Cms_User::fetchActive(); // add support for a 'firstName' field. if ($field == 'firstName') { return current(explode(' ', $user->getFullName(), 2)); } return $user->hasField($field) ? $user->getValue($field) : null; } ); // provide form to filter users by roles P4Cms_PubSub::subscribe('p4cms.user.grid.form.subForms', function(Zend_Form $form) { $roles = P4Cms_Acl_Role::fetchAll()->invoke('getId'); // early exit if there are no roles if (!count($roles)) { return; } $form = new P4Cms_Form_SubForm; $form->setName('role') ->setAttrib('class', 'site-role-form') ->setOrder(10) ->addElement( 'MultiCheckbox', 'roles', array( 'label' => 'Roles', 'autoApply' => true, 'multiOptions' => array_combine($roles, $roles) ) ); return $form; } ); // filter users by roles P4Cms_PubSub::subscribe('p4cms.user.grid.populate', function(P4Cms_Model_Iterator $users, Zend_Form $form) { $values = $form->getValues(); // extract selected roles $roles = isset($values['role']['roles']) ? $values['role']['roles'] : null; // early exit if no role selected if (!$roles) { return null; } // filter users by selected roles $users->filterByCallback( function($user, $roles) { $match = array_intersect($roles, $user->getRoles()->invoke('getId')); return !empty($match); }, $roles ); } ); // provide form to search users P4Cms_PubSub::subscribe('p4cms.user.grid.form.subForms', function(Zend_Form $form) { return new Ui_Form_GridSearch; } ); // filter users by keyword search P4Cms_PubSub::subscribe('p4cms.user.grid.populate', function(P4Cms_Model_Iterator $users, Zend_Form $form) { $values = $form->getValues(); // extract search query. $query = isset($values['search']['query']) ? $values['search']['query'] : null; // early exit if no query. if (!$query) { return null; } // remove users that don't match search query. return $users->search( array('id', 'fullName', 'email'), $query ); } ); // provide user grid actions P4Cms_PubSub::subscribe('p4cms.user.grid.actions', function($actions) { $actions->addPages( array( array( 'label' => 'Edit', 'onClick' => 'p4cms.user.grid.Actions.onClickEdit();', 'order' => '10' ), array( 'label' => 'Delete', 'onClick' => 'p4cms.user.grid.Actions.onClickDelete();', 'order' => '20' ) ) ); } ); // provide form to filter roles by type P4Cms_PubSub::subscribe('p4cms.user.role.grid.form.subForms', function(Zend_Form $form) { $types = array( 'system' => 'System', 'custom' => 'Custom' ); $form = new P4Cms_Form_SubForm; $form->setName('type') ->setAttrib('class', 'role-type-form') ->setOrder(10) ->addElement( 'MultiCheckbox', 'types', array( 'label' => 'Type', 'autoApply' => true, 'multiOptions' => $types ) ); return $form; } ); // filter roles by type P4Cms_PubSub::subscribe('p4cms.user.role.grid.populate', function(P4Cms_Model_Iterator $roles, Zend_Form $form) { $values = $form->getValues(); // extract selected type $types = isset($values['type']['types']) ? $values['type']['types'] : null; // early exit if no type selected if (!$types) { return null; } // filter roles by selected types $roles->filter('type', $types, P4Cms_Model_Iterator::FILTER_NO_CASE); } ); // provide form to search roles P4Cms_PubSub::subscribe('p4cms.user.role.grid.form.subForms', function(Zend_Form $form) { return new Ui_Form_GridSearch; } ); // filter roles for keyword search P4Cms_PubSub::subscribe('p4cms.user.role.grid.populate', function(P4Cms_Model_Iterator $roles, Zend_Form $form) { $values = $form->getValues(); // extract search query. $query = isset($values['search']['query']) ? $values['search']['query'] : null; // early exit if no query. if (!$query) { return null; } // search/filter roles by query. return $roles->search(array('id', 'type'), $query); } ); // provide role grid actions P4Cms_PubSub::subscribe('p4cms.user.role.grid.actions', function($actions) { $actions->addPages( array( array( 'label' => 'Edit', 'onClick' => 'p4cms.user.role.grid.Actions.onClickEdit();', 'onShow' => 'p4cms.user.role.grid.Actions.onShowEdit(this);', 'order' => '10' ), array( 'label' => 'Delete', 'onClick' => 'p4cms.user.role.grid.Actions.onClickDelete();', 'onShow' => 'p4cms.user.role.grid.Actions.onShowDelete(this);', 'order' => '20' ) ) ); } ); // provide form to search acl permissions P4Cms_PubSub::subscribe('p4cms.user.acl.grid.form.subForms', function(Zend_Form $form) { return new Ui_Form_GridSearch; } ); // filter acl permissions by keyword search. P4Cms_PubSub::subscribe('p4cms.user.acl.permissions', function(P4Cms_Model_Iterator $permissions, Zend_Form $form) { $values = $form->getValues(); // extract search query. $query = isset($values['search']['query']) ? $values['search']['query'] : null; // early exit if no query. if (!$query) { return null; } // remove permissions that don't match search query. return $permissions->search( array('resourceLabel', 'privilegeLabel'), $query ); } ); // provide form to limit acl permissions by resource. P4Cms_PubSub::subscribe('p4cms.user.acl.grid.form.subForms', function(Zend_Form $form) { // collect resource options from acl. $acl = $form->getAcl(); $options = array(); foreach ($acl->getResourceObjects() as $resource) { $options[$resource->getResourceId()] = $resource->getLabel(); } // ensure natural order. natcasesort($options); $form = new P4Cms_Form_SubForm; $form->setName('resource') ->setAttrib('class', 'resource-form') ->setOrder(20) ->addElement( 'MultiCheckbox', 'resources', array( 'label' => 'Resource', 'multiOptions' => $options, 'autoApply' => true, ) ); return $form; } ); // filter acl permissions by resource. P4Cms_PubSub::subscribe('p4cms.user.acl.permissions', function(P4Cms_Model_Iterator $permissions, Zend_Form $form) { $values = $form->getValues(); // extract selected resources. $resources = isset($values['resource']['resources']) ? $values['resource']['resources'] : null; // early exit if no query. if (!$resources) { return null; } // remove permissions that don't match selected resources. return $permissions->filter('resourceId', $resources); } ); // touch-up user add privilege to indicate that super user // access is required if auto user creation is not enabled, or // the P4 server we are connected to uses external authentication. P4Cms_PubSub::subscribe( 'p4cms.acl.users.privileges', function(P4Cms_Acl_Resource $resource) { try { $resource->getPrivilege('add')->setOption( 'needsSuper', !P4_User::isAutoUserCreationEnabled() || P4_Connection::getDefaultConnection()->hasExternalAuth() ); } catch (Exception $e) { // fail silently. return; } } ); // put acl role columns in a prescribed order. P4Cms_PubSub::subscribe( 'p4cms.user.acl.roles', function(P4Cms_Model_Iterator $roles, Zend_Form $form) { $order = array( 'anonymous', 'member', 'author', 'editor', 'administrator' ); $roles->sortBy( array( array('id', array(P4Cms_Model_Iterator::SORT_FIXED => $order)), array('id', array(P4Cms_Model_Iterator::SORT_NO_CASE)) ) ); } ); // move acl file to 'permissions' group for pull operations. P4Cms_PubSub::subscribe( 'p4cms.site.branch.pull.groupPaths', function($paths, $source, $target, $result) { // try to find the config group (fallback to top-level) $parent = $paths->getSubGroups() ->filter('label', 'Configuration', array(P4Cms_Model_Iterator::FILTER_COPY)) ->first(); $parent = $parent ?: $paths; $parent->addSubGroup( array( 'label' => 'Permissions', 'hideCount' => true, 'inheritPaths' => $target->getId() . '/config/acl', 'details' => function($paths) use ($source) { $path = $paths->first(); $details = new P4Cms_Model_Iterator; if ($path) { $details[] = new P4Cms_Model( array( 'conflict' => $path->conflict, 'action' => $path->action, 'type' => 'Configuration', 'label' => 'Permissions' ) ); } return $details; } ) ); } ); } /** * Perform integration operations when the site is loaded. */ public static function load() { // make the current users ID and Roles visible to javascript if (P4Cms_User::hasActive()) { $view = Zend_Layout::getMvcInstance()->getView(); $user = P4Cms_User::fetchActive(); $active = array('id' => $user->getId(), 'roles' => $user->getRoles()->invoke('getId')); $script = "dojo.setObject('p4cms.user.active', " . Zend_Json::encode($active) . ");"; $view->headScript()->appendScript($script); } } }