* @copyright 2014 – 2016 Heinrich-Heine-Universität Düsseldorf * @license http://www.gnu.org/licenses/gpl.html * @link https://github.com/coderkun/questlab */ namespace hhu\z\controllers; /** * Controller of the Agent to list registered users and their data. * * @author Oliver Hanraths */ class UsersController extends \hhu\z\controllers\IntermediateController { /** * User permissions * * @var array */ public $permissions = array( 'index' => array('admin', 'moderator'), 'user' => array('admin', 'moderator', 'user'), 'create' => array('admin', 'moderator'), 'edit' => array('admin', 'moderator', 'user'), 'delete' => array('admin') ); /** * Required models * * @var array */ public $models = array('users', 'userroles', 'characters', 'characterroles', 'avatars', 'media', 'xplevels'); /** * Required components * * @var array */ public $components = array('validation'); /** * Action: index. * * @param string $all Whether to list all users at once or not (optional) */ public function index($all=null) { // Set filters $sortorder = 'username'; $username = null; $name = null; $email = null; $page = 1; if($this->request->getRequestMethod() == 'GET') { $sortorder = $this->request->getGetParam('sortorder'); $sortorder = !empty($sortorder) ? $sortorder : 'username'; $username = (!is_null($this->request->getGetParam('username'))) ? $this->request->getGetParam('username') : $username; $name = (!is_null($this->request->getGetParam('name'))) ? $this->request->getGetParam('name') : $name; $email = (!is_null($this->request->getGetParam('email'))) ? $this->request->getGetParam('email') : $email; $page = $this->request->getGetParam('page'); $page = !empty($page) ? intval($page) : 1; } // Get registered users $limit = ($all != 'all') ? \nre\configs\AppConfig::$misc['lists_limit'] : null; $offset = ($all != 'all') ? max((intval($page) - 1), 0) * $limit : 0; $usersCount = $this->Users->getUsersCount($username, $name, $email); $users = $this->Users->getUsers($sortorder, $username, $name, $email, $limit, $offset); foreach($users as &$user) { $user['roles'] = array_map(function($r) { return $r['name']; }, $this->Userroles->getUserrolesForUserById($user['id'])); } // Set titile $this->addTitleLocalized('Users'); // Pass data to view $this->set('users', $users); $this->set('usersCount', $usersCount); $this->set('sortorder', $sortorder); $this->set('username', $username); $this->set('name', $name); $this->set('email', $email); $this->set('all', $all); $this->set('page', $page); $this->set('limit', $limit); } /** * Action: user. * * Show a user and its details. * * @throws \nre\exceptions\IdNotFoundException * @throws \nre\exceptions\AccessDeniedException * @param string $userUrl URL-Username of an user */ public function user($userUrl) { // Get user $user = $this->Users->getUserByUrl($userUrl); // Check permissions if(count(array_intersect(array('admin','moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0 && $user['id'] != IntermediateController::$user['id']) { throw new \nre\exceptions\AccessDeniedException(); } // Get Characters $characters = $this->Characters->getCharactersForUser($user['id']); // Additional Character information foreach($characters as &$character) { // Seminary roles $character['characterroles'] = $this->Characterroles->getCharacterrolesForCharacterById($character['id']); $character['characterroles'] = array_map(function($a) { return $a['name']; }, $character['characterroles']); // Level try { $character['xplevel'] = $this->Xplevels->getXPLevelById($character['xplevel_id']); } catch(\nre\Exceptions\IdNotFoundException $e) { // No XP-level } // Avatar $avatar = $this->Avatars->getAvatarById($character['avatar_id']); if(!is_null($avatar['small_avatarpicture_id'])) { //$character['seminary'] = $character['small_avatar'] = $this->Media->getSeminaryMediaById($avatar['small_avatarpicture_id']); } } // Set titile $this->addTitleLocalized($user['username']); $this->addTitleLocalized('Users'); // Pass data to view $this->set('user', $user); $this->set('characters', $characters); } /** * Action: login. * * Log in a user. */ public function login() { $username = ''; $referrer = null; // Log the user in if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('login'))) { $username = $this->request->getPostParam('username'); $referrer = $this->request->getPostParam('referrer'); $userId = $this->Users->login( $username, $this->request->getPostParam('password') ); if(!is_null($userId)) { $this->Auth->setUserId($userId); $user = $this->Users->getUserById($userId); if(!empty($referrer)) { $this->redirect($referrer); } else { $this->redirect($this->linker->link(array($user['url']), 1)); } } } // Set titile $this->addTitleLocalized('Login'); // Pass data to view $this->set('username', $username); $this->set('referrer', $referrer); $this->set('failed', ($this->request->getRequestMethod() == 'POST')); } /** * Action: register. * * Register a new user. */ public function register() { $username = ''; $prename = ''; $surname = ''; $email = ''; $fields = array('username', 'prename', 'surname', 'email', 'password'); $validation = array(); $emailhost = \nre\configs\AppConfig::$app['registration_host']; // Register a new user if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('register'))) { // Get params and validate them $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); $username = $this->request->getPostParam('username'); if($this->Users->usernameExists($username)) { $validation = $this->Validation->addValidationResult($validation, 'username', 'exist', true); } $prename = $this->request->getPostParam('prename'); $surname = $this->request->getPostParam('surname'); $email = $this->request->getPostParam('email'); if(!empty($emailhost)) { if(substr_compare($email, $emailhost, max(0, strlen($email)-strlen($emailhost)), strlen($emailhost)) !== 0) { $validation = $this->Validation->addValidationResult($validation, 'email', 'host', 'invalid'); } } if($this->Users->emailExists($email)) { $validation = $this->Validation->addValidationResult($validation, 'email', 'exist', true); } $password = $this->request->getPostParam('password'); if($password != $this->request->getPostParam('passwordrepeat')) { $validation = $this->Validation->addValidationResult($validation, 'password', 'repeat', false); } // Register if($validation === true) { $userId = $this->Users->createUser( $username, $prename, $surname, $email, $password ); $user = $this->Users->getUserById($userId); // Send mail $this->sendRegistrationMail($user); // Login $this->Auth->setUserId($userId); // Redirect to user page $this->redirect($this->linker->link(array($user['url']), 1)); } } // Get validation settings $validationSettings = array(); foreach($fields as &$field) { $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; } // Set titile $this->addTitleLocalized('Registration'); // Pass data to view $this->set('username', $username); $this->set('prename', $prename); $this->set('surname', $surname); $this->set('email', $email); $this->set('emailhost', $emailhost); $this->set('validation', $validation); $this->set('validationSettings', $validationSettings); } /** * Action: logout. * * Log out a user. */ public function logout() { // Unset the currently logged in user $this->Auth->setUserId(null); // Redirect $this->redirect($this->linker->link(array())); } /** * Action: manage. * * Manage users. */ public function manage() { $selectedUsers = array(); //global $sortorder; $sortorder = 'username'; if($this->request->getRequestMethod() == 'POST') { // Set sortorder $sortorder = $this->request->getPostParam('sortorder'); // Do action $selectedUsers = $this->request->getPostParam('users'); if(!is_array($selectedUsers)) { $selectedUsers = array(); } if(!is_null($this->request->getPostParam('actions')) && count($this->request->getPostParam('actions')) > 0 && !is_null($this->request->getPostParam('users')) && count($this->request->getPostParam('users')) > 0) { $actions = $this->request->getPostParam('actions'); $action = array_keys($actions)[0]; switch($action) { // Add/remove role to/from Characters case 'addrole': case 'removerole': // Determine role and check permissions $role = null; switch($actions[$action]) { case _('Admin'): if(!in_array('admin', \hhu\z\controllers\IntermediateController::$user['roles'])) { throw new \nre\exceptions\AccessDeniedException(); } $role = 'admin'; break; case _('Moderator'): if(!in_array('admin', \hhu\z\controllers\IntermediateController::$user['roles'])) { throw new \nre\exceptions\AccessDeniedException(); } $role = 'moderator'; break; case _('User'): if(count(array_intersect(array('admin', 'moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) <= 0) { throw new \nre\exceptions\AccessDeniedException(); } $role = 'user'; break; } // Add role if($action == 'addrole') { foreach($selectedUsers as &$userId) { $this->Userroles->addUserroleToUser($userId, $role); } } // Remove role else { foreach($selectedUsers as &$userId) { $this->Userroles->removeUserroleFromUser($userId, $role); } } break; } } } // Get registered users $users = $this->Users->getUsers($sortorder); foreach($users as &$user) { $user['roles'] = array_map(function($r) { return $r['name']; }, $this->Userroles->getUserrolesForUserById($user['id'])); } // Set titile $this->addTitleLocalized('Manage users'); // Pass data to view $this->set('users', $users); $this->set('selectedUsers', $selectedUsers); $this->set('sortorder', $sortorder); } /** * Action: create. * * Create a new user. */ public function create() { // Values $username = ''; $prename = ''; $surname = ''; $email = ''; $fields = array('username', 'prename', 'surname', 'email', 'password'); $validation = array(); // Create new user if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('create'))) { // Get params and validate them $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); $username = $this->request->getPostParam('username'); if($this->Users->usernameExists($username)) { $validation = $this->Validation->addValidationResult($validation, 'username', 'exist', true); } $prename = $this->request->getPostParam('prename'); $surname = $this->request->getPostParam('surname'); $email = $this->request->getPostParam('email'); if($this->Users->emailExists($email)) { $validation = $this->Validation->addValidationResult($validation, 'email', 'exist', true); } $password = $this->request->getPostParam('password'); if($password != $this->request->getPostParam('passwordrepeat')) { $validation = $this->Validation->addValidationResult($validation, 'password', 'repeat', false); } // Create if($validation === true) { $userId = $this->Users->createUser( $this->request->getPostParam('username'), $this->request->getPostParam('prename'), $this->request->getPostParam('surname'), $this->request->getPostParam('email'), $this->request->getPostParam('password') ); // Redirect to user $user = $this->Users->getUserById($userId); $this->redirect($this->linker->link(array($user['url']), 1)); } } // Get validation settings $validationSettings = array(); foreach($fields as &$field) { $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; } // Set titile $this->addTitleLocalized('New user'); // Pass data to view $this->set('username', $username); $this->set('prename', $prename); $this->set('surname', $surname); $this->set('email', $email); $this->set('validation', $validation); $this->set('validationSettings', $validationSettings); } /** * Action: edit. * * Edit a user. * * @throws \nre\exceptions\IdNotFoundException * @param string $userUrl URL-Username of an user */ public function edit($userUrl) { // User $user = $this->Users->getUserByUrl($userUrl); // Check permissions if(count(array_intersect(array('admin','moderator'), \hhu\z\controllers\IntermediateController::$user['roles'])) == 0 && $user['id'] != \hhu\z\controllers\IntermediateController::$user['id']) { throw new \nre\exceptions\AccessDeniedException(); } // Values $username = $user['username']; $prename = $user['prename']; $surname = $user['surname']; $email = $user['email']; $mailing = $user['mailing']; $fields = array('username', 'prename', 'surname', 'email'); $validation = array(); // Edit user if($this->request->getRequestMethod() == 'POST' && !is_null($this->request->getPostParam('save'))) { // Get params and validate them $validation = $this->Validation->validateParams($this->request->getPostParams(), $fields); $username = $this->request->getPostParam('username'); if($this->Users->usernameExists($username, $user['id'])) { $validation = $this->Validation->addValidationResult($validation, 'username', 'exist', true); } $password = $this->request->getPostParam('password'); if(!empty($password)) { $validation = $this->Validation->addValidationResults($validation, 'password', $this->Validation->validateParam( $this->request->getPostParams(), 'password' ) ); if($password != $this->request->getPostParam('passwordrepeat')) { $validation = $this->Validation->addValidationResult($validation, 'password', 'repeat', false); } } $prename = $this->request->getPostParam('prename'); $surname = $this->request->getPostParam('surname'); $email = $this->request->getPostParam('email'); if($this->Users->emailExists($email, $user['id'])) { $validation = $this->Validation->addValidationResult($validation, 'email', 'exist', true); } $mailing = !is_null($this->request->getPostParam('mailing')); // Save changes if($validation === true) { // Edit user $this->Users->editUser( $user['id'], (count(array_intersect(array('admin','moderator'),\hhu\z\controllers\IntermediateController::$user['roles'])) > 0) ? $this->request->getPostParam('username') : $user['username'], $prename, $surname, $email, $password, $mailing ); // Redirect to entry $user = $this->Users->getUserById($user['id']); $this->redirect($this->linker->link(array('user', $user['url']), 1)); } } // Get validation settings $validationSettings = array(); foreach($fields as &$field) { $validationSettings[$field] = \nre\configs\AppConfig::$validation[$field]; } $validationSettings['password'] = \nre\configs\AppConfig::$validation['password']; // Set titile $this->addTitleLocalized('Edit user'); // Pass data to view $this->set('username', $username); $this->set('prename', $prename); $this->set('surname', $surname); $this->set('email', $email); $this->set('mailing', $mailing); $this->set('validation', $validation); $this->set('validationSettings', $validationSettings); } /** * Action: delete. * * Delete a user. * * @throws \nre\exceptions\IdNotFoundException * @param string $userUrl URL-Username of an user */ public function delete($userUrl) { // User $user = $this->Users->getUserByUrl($userUrl); // Check request method if($this->request->getRequestMethod() == 'POST') { // Check confirmation if(!is_null($this->request->getPostParam('delete'))) { // Delete user $this->Users->deleteUser($user['id']); // Redirect to overview $this->redirect($this->linker->link(null, 1)); } // Redirect to entry $this->redirect($this->linker->link(array('user', $user['url']), 1)); } // Set titile $this->addTitleLocalized('Delete user'); // Show confirmation $this->set('user', $user); } /** * Send mail for new user registration. * * @param array $user Newly registered user */ private function sendRegistrationMail($user) { // Get system moderators $moderators = $this->Users->getUsersWithRole('moderator'); // Send notification mail try { foreach($moderators as &$moderator) { if($moderator['mailing']) { \hhu\z\Utils::sendMail( $moderator['email'], 'userregistration', true, array( $moderator, $user ), $this->linker ); } } } catch(\hhu\z\exceptions\MailingException $e) { $this->log($e->getMessage()); } } } ?>