/web/system/UsersModule/Controller/AdminController.php
PHP | 2540 lines | 1949 code | 191 blank | 400 comment | 335 complexity | 0dc34229062caee81f8f605a41ba28c9 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-3.0, MIT
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * Copyright Zikula Foundation 2009 - Zikula Application Framework
- *
- * This work is contributed to the Zikula Foundation under one or more
- * Contributor Agreements and licensed to You under the following license:
- *
- * @license GNU/LGPLv3 (or at your option, any later version).
- * @package Zikula
- * @subpackage Users
- *
- * Please see the NOTICE file distributed with this source code for further
- * information regarding copyright and licensing.
- */
- namespace UsersModule\Controller;
- use Zikula\Core\Event\GenericEvent;
- use Zikula_View, SecurityUtil, ModUtil, UserUtil, DataUtil, DateUtil, LogUtil, System, FileUtil;
- use DateTime, DateTimeZone, Exception;
- use Zikula_Session;
- use \Zikula\Framework\Exception\ForbiddenException;
- use UsersModule\Constants as UsersConstant;
- use Zikula\Framework\Exception\FatalException;
- use Zikula\Core\Hook\ProcessHook;
- use Zikula\Core\Hook\ValidationProviders;
- use Zikula\Core\Hook\ValidationHook;
- /**
- * Administrator-initiated actions for the Users module.
- */
- class AdminController extends \Zikula\Framework\Controller\AbstractController
- {
- /**
- * Post initialise.
- *
- * Run after construction.
- *
- * @return void
- */
- protected function postInitialize()
- {
- // Disable caching by default.
- $this->view->setCaching(Zikula_View::CACHE_DISABLED);
- }
- /**
- * Determines if the user currently logged in has administrative access for the Users module.
- *
- * @return bool True if the current user is logged in and has administrator access for the Users
- * module; otherwise false.
- */
- private function currentUserIsAdmin()
- {
- return UserUtil::isLoggedIn() && SecurityUtil::checkPermission('Users::', '::', ACCESS_ADMIN);
- }
- /**
- * Redirects users to the "view" page.
- *
- * @return string HTML string containing the rendered view template.
- */
- public function indexAction()
- {
- // Security check will be done in view()
- return $this->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- /**
- * Shows all items and lists the administration options.
- *
- * Parameters passed via GET:
- * --------------------------
- * numeric startnum The ordinal number at which to start displaying user records.
- * string letter The first letter of the user names to display.
- * string sort The field on which to sort the data.
- * string sortdir Either 'ASC' for an ascending sort (a to z) or 'DESC' for a descending sort (z to a).
- *
- * Parameters passed via POST:
- * ---------------------------
- * None.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return string HTML string containing the rendered template.
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have moderate access, or if the method of accessing this function is improper.
- */
- public function viewAction()
- {
- if (!SecurityUtil::checkPermission('Users::', '::', ACCESS_MODERATE)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- // we need this value multiple times, so we keep it
- $itemsPerPage = $this->getVar(UsersConstant::MODVAR_ITEMS_PER_PAGE);
- $sort = $this->request->query->get('sort', isset($args['sort']) ? $args['sort'] : 'uname');
- $sortDirection = $this->request->query->get('sortdir', isset($args['sortdir']) ? $args['sortdir'] : 'ASC');
- $sortArgs = array(
- $sort => $sortDirection,
- );
- if (!isset($sortArgs['uname'])) {
- $sortArgs['uname'] = 'ASC';
- }
- $getAllArgs = array(
- 'startnum' => $this->request->query->get('startnum', isset($args['startnum']) ? $args['startnum'] : null),
- 'numitems' => $itemsPerPage,
- 'letter' => $this->request->query->get('letter', isset($args['letter']) ? $args['letter'] : null),
- 'sort' => $sortArgs,
- );
- // Get all users as specified by the arguments.
- $userList = ModUtil::apiFunc($this->name, 'user', 'getAll', $getAllArgs);
- // Get all groups
- $groups = ModUtil::apiFunc('GroupsModule', 'user', 'getall');
- // check what groups can access the user
- $userGroupsAccess = array();
- $groupsArray = array();
- $canSeeGroups = !empty($groups);
- foreach ($groups as $group) {
- $userGroupsAccess[$group['gid']] = array('gid' => $group['gid']);
- // rewrite the groups array with the group id as key and the group name as value
- $groupsArray[$group['gid']] = array('name' => DataUtil::formatForDisplayHTML($group['name']));
- }
- // Get the current user's uid
- $currentUid = UserUtil::getVar('uid');
- // Determine the available options
- $currentUserHasReadAccess = SecurityUtil::checkPermission($this->name . '::', 'ANY', ACCESS_READ);
- $currentUserHasModerateAccess = SecurityUtil::checkPermission($this->name . '::', 'ANY', ACCESS_MODERATE);
- $currentUserHasEditAccess = SecurityUtil::checkPermission($this->name . '::', 'ANY', ACCESS_EDIT);
- $currentUserHasDeleteAccess = SecurityUtil::checkPermission($this->name . '::', 'ANY', ACCESS_DELETE);
- $availableOptions = array(
- 'lostUsername' => $currentUserHasModerateAccess,
- 'lostPassword' => $currentUserHasModerateAccess,
- 'toggleForcedPasswordChange' => $currentUserHasEditAccess,
- 'modify' => $currentUserHasEditAccess,
- 'deleteUsers' => $currentUserHasDeleteAccess,
- );
- // Loop through each returned item adding in the options that the user has over
- // each item based on the permissions the user has.
- foreach ($userList as $key => $userObj) {
- $isCurrentUser = ($userObj['uid'] == $currentUid);
- $isGuestAccount = ($userObj['uid'] == 1);
- $isAdminAccount = ($userObj['uid'] == 2);
- $hasUsersPassword = (!empty($userObj['pass']) && ($userObj['pass'] != UsersConstant::PWD_NO_USERS_AUTHENTICATION));
- $currentUserHasReadAccess = !$isGuestAccount && SecurityUtil::checkPermission($this->name . '::', "{$userObj['uname']}::{$userObj['uid']}", ACCESS_READ);
- $currentUserHasModerateAccess = !$isGuestAccount && SecurityUtil::checkPermission($this->name . '::', "{$userObj['uname']}::{$userObj['uid']}", ACCESS_MODERATE);
- $currentUserHasEditAccess = !$isGuestAccount && SecurityUtil::checkPermission($this->name . '::', "{$userObj['uname']}::{$userObj['uid']}", ACCESS_EDIT);
- $currentUserHasDeleteAccess = !$isGuestAccount && !$isAdminAccount && !$isCurrentUser && SecurityUtil::checkPermission($this->name . '::', "{$userObj['uname']}::{$userObj['uid']}", ACCESS_DELETE);
- $userList[$key]['options'] = array(
- 'lostUsername' => $currentUserHasModerateAccess,
- 'lostPassword' => $currentUserHasModerateAccess,
- 'toggleForcedPasswordChange'=> $hasUsersPassword && $currentUserHasEditAccess,
- 'modify' => $currentUserHasEditAccess,
- 'deleteUsers' => $currentUserHasDeleteAccess,
- );
- if ($isGuestAccount) {
- $userList[$key]['userGroupsView'] = array();
- } else {
- // get user groups
- $userGroups = ModUtil::apiFunc('GroupsModule', 'user', 'getusergroups', array(
- 'uid' => $userObj['uid'],
- 'clean' => 1
- ));
- // we need an associative array by the key to compare with the groups that the user can see
- $userGroupsByKey = array();
- foreach ($userGroups as $userGroup) {
- $userGroupsByKey[$userGroup['gid']] = array('gid' => $userGroup['gid']);
- }
- $userList[$key]['userGroupsView'] = array_intersect_key($userGroupsAccess, $userGroupsByKey);
- }
- // format the dates
- if (!empty($userObj['user_regdate']) && ($userObj['user_regdate'] != '0000-00-00 00:00:00') && ($userObj['user_regdate'] != '1970-01-01 00:00:00')) {
- $userList[$key]['user_regdate'] = DateUtil::formatDatetime($userObj['user_regdate'], $this->__('%m-%d-%Y'));
- } else {
- $userList[$key]['user_regdate'] = '---';
- }
- if (!empty($userObj['lastlogin']) && ($userObj['lastlogin'] != '0000-00-00 00:00:00') && ($userObj['lastlogin'] != '1970-01-01 00:00:00')) {
- $userList[$key]['lastlogin'] = DateUtil::formatDatetime($userObj['lastlogin'], $this->__('%m-%d-%Y'));
- } else {
- $userList[$key]['lastlogin'] = '---';
- }
- $userList[$key]['_Users_mustChangePassword'] = (isset($userObj['__ATTRIBUTES__']) && isset($userObj['__ATTRIBUTES__']['_Users_mustChangePassword']) && $userObj['__ATTRIBUTES__']['_Users_mustChangePassword']);
- }
- $pager = array(
- 'numitems' => ModUtil::apiFunc($this->name, 'user', 'countItems', array('letter' => $getAllArgs['letter'])),
- 'itemsperpage' => $itemsPerPage,
- );
- // Assign the items to the template & return output
- return $this->response($this->view->assign('usersitems', $userList)
- ->assign('pager', $pager)
- ->assign('allGroups', $groupsArray)
- ->assign('canSeeGroups', $canSeeGroups)
- ->assign('sort', $sort)
- ->assign('sortdir', $sortDirection)
- ->assign('available_options', $availableOptions)
- ->fetch('Admin/view.tpl'));
- }
- /**
- * Add a new user to the system.
- *
- * Parameters passed via GET:
- * --------------------------
- * None.
- *
- * Parameters passed via POST:
- * ---------------------------
- * See the definition of {@link Users_Controller_FormData_NewUserForm}.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return string HTML string containing the rendered template.
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have add access, or if the method of accessing this function is improper.
- */
- public function newUserAction()
- {
- // The user must have ADD access to submit a new user record.
- if (!SecurityUtil::checkPermission($this->name . '::', '::', ACCESS_ADD)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- // When new user registration is disabled, the user must have ADMIN access instead of ADD access.
- if (!$this->getVar(UsersConstant::MODVAR_REGISTRATION_ENABLED, false) && !SecurityUtil::checkPermission($this->name . '::', '::', ACCESS_ADMIN)) {
- $registrationUnavailableReason = $this->getVar(UsersConstant::MODVAR_REGISTRATION_DISABLED_REASON, $this->__('Sorry! New user registration is currently disabled.'));
- $this->registerError($registrationUnavailableReason);
- // TODO - The home page typically does not display errors.
- return $this->redirect(System::getHomepageUrl());
- }
- $proceedToForm = true;
- $formData = new FormData\NewUserForm('users_newuser', $this->container);
- $errorFields = array();
- $errorMessages = array();
- if ($this->request->getMethod() == 'POST') {
- // Returning from a form POST operation. Process the input.
- $this->checkCsrfToken();
- $formData->setFromRequestCollection($this->request->request->all());
- $registrationArgs = array(
- 'checkMode' => 'new',
- 'emailagain' => $formData->getField('emailagain')->getData(),
- 'setpass' => (bool)$formData->getField('setpass')->getData(),
- 'antispamanswer' => '',
- );
- $registrationArgs['passagain'] = $registrationArgs['setpass'] ? $formData->getField('passagain')->getData() : '';
- $registrationInfo = array(
- 'uname' => $formData->getField('uname')->getData(),
- 'pass' => $registrationArgs['setpass'] ? $formData->getField('pass')->getData() : '',
- 'passreminder' => $registrationArgs['setpass'] ? $this->__('(Password provided by site administrator)') : '',
- 'email' => mb_strtolower($formData->getField('email')->getData()),
- );
- $registrationArgs['reginfo'] = $registrationInfo;
- $sendPass = $formData->getField('sendpass')->getData();
- if ($formData->isValid()) {
- $errorFields = ModUtil::apiFunc($this->name, 'registration', 'getRegistrationErrors', $registrationArgs);
- } else {
- $errorFields = $formData->getErrorMessages();
- }
- $event = new GenericEvent($registrationInfo, array(), new ValidationProviders());
- $this->dispatcher->dispatch('module.users.ui.validate_edit.new_user', $event);
- $validators = $event->getData();
- $hook = new ValidationHook($validators);
- $this->dispatchHooks('users.ui_hooks.user.validate_edit', $hook);
- $validators = $hook->getValidators();
- if (empty($errorFields) && !$validators->hasErrors()) {
- // TODO - Future functionality to suppress e-mail notifications, see ticket #2351
- //$currentUserEmail = UserUtil::getVar('email');
- //$adminNotifyEmail = $this->getVar('reg_notifyemail', '');
- //$adminNotification = (strtolower($currentUserEmail) != strtolower($adminNotifyEmail));
- $registeredObj = ModUtil::apiFunc($this->name, 'registration', 'registerNewUser', array(
- 'reginfo' => $registrationInfo,
- 'sendpass' => $sendPass,
- 'usernotification' => true,
- 'adminnotification' => true,
- ));
- if (isset($registeredObj) && $registeredObj) {
- $event = new GenericEvent($registeredObj);
- $this->dispatcher->dispatch('module.users.ui.process_edit.new_user', $event);
- $hook = new ProcessHook($registeredObj['uid']);
- $this->dispatchHooks('users.ui_hooks.user.process_edit', $hook);
- if ($registeredObj['activated'] == UsersConstant::ACTIVATED_PENDING_REG) {
- $this->registerStatus($this->__('Done! Created new registration application.'));
- } elseif (isset($registeredObj['activated'])) {
- $this->registerStatus($this->__('Done! Created new user account.'));
- } else {
- $this->registerError($this->__('Warning! New user information has been saved, however there may have been an issue saving it properly.'));
- }
- $proceedToForm = false;
- } else {
- $this->registerError($this->__('Error! Could not create the new user account or registration application.'));
- }
- }
- } elseif (!$this->request->getMethod() == 'GET') {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- if ($proceedToForm) {
- return $this->response($this->view->assign_by_ref('formData', $formData)
- ->assign('mode', 'new')
- ->assign('errorMessages', $errorMessages)
- ->assign('errorFields', $errorFields)
- ->fetch('Admin/newuser.tpl'));
- } else {
- return $this->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- }
- /**
- * Renders a user search form used by both the search operation and the mail users operation.
- *
- * @param string $callbackFunc Either 'search' or 'mailUsers', indicating which operation is calling this function.
- *
- * @return string The rendered output from the template, appropriate for the indicated operation.
- */
- protected function renderSearchForm($callbackFunc = 'search')
- {
- // get group items
- $groups = ModUtil::apiFunc('GroupsModule', 'user', 'getAll');
- return $this->response($this->view->assign('groups', $groups)
- ->assign('callbackFunc', $callbackFunc)
- ->fetch('Admin/search.tpl'));
- }
- /**
- * Gathers the user input from a rendered search form, and also makes the appropriate hook calls.
- *
- * Parameters passed via GET:
- * --------------------------
- * None.
- *
- * Parameters passed via POST:
- * ---------------------------
- * string uname A fragment of a user name on which to search using an SQL LIKE clause. The user name will be
- * surrounded by wildcards.
- * integer ugroup A group id in which to search (only users who are members of the specified group are returned).
- * string email A fragment of an e-mail address on which to search using an SQL LIKE clause. The e-mail address
- * will be surrounded by wildcards.
- * string regdateafter An SQL date-time (in the form '1970-01-01 00:00:00'); only user accounts with a registration date
- * after the date specified will be returned.
- * string regdatebefore An SQL date-time (in the form '1970-01-01 00:00:00'); only user accounts with a registration date
- * before the date specified will be returned.
- * array dynadata An array of search values to be passed to the designated profile module. Only those user records
- * also satisfying the profile module's search of its dataare returned.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @param string $callbackFunc Either 'search' or 'mailUsers', indicating which operation is calling this function.
- *
- * @return array|boolean An array of search results, which may be empty; false if the search was unsuccessful.
- */
- protected function getSearchResults($callbackFunc = 'search')
- {
- $findUsersArgs = array(
- 'uname' => $this->request->request->get('uname', null),
- 'email' => $this->request->request->get('email', null),
- 'ugroup' => $this->request->request->get('ugroup', null),
- 'regdateafter' => $this->request->request->get('regdateafter', null),
- 'regdatebefore' => $this->request->request->get('regdatebefore', null),
- );
- if ($callbackFunc == 'mailUsers') {
- $processEditEvent = $this->dispatcher->dispatch('users.mailuserssearch.process_edit', new GenericEvent(null, array(), $findUsersArgs));
- } else {
- $processEditEvent = $this->dispatcher->dispatch('users.search.process_edit', new GenericEvent(null, array(), $findUsersArgs));
- }
- $findUsersArgs = $processEditEvent->getData();
- // call the api
- return ModUtil::apiFunc($this->name, 'admin', 'findUsers', $findUsersArgs);
- }
- /**
- * Displays a user account search form, or the search results from a post.
- *
- * Parameters passed via GET:
- * --------------------------
- * None.
- *
- * Parameters passed via POST:
- * ---------------------------
- * See the definition of {@link getSearchResults()}.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return string HTML string containing the rendered template.
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have moderate access, or if the method of accessing this function is improper.
- */
- public function searchAction()
- {
- if (!SecurityUtil::checkPermission($this->name . '::', '::', ACCESS_MODERATE)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- if ($this->request->getMethod() == 'POST') {
- $this->checkCsrfToken();
- $usersList = $this->getSearchResults();
- if ($usersList) {
- $currentUid = UserUtil::getVar('uid');
- $actions = array();
- foreach ($usersList as $key => $user) {
- $actions[$key] = array(
- 'modifyUrl' => false,
- 'deleteUrl' => false,
- );
- if ($user['uid'] != 1) {
- if (SecurityUtil::checkPermission($this->name.'::', $user['uname'].'::'.$user['uid'], ACCESS_EDIT)) {
- $actions[$key]['modifyUrl'] = ModUtil::url($this->name, 'admin', 'modify', array('userid' => $user['uid']));
- }
- if (($currentUid != $user['uid'])
- && SecurityUtil::checkPermission($this->name.'::', $user['uname'].'::'.$user['uid'], ACCESS_DELETE)) {
- $actions[$key]['deleteUrl'] = ModUtil::url($this->name, 'admin', 'deleteusers', array('userid' => $user['uid']));
- }
- }
- }
- } else {
- $this->registerError($this->__('Sorry! No matching users found.'));
- }
- }
- if (isset($usersList) && $usersList) {
- return $this->response($this->view->assign('items', $usersList)
- ->assign('actions', $actions)
- ->assign('deleteUsers', SecurityUtil::checkPermission($this->name . '::', '::', ACCESS_ADMIN))
- ->fetch('Admin/search_results.tpl'));
- } elseif ($this->request->getMethod() == 'GET' || ($this->request->getMethod() == 'POST' && (!isset
- ($usersList) || !$usersList))) {
- return $this->renderSearchForm('search');
- } else {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- }
- /**
- * Search for users and then compose an email to them.
- *
- * Parameters passed via GET:
- * --------------------------
- * None.
- *
- * Parameters passed via POST:
- * ---------------------------
- * string formid The form id posting to this function. Used to determine the workflow.
- *
- * See also the definition of {@link getSearchResults()}.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return string HTML string containing the rendered template.
- *
- * @throws \Zikula\Framework\Exception\FatalException Thrown if the function enters an unknown state.
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have comment access, or if the method of accessing this function is improper.
- */
- public function mailUsersAction()
- {
- if (!SecurityUtil::checkPermission($this->name . '::MailUsers', '::', ACCESS_COMMENT)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- if ($this->request->getMethod() == 'POST') {
- $this->checkCsrfToken();
- $formId = $this->request->request->get('formid', 'UNKNOWN');
- if ($formId == 'users_search') {
- $userList = $this->getSearchResults('mailUsers');
- if (!isset($userList) || !$userList) {
- $this->registerError($this->__('Sorry! No matching users found.'));
- }
- } elseif ($formId == 'users_mailusers') {
- $uid = $this->request->request->get('userid', null);
- $sendmail = $this->request->request->get('sendmail', null);
- $mailSent = ModUtil::apiFunc($this->name, 'admin', 'sendmail', array(
- 'uid' => $uid,
- 'sendmail' => $sendmail,
- ));
- } else {
- throw new \Zikula\Framework\Exception\FatalException($this->__f('An unknown form type was received by %1$s.', array('mailUsers')));
- }
- } elseif (!$this->request->getMethod() == 'GET') {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- if ($this->request->getMethod() == 'GET' || (($formId == 'users_search') && (!isset($userList) || !$userList)) || (($formId == 'users_mailusers') && !$mailSent)) {
- return $this->renderSearchForm('mailUsers');
- } elseif ($formId == 'users_search') {
- return $this->response($this->view->assign('items', $userList)
- ->assign('mailusers', SecurityUtil::checkPermission($this->name . '::MailUsers', '::', ACCESS_COMMENT))
- ->fetch('Admin/mailusers.tpl'));
- } elseif ($formId == 'users_mailusers') {
- return $this->redirect(ModUtil::url($this->name, 'admin', 'index'));
- } else {
- throw new \Zikula\Framework\Exception\FatalException($this->__f('The %1$s function has entered an unknown state.', array('mailUsers')));
- }
- }
- /**
- * Display a form to edit one user account, and process that edit request.
- *
- * Parameters passed via GET:
- * --------------------------
- * numeric userid The user id of the user to be modified.
- * string uname The user name of the user to be modified.
- *
- * Parameters passed via POST:
- * ---------------------------
- * array access_permissions An array used to modify a user's group membership.
- *
- * See also the definition of {@link Users_Controller_FormData_ModifyUserForm}.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return string HTML string containing the rendered template.
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have edit access, or if the method of accessing this function is improper.
- */
- public function modifyAction()
- {
- // security check for generic edit access
- if (!SecurityUtil::checkPermission('Users::', 'ANY', ACCESS_EDIT)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- $proceedToForm = true;
- $formData = new FormData\ModifyUserForm('users_modify', $this->container);
- if ($this->request->getMethod() == 'POST') {
- $this->checkCsrfToken();
- $formData->setFromRequestCollection($this->request->getPost());
- $accessPermissions = $this->request->request->get('access_permissions', null);
- $user = $formData->toUserArray(true);
- $originalUser = UserUtil::getVars($user['uid']);
- $userAttributes = isset($originalUser['__ATTRIBUTES__']) ? $originalUser['__ATTRIBUTES__'] : array();
- // security check for this record
- if (!SecurityUtil::checkPermission('Users::', "{$originalUser['uname']}::{$originalUser['uid']}", ACCESS_EDIT)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- if ($formData->isValid()) {
- $registrationArgs = array(
- 'checkmode' => 'modify',
- 'emailagain' => $formData->getField('emailagain')->getData(),
- 'setpass' => (bool)$formData->getField('setpass')->getData(),
- 'antispamanswer' => '',
- );
- $registrationArgs['passagain'] = $registrationArgs['setpass'] ? $formData->getField('passagain')->getData() : '';
- $registrationArgs['reginfo'] = $user;
- $errorFields = ModUtil::apiFunc($this->name, 'registration', 'getRegistrationErrors', $registrationArgs);
- } else {
- $errorFields = $formData->getErrorMessages();
- }
- $event = new GenericEvent($user, array(), new ValidationProviders());
- $this->dispatcher->dispatch('module.users.ui.validate_edit.modify_user', $event);
- $validators = $event->getData();
- $hook = new ValidationHook($validators);
- $this->dispatchHooks('users.ui_hooks.user.validate_edit', $hook);
- $validators = $hook->getValidators();
- if (!$errorFields && !$validators->hasErrors()) {
- if ($originalUser['uname'] != $user['uname']) {
- // UserUtil::setVar does not allow uname to be changed.
- // UserUtil::setVar('uname', $user['uname'], $originalUser['uid']);
- $updatedUserObj = $this->entityManager->find('UsersModule\Entity\User', $originalUser['uid']);
- $updatedUserObj['uname'] = $user['uname'];
- $this->entityManager->flush();
- $eventArgs = array(
- 'action' => 'setVar',
- 'field' => 'uname',
- 'attribute' => null,
- );
- $eventData = array(
- 'old_value' => $originalUser['uname'],
- );
- $updateEvent = new GenericEvent($updatedUserObj, $eventArgs, $eventData);
- $this->dispatcher->dispatch('user.account.update', $updateEvent);
- }
- if ($originalUser['email'] != $user['email']) {
- UserUtil::setVar('email', $user['email'], $originalUser['uid']);
- }
- if ($originalUser['activated'] != $user['activated']) {
- UserUtil::setVar('activated', $user['activated'], $originalUser['uid']);
- }
- if ($originalUser['theme'] != $user['theme']) {
- UserUtil::setVar('theme', $user['theme'], $originalUser['uid']);
- }
- if ($formData->getField('setpass')->getData()) {
- UserUtil::setPassword($user['pass'], $originalUser['uid']);
- UserUtil::setVar('passreminder', $user['passreminder'], $originalUser['uid']);
- }
- $user = UserUtil::getVars($user['uid'], true);
- // TODO - This all needs to move to a Groups module hook.
- if (isset($accessPermissions)) {
- // Fixing a high numitems to be sure to get all groups
- $groups = ModUtil::apiFunc('GroupsModule', 'user', 'getAll', array('numitems' => 10000));
- $curUserGroupMembership = ModUtil::apiFunc('GroupsModule', 'user', 'getUserGroups', array('uid' => $user['uid']));
- foreach ($groups as $group) {
- if (in_array($group['gid'], $accessPermissions)) {
- // Check if the user is already in the group
- $userIsMember = false;
- if ($curUserGroupMembership) {
- foreach ($curUserGroupMembership as $alreadyMemberOf) {
- if ($group['gid'] == $alreadyMemberOf['gid']) {
- $userIsMember = true;
- break;
- }
- }
- }
- if ($userIsMember == false) {
- // User is not in this group
- ModUtil::apiFunc('GroupsModule', 'admin', 'addUser', array(
- 'gid' => $group['gid'],
- 'uid' => $user['uid']
- ));
- $curUserGroupMembership[] = $group;
- }
- } else {
- // We don't need to do a complex check, if the user is not in the group, the SQL will not return
- // an error anyway.
- ModUtil::apiFunc('GroupsModule', 'admin', 'removeUser', array(
- 'gid' => $group['gid'],
- 'uid' => $user['uid']
- ));
- }
- }
- }
- $event = new GenericEvent($user);
- $this->dispatcher->dispatch('module.users.ui.process_edit.modify_user', $event);
- $hook = new ProcessHook($user['uid']);
- $this->dispatchHooks('users.ui_hooks.user.process_edit', $hook);
- $this->registerStatus($this->__("Done! Saved user's account information."));
- $proceedToForm = false;
- }
- } elseif ($this->request->getMethod() == 'GET') {
- $uid = $this->request->query->get('userid', null);
- $uname = $this->request->query->get('uname', null);
- // check arguments
- if (is_null($uid) && is_null($uname)) {
- $this->registerError(LogUtil::getErrorMsgArgs());
- $proceedToForm = false;
- }
- // retreive userid from uname
- if (is_null($uid) && !empty($uname)) {
- $uid = UserUtil::getIdFromName($uname);
- }
- // warning for guest account
- if ($uid == 1) {
- $this->registerError($this->__("Error! You can't edit the guest account."));
- $proceedToForm = false;
- }
- // get the user vars
- $originalUser = UserUtil::getVars($uid);
- if ($originalUser == false) {
- $this->registerError($this->__('Sorry! No such user found.'));
- $proceedToForm = false;
- }
- $userAttributes = isset($originalUser['__ATTRIBUTES__']) ? $originalUser['__ATTRIBUTES__'] : array();
- $formData->setFromArray($originalUser);
- $formData->getField('emailagain')->setData($originalUser['email']);
- $formData->getField('pass')->setData('');
- $accessPermissions = array();
- $errorFields = array();
- } else {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- if ($proceedToForm) {
- // security check for this record
- if (!SecurityUtil::checkPermission('Users::', "{$originalUser['uname']}::{$originalUser['uid']}", ACCESS_EDIT)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- // groups
- $gidsUserMemberOf = array();
- $allGroups = ModUtil::apiFunc('GroupsModule', 'user', 'getall');
- if (!empty($accessPermissions)) {
- $gidsUserMemberOf = $accessPermissions;
- $accessPermissions = array();
- } else {
- $groupsUserMemberOf = ModUtil::apiFunc('GroupsModule', 'user', 'getusergroups', array('uid' => $originalUser['uid']));
- foreach ($groupsUserMemberOf as $user_group) {
- $gidsUserMemberOf[] = $user_group['gid'];
- }
- }
- foreach ($allGroups as $group) {
- if (SecurityUtil::checkPermission('Groups::', "{$group['gid']}::", ACCESS_EDIT)) {
- $accessPermissions[$group['gid']] = array();
- $accessPermissions[$group['gid']]['name'] = $group['name'];
- if (in_array($group['gid'], $gidsUserMemberOf) || in_array($group['gid'], $gidsUserMemberOf)) {
- $accessPermissions[$group['gid']]['access'] = true;
- } else {
- $accessPermissions[$group['gid']]['access'] = false;
- }
- }
- }
- if (!isset($userAttributes['realname'])) {
- $userAttributes['realname'] = '';
- }
- return $this->response($this->view->assign_by_ref('formData', $formData)
- ->assign('user_attributes', $userAttributes)
- ->assign('defaultGroupId', ModUtil::getVar('Groups', 'defaultgroup', 1))
- ->assign('primaryAdminGroupId', ModUtil::getVar('Groups', 'primaryadmingroup', 2))
- ->assign('accessPermissions', $accessPermissions)
- ->assign('errorFields', $errorFields)
- ->fetch('Admin/modify.tpl'));
- } else {
- return $this->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- }
- /**
- * Allows an administrator to send a user his user name via email.
- *
- * Parameters passed via GET:
- * --------------------------
- * numeric userid The user id of the user to be modified.
- *
- * Parameters passed via POST:
- * ---------------------------
- * numeric userid The user id of the user to be modified.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return void
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have moderate access.
- *
- * @todo The link on the view page should be a mini form, and should post.
- *
- * @todo This should have a confirmation page.
- */
- public function lostUsernameAction()
- {
- if ($this->request->getMethod() == 'POST') {
- $this->checkCsrfToken();
- $uid = $this->request->request->get('userid', null);
- } else {
- $this->checkCsrfToken($this->request->query->get('csrftoken'));
- $uid = $this->request->query->get('userid', null);
- }
- if (!isset($uid) || !is_numeric($uid) || ((int)$uid != $uid) || ($uid <= 1)) {
- $this->registerError(LogUtil::getErrorMsgArgs())
- ->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- $user = UserUtil::getVars($uid);
- if (!$user) {
- $this->registerError($this->__('Sorry! Unable to retrieve information for that user id.'))
- ->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- if (!SecurityUtil::checkPermission('Users::', "{$user['uname']}::{$user['uid']}", ACCESS_MODERATE)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- $userNameSent = ModUtil::apiFunc($this->name, 'user', 'mailUname', array(
- 'idfield' => 'uid',
- 'id' => $user['uid'],
- 'adminRequest' => true,
- ));
- if ($userNameSent) {
- $this->registerStatus($this->__f('Done! The user name for \'%s\' has been sent via e-mail.', $user['uname']))
- ->redirect(ModUtil::url($this->name, 'admin', 'view'));
- } elseif (!$this->request->getSession()->getFlashBag()->has(Zikula_Session::MESSAGE_ERROR)) {
- $this->registerError($this->__f('Sorry! There was an unknown error while trying to send the user name for \'%s\'.', $user['uname']))
- ->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- }
- /**
- * Allows an administrator to send a user a password recovery verification code.
- *
- * Parameters passed via GET:
- * --------------------------
- * numeric userid The user id of the user to be modified.
- *
- * Parameters passed via POST:
- * ---------------------------
- * None.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return bool True on success and redirect; otherwise false.
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have moderate access.
- *
- * @todo The link on the view page should be a mini form, and should post.
- *
- * @todo This should have a confirmation page.
- */
- public function lostPasswordAction()
- {
- $this->checkCsrfToken($this->request->query->get('csrftoken'));
- $uid = $this->request->query->get('userid', null);
- if (!isset($uid) || !is_numeric($uid) || ((int)$uid != $uid) || ($uid <= 1)) {
- $this->registerError(LogUtil::getErrorMsgArgs())
- ->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- $user = UserUtil::getVars($uid);
- if (!$user) {
- $this->registerError($this->__('Sorry! Unable to retrieve information for that user id.'));
- return false;
- }
- if (!SecurityUtil::checkPermission('Users::', "{$user['uname']}::{$user['uid']}", ACCESS_MODERATE)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- $confirmationCodeSent = ModUtil::apiFunc($this->name, 'user', 'mailConfirmationCode', array(
- 'idfield' => 'uid',
- 'id' => $user['uid'],
- 'adminRequest' => true,
- ));
- if ($confirmationCodeSent) {
- $this->registerStatus($this->__f('Done! The password recovery verification code for %s has been sent via e-mail.', $user['uname']));
- }
- return $this->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- /**
- * Display a form to confirm the deletion of one user, and then process the deletion.
- *
- * Parameters passed via GET:
- * --------------------------
- * numeric userid The user id of the user to be deleted.
- * string uname The user name of the user to be deleted.
- *
- * Parameters passed via POST:
- * ---------------------------
- * array userid The array of user ids of the users to be deleted.
- * boolean process_delete True to process the posted userid list, and delete the corresponding accounts; false or null to confirm first.
- *
- * Parameters passed via SESSION:
- * ------------------------------
- * None.
- *
- * @return string HTML string containing the rendered template.
- *
- * @throws \Zikula\Framework\Exception\ForbiddenException Thrown if the current user does not have delete access, or if the method of accessing this function is improper.
- */
- public function deleteUsersAction()
- {
- // check permissions
- if (!SecurityUtil::checkPermission('Users::', 'ANY', ACCESS_DELETE)) {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- $proceedToForm = false;
- $processDelete = false;
- if ($this->request->getMethod() == 'POST') {
- $userid = $this->request->request->get('userid', null);
- $processDelete = $this->request->request->get('process_delete', false);
- $proceedToForm = !$processDelete;
- } elseif ($this->request->getMethod() == 'GET') {
- $userid = $this->request->query->get('userid', null);
- $uname = $this->request->query->get('uname', null);
- // retreive userid from uname
- if (empty($userid) && !empty($uname)) {
- $userid = UserUtil::getIdFromName($uname);
- }
- $proceedToForm = true;
- } else {
- throw new \Zikula\Framework\Exception\ForbiddenException();
- }
- if (empty($userid)) {
- $this->registerError($this->__('Sorry! No such user found.'));
- $proceedToForm = false;
- }
- if (!is_array($userid)) {
- $userid = array($userid);
- }
- $currentUser = UserUtil::getVar('uid');
- $users = array();
- foreach ($userid as $key => $uid) {
- if ($uid == 1) {
- $this->registerError($this->__("Error! You can't delete the guest account."));
- $proceedToForm = false;
- $processDelete = false;
- } elseif ($uid == 2) {
- $this->registerError($this->__("Error! You can't delete the primary administrator account."));
- $proceedToForm = false;
- $processDelete = false;
- } elseif ($uid == $currentUser) {
- $this->registerError($this->__("Error! You can't delete the account you are currently logged into."));
- $proceedToForm = false;
- $processDelete = false;
- }
- // get the user vars
- $users[$key] = UserUtil::getVars($uid);
- if ($users[$key] == false) {
- $this->registerError($this->__('Sorry! No such user found.'));
- $proceedToForm = false;
- $processDelete = false;
- }
- }
- if ($processDelete) {
- $valid = true;
- foreach ($userid as $uid) {
- $event = new GenericEvent(null, array('id' => $uid), new ValidationProviders());
- $validators = $this->dispatcher->dispatch('module.users.ui.validate_delete', $event)->getData();
- $hook = new ValidationHook($validators);
- $this->dispatchHooks('users.ui_hooks.user.validate_delete', $hook);
- $validators = $hook->getValidators();
- if ($validators->hasErrors()) {
- $valid = false;
- }
- }
- $proceedToForm = false;
- if ($valid) {
- $deleted = ModUtil::apiFunc($this->name, 'admin', 'deleteUser', array('uid' => $userid));
- if ($deleted) {
- foreach ($userid as $uid) {
- $event = new GenericEvent(null, array('id' => $uid));
- $this->dispatcher->dispatch('module.users.ui.process_delete', $event);
- $hook = new ProcessHook($uid);
- $this->dispatchHooks('users.ui_hooks.user.process_delete', $hook);
- }
- $count = count($userid);
- $this->registerStatus($this->_fn('Done! Deleted %1$d user account.', 'Done! Deleted %1$d user accounts.', $count, array($count)));
- }
- }
- }
- if ($proceedToForm) {
- return $this->response($this->view->assign('users', $users)
- ->fetch('Admin/deleteusers.tpl'));
- } else {
- return $this->redirect(ModUtil::url($this->name, 'admin', 'view'));
- }
- }
- /**
- * Constructs a list of various actions for a list of registrations appropriate for the current user.
- *
- * NOTE: Internal function.
- *
- * @param array $reglist The list of registration records.
- * @param string $restoreView Indicates where the calling function expects to return to; 'view' indicates
- * that the calling function expects to return to the registration list
- * and 'display' indicates that the calling function expects to return
- * to an individual registration record.
- *
- * @return array An array of valid action URLs for each registration record in the list.
- */
- protected function getActionsForRegistrations(array $reglist, $restoreView='view')
- {
- $actions = array();
- if (!empty($reglist)) {
- $approvalOrder = $this->getVar('moderation_order', UsersConstant::APPROVAL_BEFORE);
- // Don't try to put any visual elements here (images, titles, colors, css classes, etc.). Leave that to
- // the template, so that they can be customized without hacking the core code. In fact, all we really need here
- // is what options are enabled. The template could build everything else. We will put the URL for the action
- // in the array for convenience, but that could be done in the template too, really.
- //
- // Make certain that the following goes from most restricted to least (ADMIN...NONE order). Having the
- // security check as the outer if statement, and similar foreach loops within each saves on repeated checking
- // of permissions, speeding things up a bit.
- if (SecurityUtil::checkPermission('Users::', '::', ACCESS_ADMIN)) {
- $actions['count'] = 6;
- foreach ($reglist as $key => $reginfo) {
- $enableVerify = !$reginfo['isverified'];
- $enableApprove = !$reginfo['isapproved'];
- $enableForced = !$reginfo['isverified'] && isset($reginfo['pass']) && !empty($reginfo['pass']);
- $actions['list'][$reginfo['uid']] = array(
- 'display' => ModUtil::url($this->name, 'admin', 'displayRegistration', array('uid' => $reginfo['uid'])),
- 'modify' => ModUtil::url($this->name, 'admin', 'modifyRegistration', array('uid' => $reginfo['uid'], 'restoreview' => $restoreView)),
- 'verify' => $enableVerify ? ModUtil::url($this->name, 'admin', 'verifyRegistration', array('uid' => $reginfo['uid'], 'restoreview' => $restoreView)) : false,
- 'approve' => $enableApprove ? ModUtil::url($this->name, 'admin', 'approveRegistration', array('uid' => $reginfo['uid'])) : false,
- 'deny' => ModUtil::url($this->name, 'admin', 'denyRegistration', array('uid' => $reginfo['uid'])),
- 'approveForce' => $enableForced ? ModUtil::url($this->name, 'admin', 'approveRegistration', array('uid' => $reginfo['uid'], 'force' => true)) : false,
- );
- …
Large files files are truncated, but you can click here to view the full file