. * * @package phpservermon * @author Pepijn Over * @copyright Copyright (c) 2008-2015 Pepijn Over * @license http://www.gnu.org/licenses/gpl.txt GNU GPL v3 * @version Release: @package_version@ * @link http://www.phpservermonitor.org/ **/ namespace psm\Module\User\Controller; use psm\Module\AbstractController; use psm\Service\Database; /** * User module. Add, edit and delete users, or assign * servers to users. */ class UserController extends AbstractController { public $servers; function __construct(Database $db, \Twig_Environment $twig) { parent::__construct($db, $twig); $this->setMinUserLevelRequired(PSM_USER_ADMIN); $this->setActions(array( 'index', 'edit', 'delete', 'save', ), 'index'); $this->twig->addGlobal('subtitle', psm_get_lang('menu', 'user')); } public function initialize() { $servers = $this->db->select(PSM_DB_PREFIX.'servers', null, array('server_id', 'label'), '', "ORDER BY `active` ASC, `status` DESC, `label` ASC"); // change the indexes to reflect their server ids foreach($servers as $server) { $this->servers[$server['server_id']] = $server; } return parent::initialize(); } /** * Create HTML to show a list of all users * * @return string */ protected function executeIndex() { $sidebar = new \psm\Util\Module\Sidebar($this->twig); $this->setSidebar($sidebar); $sidebar->addButton( 'add_new', psm_get_lang('system', 'add_new'), psm_build_url(array('mod' => 'user', 'action' => 'edit')), 'plus icon-white', 'success' ); $modal = new \psm\Util\Module\Modal($this->twig, 'delete', \psm\Util\Module\Modal::MODAL_TYPE_DANGER); $this->addModal($modal); $modal->setTitle(psm_get_lang('users', 'delete_title')); $modal->setMessage(psm_get_lang('users', 'delete_message')); $modal->setOKButtonLabel(psm_get_lang('system', 'delete')); // build label array for the next loop $servers_labels = array(); foreach ($this->servers as $server) { $servers_labels[$server['server_id']] = $server['label']; } $users = $this->db->select( PSM_DB_PREFIX.'users', null, array('user_id', 'user_name', 'level', 'name', 'mobile', 'pushover_key', 'pushover_device', 'email'), null, array('name') ); foreach($users as $x => &$user) { $user_servers = $this->getUserServers($user['user_id']); $user['class'] = ($x & 1) ? 'odd' : 'even'; $user['level_text'] = psm_get_lang('users', 'level_' . $user['level']); $user['emp_servers'] = array(); // fix server list foreach($user_servers as $server_id) { if (!isset($servers_labels[$server_id])) continue; $user['emp_servers'][] = array( 'label' => $servers_labels[$server_id] ); } $user['url_delete'] = psm_build_url(array( 'mod' => 'user', 'action' => 'delete', 'id' => $user['user_id'], )); $user['url_edit'] = psm_build_url(array( 'mod' => 'user', 'action' => 'edit', 'id' => $user['user_id'], )); } $tpl_data = $this->getLabels(); $tpl_data['users'] = $users; return $this->twig->render('module/user/user/list.tpl.html', $tpl_data); } /** * Crate HTML for the update screen for a user * * @return string */ protected function executeEdit() { $user_id = isset($_GET['id']) ? intval($_GET['id']) : 0; $fields_prefill = array('name', 'user_name', 'mobile', 'pushover_key', 'pushover_device', 'email'); if($user_id == 0) { // insert mode $title = psm_get_lang('system', 'insert'); $placeholder_password = ''; $lvl_selected = PSM_USER_USER; // default level is regular user // attempt to prefill previously posted fields $edit_user = new \stdClass(); foreach($fields_prefill as $field) { $edit_user->$field = (isset($_POST[$field])) ? $_POST[$field] : ''; } // add inactive class to all servers foreach($this->servers as &$server) { $server['class'] = 'inactive'; } } else { // edit mode try { $this->container->get('util.user.validator')->userId($user_id); } catch(\InvalidArgumentException $e) { $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); return $this->executeIndex(); } $edit_user = $this->getUser()->getUser($user_id); $title = psm_get_lang('system', 'edit') . ' ' . $edit_user->name; $placeholder_password = psm_get_lang('users', 'password_leave_blank'); $lvl_selected = $edit_user->level; // select servers for this user $user_servers = $this->getUserServers($user_id); foreach($this->servers as &$server) { if(in_array($server['server_id'], $user_servers)) { $server['edit_selected'] = 'selected="selected"'; $server['class'] = 'active'; } } } $tpl_data = array( 'titlemode' => $title, 'placeholder_password' => $placeholder_password, 'edit_user_id' => $user_id, 'url_save' => psm_build_url(array( 'mod' => 'user', 'action' => 'save', 'id' => $user_id, )), 'servers' => $this->servers, 'user_level' => $lvl_selected, ); foreach($fields_prefill as $field) { if(isset($edit_user->$field)) { $tpl_data['edit_value_' . $field] = $edit_user->$field; } } $tpl_data['levels'] = array(); foreach($this->container->get('util.user.validator')->getUserLevels() as $lvl) { $tpl_data['levels'][] = array( 'value' => $lvl, 'label' => psm_get_lang('users', 'level_' . $lvl), ); } $tpl_data = array_merge($this->getLabels(), $tpl_data); return $this->twig->render('module/user/user/update.tpl.html', $tpl_data); } /** * Executes the saving of a user */ protected function executeSave() { if(empty($_POST)) { // dont process anything if no data has been posted return $this->executeIndex(); } $user_id = (isset($_GET['id'])) ? intval($_GET['id']) : 0; $fields = array('name', 'user_name', 'password', 'password_repeat', 'level', 'mobile', 'pushover_key', 'pushover_device', 'email'); $clean = array(); foreach($fields as $field) { if(isset($_POST[$field])) { $clean[$field] = trim(strip_tags($_POST[$field])); } else { $clean[$field] = ''; } } $user_validator = $this->container->get('util.user.validator'); try { $user_validator->username($clean['user_name'], $user_id); $user_validator->email($clean['email']); $user_validator->level($clean['level']); // always validate password for new users, // but only validate it for existing users when they change it. if($user_id == 0 || ($user_id > 0 && $clean['password'] != '')) { $user_validator->password($clean['password'], $clean['password_repeat']); } if($user_id > 0) { $user_validator->userId($user_id); } } catch(\InvalidArgumentException $e) { $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); return $this->executeEdit(); } if(!empty($clean['password'])) { $password = $clean['password']; } unset($clean['password_repeat']); if($user_id > 0) { // edit user unset($clean['password']); // password update is executed separately $this->db->save(PSM_DB_PREFIX.'users', $clean, array('user_id' => $user_id)); $this->addMessage(psm_get_lang('users', 'updated'), 'success'); } else { // add user $clean['password'] = ''; // password update is executed separately $user_id = $this->db->save(PSM_DB_PREFIX.'users', $clean); $this->addMessage(psm_get_lang('users', 'inserted'), 'success'); } if(isset($password)) { $this->getUser()->changePassword($user_id, $password); } // update servers $server_idc = psm_POST('server_id', array()); $server_idc_save = array(); foreach($server_idc as $server_id) { $server_idc_save[] = array( 'user_id' => $user_id, 'server_id' => intval($server_id), ); } // delete all existing records $this->db->delete(PSM_DB_PREFIX.'users_servers', array('user_id' => $user_id)); if(!empty($server_idc_save)) { // add all new servers $this->db->insertMultiple(PSM_DB_PREFIX.'users_servers', $server_idc_save); } return $this->executeIndex(); } /** * Executes the deletion of a user */ protected function executeDelete() { $id = (isset($_GET['id'])) ? intval($_GET['id']) : 0; try { $this->container->get('util.user.validator')->userId($id); $this->db->delete(PSM_DB_PREFIX . 'users', array('user_id' => $id,)); $this->db->delete(PSM_DB_PREFIX.'users_servers', array('user_id' => $id)); $this->addMessage(psm_get_lang('users', 'deleted'), 'success'); } catch(\InvalidArgumentException $e) { $this->addMessage(psm_get_lang('users', 'error_' . $e->getMessage()), 'error'); } return $this->executeIndex(); } protected function getLabels() { return array( 'label_users' => psm_get_lang('menu', 'users'), 'label_user' => psm_get_lang('users', 'user'), 'label_name' => psm_get_lang('users', 'name'), 'label_user_name' => psm_get_lang('users', 'user_name'), 'label_password' => psm_get_lang('users', 'password'), 'label_password_repeat' => psm_get_lang('users', 'password_repeat'), 'label_level' => psm_get_lang('users', 'level'), 'label_level_description' => psm_get_lang('users', 'level_description'), 'label_mobile' => psm_get_lang('users', 'mobile'), 'label_pushover' => psm_get_lang('users', 'pushover'), 'label_pushover_description' => psm_get_lang('users', 'pushover_description'), 'label_pushover_key' => psm_get_lang('users', 'pushover_key'), 'label_pushover_device' => psm_get_lang('users', 'pushover_device'), 'label_pushover_device_description' => psm_get_lang('users', 'pushover_device_description'), 'label_email' => psm_get_lang('users', 'email'), 'label_servers' => psm_get_lang('menu', 'server'), 'label_action' => psm_get_lang('system', 'action'), 'label_save' => psm_get_lang('system', 'save'), 'label_go_back' => psm_get_lang('system', 'go_back'), 'label_edit' => psm_get_lang('system', 'edit'), 'label_delete' => psm_get_lang('system', 'delete'), 'label_add_new' => psm_get_lang('system', 'add_new'), ); } /** * Get all server ids for a user * @param int $user_id * @return array with ids only * @todo we should probably find a central place for this kind of stuff */ protected function getUserServers($user_id) { $servers = $this->db->select( PSM_DB_PREFIX.'users_servers', array('user_id' => $user_id), array('server_id') ); $result = array(); foreach($servers as $server) { $result[] = $server['server_id']; } return $result; } }