diff --git a/bootstrap.php b/bootstrap.php index bb9eede3555e3ab0778c2c9dea054cf884ce0041..424f3637c1bc5cc9ecde66edd30fd07555490562 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -80,7 +80,7 @@ class Bootstrap { define('TEAM_TABLE',$prefix.'team'); define('TEAM_MEMBER_TABLE',$prefix.'team_member'); define('DEPT_TABLE',$prefix.'department'); - define('GROUP_TABLE',$prefix.'groups'); + define('GROUP_TABLE', $prefix.'group'); define('GROUP_DEPT_TABLE', $prefix.'group_dept_access'); define('ROLE_TABLE', $prefix.'role'); diff --git a/include/class.config.php b/include/class.config.php index 164171a920a964493fbd24ebe969f814709c65ee..6fd4208b64e2f1e9a0f8fbc3aa5d44a8fb161704 100644 --- a/include/class.config.php +++ b/include/class.config.php @@ -39,6 +39,10 @@ class Config { if (!isset($_SESSION['cfg:'.$this->section])) $_SESSION['cfg:'.$this->section] = array(); $this->session = &$_SESSION['cfg:'.$this->section]; + $this->load(); + } + + function load() { $sql='SELECT id, `key`, value, `updated` FROM '.$this->table .' WHERE `'.$this->section_column.'` = '.db_input($this->section); diff --git a/include/class.dept.php b/include/class.dept.php index d80ceb28aa44c2aa3db88a423dc6fecbec858d13..a3129c909dfe991fe80b3588a5d098fa1d35a997 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -45,7 +45,7 @@ class Dept extends VerySimpleModel { ), ); - var $members; + var $_members; var $_groupids; var $config; @@ -97,11 +97,10 @@ class Dept extends VerySimpleModel { function getEmail() { global $cfg; - if(!$this->email) - if(!($this->email = Email::lookup($this->getEmailId())) && $cfg) - $this->email = $cfg->getDefaultEmail(); + if ($this->email) + return $this->email; - return $this->email; + return $cfg? $cfg->getDefaultEmail() : null; } function getNumMembers() { @@ -109,7 +108,7 @@ class Dept extends VerySimpleModel { } function getMembers($criteria=null) { - if (!$this->members || $criteria) { + if (!$this->_members || $criteria) { $members = Staff::objects() ->filter(Q::any(array( 'dept_id' => $this->getId(), @@ -132,9 +131,9 @@ class Dept extends VerySimpleModel { if ($criteria) return $members->all(); - $this->members = $members->all(); + $this->_members = $members->all(); } - return $this->members; + return $this->_members; } function getAvailableMembers() { @@ -268,21 +267,30 @@ class Dept extends VerySimpleModel { return $this->_groupids; } - function updateGroups($groups_ids) { + function updateGroups($groups_ids, $vars) { - // Groups allowes to access department + // Groups allowed to access department if (is_array($groups_ids)) { - $groups = GroupDept::objects() + $groups = GroupDeptAccess::objects() ->filter(array('dept_id' => $this->getId())); foreach ($groups as $group) { - if ($idx = array_search($group->group_id, $groups_ids)) + if ($idx = array_search($group->group_id, $groups_ids)) { unset($groups_ids[$idx]); - else + $roleId = $vars['group'.$group->group_id.'_role_id']; + if ($roleId != $group->role_id) { + $group->set('role_id', $roleId ?: 0); + $group->save(); + } + } else { $group->delete(); + } } foreach ($groups_ids as $id) { - GroupDept::create(array( - 'dept_id'=>$this->getId(), 'group_id'=>$id + $roleId = $vars['group'.$id.'_role_id']; + GroupDeptAccess::create(array( + 'dept_id' => $this->getId(), + 'group_id' => $id, + 'role_id' => $roleId ?: 0, ))->save(); } } @@ -290,7 +298,7 @@ class Dept extends VerySimpleModel { } function updateSettings($vars) { - $this->updateGroups($vars['groups'] ?: array()); + $this->updateGroups($vars['groups'] ?: array(), $vars); $this->getConfig()->set('assign_members_only', $vars['assign_members_only']); return true; } @@ -302,9 +310,7 @@ class Dept extends VerySimpleModel { // Default department cannot be deleted || $this->getId()==$cfg->getDefaultDeptId() // Department with users cannot be deleted - || Staff::objects() - ->filter(array('dept_id'=>$this->getId())) - ->count() + || $this->members->count() ) { return 0; } @@ -482,7 +488,10 @@ class GroupDeptAccess extends VerySimpleModel { 'constraint' => array('dept_id' => 'Dept.id'), ), 'group' => array( - 'constraint' => array('group_id' => 'Group.group_id'), + 'constraint' => array('group_id' => 'Group.id'), + ), + 'role' => array( + 'constraint' => array('role_id' => 'Role.id'), ), ), ); diff --git a/include/class.group.php b/include/class.group.php index 48fe6dba40031feb556783b88f72a42d7080041c..3bbf296f5ecbfaf2173311ac1f23a4124b31746b 100644 --- a/include/class.group.php +++ b/include/class.group.php @@ -18,37 +18,79 @@ class Group extends VerySimpleModel { static $meta = array( 'table' => GROUP_TABLE, - 'pk' => array('group_id'), + 'pk' => array('id'), + 'joins' => array( + 'members' => array( + 'null' => true, + 'list' => true, + 'reverse' => 'Staff.group', + ), + 'depts' => array( + 'null' => true, + 'list' => true, + 'reverse' => 'GroupDeptAccess.group', + ), + 'role' => array( + 'constraint' => array('role_id' => 'Role.id') + ), + ), ); - var $members; + const FLAG_ENABLED = 0X0001; + var $departments; function getHashtable() { $base = $this->ht; - $base['name'] = $base['group_name']; - $base['isactive'] = $base['group_enabled']; + $base['name'] = $base['name']; + $base['isactive'] = $base['flags']; return $base; } - function getInfo(){ + function getInfo() { return $this->getHashtable(); } - function getId(){ - return $this->group_id; + function getId() { + return $this->id; + } + + function getRoleId() { + return $this->role_id; } - function getName(){ - return $this->group_name; + function getRole($deptId=0) { + + if ($deptId // Department specific role. + && ($roles=$this->getDepartmentsAccess()) + && isset($roles[$deptId]) + && $roles[$deptId] + && ($role=Role::lookup($roles[$deptId])) + && $role->isEnabled()) + return $role; + + // Default role for this group. + return $this->role; } - function getNumUsers(){ - return Staff::objects()->filter(array('group_id'=>$this->getId()))->count(); + function getName() { + return $this->name; } - function isEnabled(){ - return $this->group_enabled; + function getCreateDate() { + return $this->created; + } + + function getUpdateDate() { + return $this->updated; + } + + function getNumMembers() { + return $this->members ? $this->members->count() : 0; + } + + function isEnabled() { + $this->get('flags') & self::FLAG_ENABLED !== 0; } function isActive(){ @@ -81,34 +123,47 @@ class Group extends VerySimpleModel { return $this->members; } - //Get departments the group is allowed to access. + //Get departments & roles the group is allowed to access. function getDepartments() { + return array_keys($this->getDepartmentsAccess()); + } + + function getDepartmentsAccess() { if (!isset($this->departments)) { $this->departments = array(); foreach (GroupDeptAccess::objects() ->filter(array('group_id'=>$this->getId())) - ->values_flat('dept_id') as $gda + ->values_flat('dept_id', 'role_id') as $gda ) { - $this->departments[] = $gda[0]; + $this->departments[$gda[0]] = $gda[1]; } } + return $this->departments; } - - function updateDeptAccess($dept_ids) { + function updateDeptAccess($dept_ids, $vars=array()) { if (is_array($dept_ids)) { $groups = GroupDeptAccess::objects() ->filter(array('group_id' => $this->getId())); foreach ($groups as $group) { - if ($idx = array_search($group->dept_id, $dept_ids)) + if ($idx = array_search($group->dept_id, $dept_ids)) { unset($dept_ids[$idx]); - else + $roleId = $vars['dept'.$group->dept_id.'_role_id']; + if ($roleId != $group->role_id) { + $group->set('role_id', $roleId ?: 0); + $group->save(); + } + } else { $group->delete(); + } } foreach ($dept_ids as $id) { + $roleId = $vars['dept'.$id.'_role_id']; GroupDeptAccess::create(array( - 'group_id'=>$this->getId(), 'dept_id'=>$id + 'group_id' => $this->getId(), + 'dept_id' => $id, + 'role_id' => $roleId ?: 0 ))->save(); } } @@ -118,7 +173,7 @@ class Group extends VerySimpleModel { function delete() { // Can't delete with members - if ($this->getNumUsers()) + if ($this->getNumMembers()) return false; if (!parent::delete()) @@ -132,45 +187,8 @@ class Group extends VerySimpleModel { return true; } - /*** Static functions ***/ - static function getIdByName($name){ - $id = static::objects()->filter(array('group_name'=>trim($name))) - ->values_flat('group_id')->first(); - - return $id ? $id[0] : 0; - } - - static function getGroupNames($localize=true) { - static $groups=array(); - - if (!$groups) { - $query = static::objects() - ->values_flat('group_id', 'group_name', 'group_enabled') - ->order_by('group_name'); - foreach ($query as $row) { - list($id, $name, $enabled) = $row; - $groups[$id] = sprintf('%s%s', - self::getLocalById($id, 'name', $name), - $enabled ? '' : ' ' . __('(disabled)')); - } - } - // TODO: Sort groups if $localize - return $groups; - } - - static function create($vars=false) { - $group = parent::create($vars); - $group->created = SqlFunction::NOW(); - return $group; - } - - static function __create($vars, &$errors) { - $g = self::create($vars); - $g->save(); - if ($vars['depts']) - $g->updateDeptAccess($vars['depts']); - - return $g; + function __toString() { + return $this->getName(); } function save($refetch=false) { @@ -181,40 +199,37 @@ class Group extends VerySimpleModel { } function update($vars,&$errors) { - if (isset($this->group_id) && $this->getId() != $vars['id']) - $errors['err']=__('Missing or invalid group ID'); + if (isset($this->id) && $this->getId() != $vars['id']) + $errors['err'] = __('Missing or invalid group ID'); if (!$vars['name']) { - $errors['name']=__('Group name required'); + $errors['name'] = __('Group name required'); } elseif(strlen($vars['name'])<3) { - $errors['name']=__('Group name must be at least 3 chars.'); + $errors['name'] = __('Group name must be at least 3 chars.'); } elseif (($gid=static::getIdByName($vars['name'])) - && (!isset($this->group_id) || $gid!=$this->getId())) { - $errors['name']=__('Group name already exists'); + && (!isset($this->id) || $gid!=$this->getId())) { + $errors['name'] = __('Group name already exists'); } + if (!$vars['role_id']) + $errors['role_id'] = __('Role selection required'); + if ($errors) return false; - $this->group_name=Format::striptags($vars['name']); - $this->group_enabled=$vars['isactive']; - $this->can_create_tickets=$vars['can_create_tickets']; - $this->can_delete_tickets=$vars['can_delete_tickets']; - $this->can_edit_tickets=$vars['can_edit_tickets']; - $this->can_assign_tickets=$vars['can_assign_tickets']; - $this->can_transfer_tickets=$vars['can_transfer_tickets']; - $this->can_close_tickets=$vars['can_close_tickets']; - $this->can_ban_emails=$vars['can_ban_emails']; - $this->can_manage_premade=$vars['can_manage_premade']; - $this->can_manage_faq=$vars['can_manage_faq']; - $this->can_post_ticket_reply=$vars['can_post_ticket_reply']; - $this->can_view_staff_stats=$vars['can_view_staff_stats']; - $this->notes=Format::sanitize($vars['notes']); + $this->name = Format::striptags($vars['name']); + $this->role_id = $vars['role_id']; + $this->notes = Format::sanitize($vars['notes']); + + if ($vars['isactive']) + $this->flags = ($this->flags | self::FLAG_ENABLED); + else + $this->flags = ($this->flags & ~self::FLAG_ENABLED); if ($this->save()) - return $this->updateDeptAccess($vars['depts'] ?: array()); + return $this->updateDeptAccess($vars['depts'] ?: array(), $vars); - if (isset($this->group_id)) { + if (isset($this->id)) { $errors['err']=sprintf(__('Unable to update %s.'), __('this group')) .' '.__('Internal error occurred'); } @@ -224,5 +239,72 @@ class Group extends VerySimpleModel { } return false; } + + /*** Static functions ***/ + static function getIdByName($name){ + $id = static::objects()->filter(array('name'=>trim($name))) + ->values_flat('id')->first(); + + return $id ? $id[0] : 0; + } + + static function create($vars=false) { + $group = parent::create($vars); + $group->created = SqlFunction::NOW(); + return $group; + } + + static function __create($vars, &$errors) { + $g = self::create($vars); + $g->save(); + if ($vars['depts']) + $g->updateDeptAccess($vars['depts'], $vars); + + return $g; + } + + static function getGroups($criteria=array()) { + static $groups = null; + if (!isset($groups) || $criteria) { + $groups = array(); + $query = static::objects() + ->values_flat('id', 'name', 'flags') + ->order_by('name'); + + $filters = array(); + if (isset($criteria['active'])) + $filters += array( + 'isactive' => $criteria['active'] ? 1 : 0); + + if ($filters) + $query->filter($filters); + + $names = array(); + foreach ($query as $row) { + list($id, $name, $flags) = $row; + $names[$id] = sprintf('%s%s', + self::getLocalById($id, 'name', $name), + $flags ? '' : ' ' . __('(disabled)')); + } + + //TODO: sort if $criteria['localize']; + if ($criteria) + return $names; + + $groups = $names; + } + + return $groups; + } + + static function getActiveGroups() { + static $groups = null; + + if (!isset($groups)) + $groups = self::getGroups(array('active'=>true)); + + return $groups; + } + } ?> diff --git a/include/class.staff.php b/include/class.staff.php index 473dc42d23e82616e15890cfe68dfaea58508a79..ebdce1aaa0aa7da41cd0316fe33b897f903b2831 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -17,6 +17,7 @@ include_once(INCLUDE_DIR.'class.ticket.php'); include_once(INCLUDE_DIR.'class.dept.php'); include_once(INCLUDE_DIR.'class.error.php'); include_once(INCLUDE_DIR.'class.team.php'); +include_once(INCLUDE_DIR.'class.role.php'); include_once(INCLUDE_DIR.'class.group.php'); include_once(INCLUDE_DIR.'class.passwd.php'); include_once(INCLUDE_DIR.'class.user.php'); @@ -34,7 +35,7 @@ implements AuthenticatedUser { 'constraint' => array('dept_id' => 'Dept.id'), ), 'group' => array( - 'constraint' => array('group_id' => 'Group.group_id'), + 'constraint' => array('group_id' => 'Group.id'), ), 'teams' => array( 'null' => true, @@ -276,7 +277,7 @@ implements AuthenticatedUser { } function isGroupActive() { - return $this->group->group_enabled; + return $this->group->isEnabled(); } function isactive() { @@ -602,7 +603,7 @@ implements AuthenticatedUser { if ($availableonly) { $members = $members->filter(array( - 'group__group_enabled' => 1, + 'group__flags__hasbit' => Group::FLAG_ENABLED, 'onvacation' => 0, 'isactive' => 1, )); @@ -610,7 +611,7 @@ implements AuthenticatedUser { $users=array(); foreach ($members as $M) { - $users[$M->id] = $M->getName(); + $users[$M->getId()] = $M->getName(); } return $users; diff --git a/include/i18n/en_US/group.yaml b/include/i18n/en_US/group.yaml index 66acefa239cab0722ed74bc0eb1dcc567926bc03..9354e343edc2add4fd535115349faef1e2911558 100644 --- a/include/i18n/en_US/group.yaml +++ b/include/i18n/en_US/group.yaml @@ -2,29 +2,11 @@ # Default groups defined for the system # # Fields: -# isactive - (bool:0|1) true or false if the group should be initially -# usable +# id - Primary id for the group +# role_id - (int) default role for the group +# flags - (bit mask) group flags # name - (string) descriptive name for the group # notes - (string) administrative notes (viewable internally only) -# can_create_tickets - (bool:0|1) true or false if users of the group can -# create new tickets -# can_edit_tickets - (bool:0|1) true or false if users of the group can -# modify and update existing tickets -# can_delete_tickets - (bool:0|1) true or false if members of the group can -# delete tickets (permanently) -# can_close_tickets - (bool:0|1) true or false if members of the group can -# close active tickets -# can_assign_ticets - (bool:0|1) true or false if members of the group can -# assign tickets to staff -# can_transfer_tickets - (bool:0|1) true or false if members of the group -# can change the department tickets are assigne dto -# can_ban_emails - (bool:0|1) true or false if members of the group can add -# emails to the system ban list -# can_manage_premade - (bool:0|1) true or false if members of the group can -# create, modify, and delete canned responses -# can_manage_faq - (bool:0|1) true or false if members of the group can -# manage the customer-facing and internal knowledgebase -# # depts: (list<Department<id>>) id's of the departments to which the group # should initially have access # @@ -32,54 +14,30 @@ # The very first group listed in this document will be the primary group of # the initial staff member -- the administrator. --- -- group_enabled: 1 - group_name: Lion Tamers +- id: 1 + role_id: 1 + flags: 1 + name: Lion Tamers notes: | System overlords. These folks (initially) have full control to all the departments they have access to. - can_create_tickets: 1 - can_edit_tickets: 1 - can_delete_tickets: 1 - can_close_tickets: 1 - can_assign_tickets: 1 - can_transfer_tickets: 1 - can_ban_emails: 1 - can_manage_premade: 1 - can_manage_faq: 1 - can_post_ticket_reply: 1 depts: [1, 2, 3] -- group_enabled: 1 - group_name: Elephant Walkers +- id: 2 + role_id: 2 + flags: 1 + name: Elephant Walkers notes: | Inhabitants of the ivory tower - can_create_tickets: 1 - can_edit_tickets: 1 - can_delete_tickets: 1 - can_close_tickets: 1 - can_assign_tickets: 1 - can_transfer_tickets: 1 - can_ban_emails: 1 - can_manage_premade: 1 - can_manage_faq: 1 - can_post_ticket_reply: 1 depts: [1, 2, 3] -- group_enabled: 1 - group_name: Flea Trainers +- id: 3 + role_id: 3 + flags: 1 + name: Flea Trainers notes: | Lowly staff members - can_create_tickets: 1 - can_edit_tickets: 1 - can_delete_tickets: 0 - can_close_tickets: 1 - can_assign_tickets: 1 - can_transfer_tickets: 1 - can_ban_emails: 0 - can_manage_premade: 0 - can_manage_faq: 0 - can_post_ticket_reply: 1 depts: [1, 2, 3] diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php index 7681645200ae9f88d6e3171cf987bc91342ba8f5..6828b06925d9bdee216ed73825707b5e8eafeae7 100644 --- a/include/staff/department.inc.php +++ b/include/staff/department.inc.php @@ -7,10 +7,9 @@ if($dept && $_REQUEST['a']!='add') { $title=__('Update Department'); $action='update'; $submit_text=__('Save Changes'); - $info=$dept->getInfo(); - $info['id']=$dept->getId(); + $info = $dept->getInfo(); + $info['id'] = $dept->getId(); $info['groups'] = $dept->getAllowedGroups(); - $qstr.='&id='.$dept->getId(); } else { $title=__('Add New Department'); @@ -23,8 +22,10 @@ if($dept && $_REQUEST['a']!='add') { $info['group_membership'] = 1; $qstr.='&a='.$_REQUEST['a']; + } -$info=Format::htmlchars(($errors && $_POST)?$_POST:$info); + +$info = Format::htmlchars(($errors && $_POST) ? $_POST : $info); ?> <form action="departments.php?<?php echo $qstr; ?>" method="post" id="save"> <?php csrf_token(); ?> @@ -32,6 +33,14 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>"> <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> <h2><?php echo __('Department');?></h2> +<br> +<ul class="tabs"> + <li class="active"><a href="#settings"> + <i class="icon-file"></i> <?php echo __('Settings'); ?></a></li> + <li><a href="#access"> + <i class="icon-lock"></i> <?php echo __('Access'); ?></a></li> +</ul> +<div id="settings" class="tab_content"> <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2"> <thead> <tr> @@ -47,7 +56,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <?php echo __('Name');?>: </td> <td> - <input data-translate-tag="<?php echo $dept ? $dept->getTranslationTag() : ''; + <input data-translate-tag="<?php echo $dept ? $dept->getTranslateTag() : ''; ?>" type="text" size="30" name="name" value="<?php echo $info['name']; ?>"> <span class="error">* <?php echo $errors['name']; ?></span> </td> @@ -250,30 +259,6 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </span> </td> </tr> - <tr> - <th colspan="2"> - <em><strong><?php echo __('Group Access'); ?></strong>: - <?php echo __('Check all groups allowed to access this department.'); ?> - <i class="help-tip icon-question-sign" href="#department_access"></i></em> - </th> - </tr> - <?php - $sql='SELECT group_id, group_name, count(staff.staff_id) as members ' - .' FROM '.GROUP_TABLE.' grp ' - .' LEFT JOIN '.STAFF_TABLE. ' staff USING(group_id) ' - .' GROUP by grp.group_id ' - .' ORDER BY group_name'; - if(($res=db_query($sql)) && db_num_rows($res)){ - while(list($id, $name, $members) = db_fetch_row($res)) { - if($members>0) - $members=sprintf('<a href="staff.php?a=filter&gid=%d">%d</a>', $id, $members); - - $ck=($info['groups'] && in_array($id,$info['groups']))?'checked="checked"':''; - echo sprintf('<tr><td colspan=2> <label><input type="checkbox" name="groups[]" value="%d" %s> %s</label> (%s)</td></tr>', - $id, $ck, $name, $members); - } - } - ?> <tr> <th colspan="2"> <em><strong><?php echo __('Department Signature'); ?></strong>: @@ -289,9 +274,92 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); </tr> </tbody> </table> +</div> +<div id="access" class="tab_content" style="display:none"> + <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2"> + <thead> + <tr> + <th colspan=2> + <em><?php echo __('Primary department members have access to this department by default'); ?></em> + </th> + </tr> + <tr> + <th width="40%"><?php echo __('Group'); ?></th> + <th><?php echo __('Role'); ?></th> + </tr> + </thead> + <tbody> + <?php + $deptId = $dept ? $dept->getId() : 0; + $roles = Role::getRoles(); + $groups = Group::objects() + ->annotate(array( + 'isenabled'=>new SqlExpr(array( + 'flags__hasbit' => Group::FLAG_ENABLED)) + )) + ->order_by('name'); + foreach ($groups as $group) { + $DeptAccess = $group->getDepartmentsAccess(); + ?> + <tr> + <td> + + <label> + <?php + $ck = ($info['groups'] && in_array($group->getId(), $info['groups'])) ? 'checked="checked"' : ''; + echo sprintf('%s %s', + sprintf('<input type="checkbox" class="grp-ckb" + name="groups[]" value="%s" %s />', + $group->getId(), $ck), + Format::htmlchars($group->getName())); + ?> + </label> + </td> + <td> + <?php + $_name = 'group'.$group->getId().'_role_id'; + ?> + <select name="<?php echo $_name; ?>"> + <option value="0">— <?php + echo sprintf('%s (%s)', + __('Group Default'), + $group->getRole()); + ?> + —</option> + <?php + foreach ($roles as $rid => $role) { + $sel = ''; + if (isset($info[$_name])) + $sel = ($info[$_name] == $rid) ? 'selected="selected"' : ''; + elseif ($deptId && isset($DeptAccess[$deptId])) + $sel = ($DeptAccess[$deptId] == $rid) ? 'selected="selected"' : ''; + + echo sprintf('<option value="%d" %s>%s</option>', + $rid, $sel, $role); + } ?> + </select> + <i class="help-tip icon-question-sign" href="#dept-role"></i> + </td> + </tr> + <?php + } ?> + </tbody> + <tfoot> + <tr> + <td colspan="2"> + <?php echo __('Select');?>: + <a id="selectAll" href="#grp-ckb"><?php echo __('All');?></a> + <a id="selectNone" href="#grp-ckb"><?php echo __('None');?></a> + <a id="selectToggle" href="#grp-ckb"><?php echo __('Toggle');?></a> + </td> + </tr> + </tfoot> + </table> +</div> <p style="text-align:center"> <input type="submit" name="submit" value="<?php echo $submit_text; ?>"> <input type="reset" name="reset" value="<?php echo __('Reset');?>"> - <input type="button" name="cancel" value="<?php echo __('Cancel');?>" onclick='window.location.href="departments.php"'> + <input type="button" name="cancel" value="<?php echo __('Cancel');?>" + onclick='window.location.href="?"'> </p> </form> diff --git a/include/staff/group.inc.php b/include/staff/group.inc.php index 74cc64cb479f4e450df44b8c60ebf8e3645419ab..d471b791d8da636d5897153fd8e886bcf6332af4 100644 --- a/include/staff/group.inc.php +++ b/include/staff/group.inc.php @@ -1,50 +1,58 @@ <?php -if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied'); + $info=array(); -$qstr=''; -if($group && $_REQUEST['a']!='add'){ - $title=__('Update Group'); - $action='update'; - $submit_text=__('Save Changes'); - $info=$group->getInfo(); - $info['id']=$group->getId(); - $info['depts']=$group->getDepartments(); +if ($group) { + $title = __('Update Group'); + $action = 'update'; + $submit_text = __('Save Changes'); + $info = $group->getInfo(); + $info['id'] = $group->getId(); + $info['depts'] = $group->getDepartments(); $trans['name'] = $group->getTranslateTag('name'); - $qstr.='&id='.$group->getId(); -}else { - $title=__('Add New Group'); - $action='create'; - $submit_text=__('Create Group'); - $info['isactive']=isset($info['isactive'])?$info['isactive']:1; - $info['can_create_tickets']=isset($info['can_create_tickets'])?$info['can_create_tickets']:1; - $qstr.='&a='.$_REQUEST['a']; +} else { + $title = __('Add New Group'); + $action = 'add'; + $submit_text = __('Create Group'); + $info['isactive'] = isset($info['isactive']) ? $info['isactive'] : 1; } -$info=Format::htmlchars(($errors && $_POST)?$_POST:$info); + +$info = Format::htmlchars(($errors && $_POST) ? array_merge($info, $_POST) : $info); +$roles = Role::getActiveRoles(); + ?> -<form action="groups.php?<?php echo $qstr; ?>" method="post" id="save" name="group"> - <?php csrf_token(); ?> - <input type="hidden" name="do" value="<?php echo $action; ?>"> - <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>"> - <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> - <h2><?php echo __('Group Access and Permissions');?></h2> - <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2"> +<form action="" method="post" id="save"> + <?php csrf_token(); ?> + <input type="hidden" name="do" value="<?php echo $action; ?>"> + <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>"> + <input type="hidden" name="id" value="<?php echo $info['id']; ?>"> +<h2> <?php echo $group ?: __('New Group'); ?></h2> +<br> +<ul class="tabs"> + <li class="active"><a href="#group"> + <i class="icon-file"></i> <?php echo __('Group'); ?></a></li> + <li><a href="#departments"> + <i class="icon-lock"></i> <?php echo __('Departments Access'); ?></a></li> +</ul> +<div id="group" class="tab_content"> + <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2"> <thead> <tr> <th colspan="2"> <h4><?php echo $title; ?></h4> - <em><strong><?php echo __('Group Information');?></strong>: <?php echo __("Disabled group will limit agents' access. Admins are exempted.");?></em> + <em><?php echo __( + 'Roles are used to define agents\' permissions' + ); ?> <i class="help-tip icon-question-sign" + href="#roles"></i></em> </th> </tr> </thead> <tbody> <tr> - <td width="180" class="required"> - <?php echo __('Name');?>: - </td> + <td width="180" class="required"><?php echo __('Name'); ?>:</td> <td> - <input type="text" size="30" name="name" value="<?php echo $info['name']; ?>" + <input size="50" type="text" name="name" value="<?php echo $info['name']; ?>" data-translate-tag="<?php echo $trans['name']; ?>"/> - <span class="error">* <?php echo $errors['name']; ?></span> + <span class="error">* <?php echo $errors['name']; ?></span> </td> </tr> <tr> @@ -52,137 +60,121 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <?php echo __('Status');?>: </td> <td> - <input type="radio" name="isactive" value="1" <?php echo $info['isactive']?'checked="checked"':''; ?>><strong><?php echo __('Active');?></strong> + <input type="radio" name="isactive" value="1" <?php + echo $info['isactive'] ? 'checked="checked"' : ''; ?>><strong><?php echo __('Active');?></strong> - <input type="radio" name="isactive" value="0" <?php echo !$info['isactive']?'checked="checked"':''; ?>><strong><?php echo __('Disabled');?></strong> + <input type="radio" name="isactive" value="0" <?php + echo !$info['isactive'] ? 'checked="checked"' : ''; ?>><strong><?php echo __('Disabled');?></strong> <span class="error">* <?php echo $errors['status']; ?></span> <i class="help-tip icon-question-sign" href="#status"></i> </td> </tr> <tr> - <th colspan="2"> - <em><strong><?php echo __('Group Permissions');?></strong>: <?php echo __('Applies to all group members');?> </em> - </th> - </tr> - <tr><td><?php echo __('Can <b>Create</b> Tickets');?></td> - <td> - <input type="radio" name="can_create_tickets" value="1" <?php echo $info['can_create_tickets']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_create_tickets" value="0" <?php echo !$info['can_create_tickets']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to open tickets on behalf of users.');?></i> - </td> - </tr> - <tr><td><?php echo __('Can <b>Edit</b> Tickets</td>');?> - <td> - <input type="radio" name="can_edit_tickets" value="1" <?php echo $info['can_edit_tickets']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_edit_tickets" value="0" <?php echo !$info['can_edit_tickets']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to edit tickets.');?></i> - </td> - </tr> - <tr><td><?php echo __('Can <b>Post Reply</b>');?></td> - <td> - <input type="radio" name="can_post_ticket_reply" value="1" <?php echo $info['can_post_ticket_reply']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_post_ticket_reply" value="0" <?php echo !$info['can_post_ticket_reply']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to post a ticket reply.');?></i> - </td> - </tr> - <tr><td><?php echo __('Can <b>Close</b> Tickets');?></td> - <td> - <input type="radio" name="can_close_tickets" value="1" <?php echo $info['can_close_tickets']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_close_tickets" value="0" <?php echo !$info['can_close_tickets']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to close tickets. Agents can still post a response.');?></i> - </td> - </tr> - <tr><td><?php echo __('Can <b>Assign</b> Tickets');?></td> - <td> - <input type="radio" name="can_assign_tickets" value="1" <?php echo $info['can_assign_tickets']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_assign_tickets" value="0" <?php echo !$info['can_assign_tickets']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to assign tickets to agents.');?></i> - </td> - </tr> - <tr><td><?php echo __('Can <b>Transfer</b> Tickets');?></td> - <td> - <input type="radio" name="can_transfer_tickets" value="1" <?php echo $info['can_transfer_tickets']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_transfer_tickets" value="0" <?php echo !$info['can_transfer_tickets']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to transfer tickets between departments.');?></i> - </td> - </tr> - <tr><td><?php echo __('Can <b>Delete</b> Tickets');?></td> - <td> - <input type="radio" name="can_delete_tickets" value="1" <?php echo $info['can_delete_tickets']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_delete_tickets" value="0" <?php echo !$info['can_delete_tickets']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __("Ability to delete tickets (Deleted tickets can't be recovered!)");?></i> - </td> - </tr> - <tr><td><?php echo __('Can Ban Emails');?></td> - <td> - <input type="radio" name="can_ban_emails" value="1" <?php echo $info['can_ban_emails']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_ban_emails" value="0" <?php echo !$info['can_ban_emails']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to add/remove emails from banlist via ticket interface.');?></i> + <td width="180" class="required"> + <?php echo __('Default Role');?>: </td> - </tr> - <tr><td><?php echo __('Can Manage Premade');?></td> <td> - <input type="radio" name="can_manage_premade" value="1" <?php echo $info['can_manage_premade']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_manage_premade" value="0" <?php echo !$info['can_manage_premade']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to add/update/disable/delete canned responses and attachments.');?></i> + <select name="role_id"> + <option value="0">Select One</option> + <?php + foreach ($roles as $id => $role) { + $sel = ($info['role_id'] == $id) ? 'selected="selected"' : ''; + echo sprintf('<option value="%d" %s>%s</option>', + $id, $sel, $role); + } ?> + </select> + <span class="error">* <?php echo $errors['role_id']; ?></span> + <i class="help-tip icon-question-sign" href="#role"></i> </td> </tr> - <tr><td><?php echo __('Can Manage FAQ');?></td> - <td> - <input type="radio" name="can_manage_faq" value="1" <?php echo $info['can_manage_faq']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_manage_faq" value="0" <?php echo !$info['can_manage_faq']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to add/update/disable/delete knowledgebase categories and FAQs.');?></i> - </td> + </tbody> + <tbody> + <tr> + <th colspan="7"> + <em><strong><?php echo __('Internal Notes'); ?></strong> </em> + </th> </tr> - <tr><td><?php echo __('Can View Agent Stats');?></td> - <td> - <input type="radio" name="can_view_staff_stats" value="1" <?php echo $info['can_view_staff_stats']?'checked="checked"':''; ?> /><?php echo __('Yes');?> - - <input type="radio" name="can_view_staff_stats" value="0" <?php echo !$info['can_view_staff_stats']?'checked="checked"':''; ?> /><?php echo __('No');?> - <i><?php echo __('Ability to view stats of other agents in allowed departments.');?></i> + <tr> + <td colspan="7"><textarea name="notes" class="richtext no-bar" + rows="6" cols="80"><?php + echo $info['notes']; ?></textarea> </td> </tr> + </tbody> + </table> +</div> +<div id="departments" class="tab_content" style="display:none"> + <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2"> + <thead> <tr> - <th colspan="2"> - <em><strong><?php echo __('Department Access');?></strong>: - <i class="help-tip icon-question-sign" href="#department_access"></i> - <a id="selectAll" href="#deptckb"><?php echo __('Select All');?></a> - - <a id="selectNone" href="#deptckb"><?php echo __('Select None');?></a></em> + <th colspan=2> + <em><?php echo __('Check departments the group is allowed to access and optionally select an effective role.') ?></em> </th> </tr> - <?php - foreach (Dept::getDepartments() as $id=>$name) { - $ck=($info['depts'] && in_array($id,$info['depts']))?'checked="checked"':''; - echo sprintf('<tr><td colspan=2> <input type="checkbox" class="deptckb" name="depts[]" value="%d" %s> %s</td></tr>',$id,$ck,$name); - } - ?> <tr> - <th colspan="2"> - <em><strong><?php echo __('Admin Notes');?></strong>: <?php echo __('Internal notes viewable by all admins.');?> </em> - </th> + <th width="40%"><?php echo __('Department'); ?></th> + <th><?php echo __('Group Role'); ?></th> </tr> - <tr> - <td colspan=2> - <textarea class="richtext no-bar" name="notes" cols="21" - rows="8" style="width: 80%;"><?php echo $info['notes']; ?></textarea> + </thead> + <tbody> + <?php + foreach (Dept::getDepartments() as $deptId => $name) { ?> + <tr> + <td> + + <label> + <?php + $ck = ($info['depts'] && in_array($deptId, $info['depts'])) ? 'checked="checked"' : ''; + echo sprintf('%s %s', + sprintf('<input type="checkbox" class="dept-ckb" + name="depts[]" value="%s" %s />', + $deptId, $ck), + Format::htmlchars($name)); + ?> + </label> </td> - </tr> + <td> + <?php + $DeptAccess = $group ? $group->getDepartmentsAccess() : array(); + $_name = 'dept'.$deptId.'_role_id'; + ?> + <select name="<?php echo $_name; ?>"> + <option value="0">— <?php + echo __('Group Default'); ?> —</option> + <?php + foreach ($roles as $rid => $role) { + $sel = ''; + if (isset($info[$_name])) + $sel = ($info[$_name] == $rid) ? 'selected="selected"' : ''; + elseif ($DeptAccess && isset($DeptAccess[$deptId])) + $sel = ($DeptAccess[$deptId] == $rid) ? 'selected="selected"' : ''; + + echo sprintf('<option value="%d" %s>%s</option>', + $rid, $sel, $role); + } ?> + </select> + <i class="help-tip icon-question-sign" href="#dept-role"></i> + </td> + </tr> + <?php + } ?> </tbody> -</table> -<p style="text-align:center"> + <tfoot> + <tr> + <td colspan="2"> + <?php echo __('Select');?>: + <a id="selectAll" href="#dept-ckb"><?php echo __('All');?></a> + <a id="selectNone" href="#dept-ckb"><?php echo __('None');?></a> + <a id="selectToggle" href="#dept-ckb"><?php echo __('Toggle');?></a> + </td> + </tr> + </tfoot> + </table> +</div> +<p class="centered"> <input type="submit" name="submit" value="<?php echo $submit_text; ?>"> - <input type="reset" name="reset" value="<?php echo __('Reset');?>"> - <input type="button" name="cancel" value="<?php echo __('Cancel');?>" onclick='window.location.href="groups.php"'> + <input type="reset" name="reset" value="<?php echo __('Reset'); ?>"> + <input type="button" name="cancel" value="<?php echo __('Cancel'); ?>" + onclick='window.location.href="?"'> </p> </form> diff --git a/include/staff/groups.inc.php b/include/staff/groups.inc.php index 326400daa0ba12932943c96934a7783ffb13af92..ac3f438956466eaa2ba695303e8ddae8152ac076 100644 --- a/include/staff/groups.inc.php +++ b/include/staff/groups.inc.php @@ -1,43 +1,44 @@ <?php -if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied'); +if (!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) + die('Access Denied'); -$qstr=''; +$qstr = ''; +$sortOptions = array( + 'name' => 'name', + 'users' => 'members_count', + 'depts' => 'depts_count', + 'status' => 'isenabled', + 'created'=> 'created', + 'updated'=> 'updated'); + +$orderWays = array('DESC'=>'DESC', 'ASC'=>'ASC'); +$sort = ($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])]) ? strtolower($_REQUEST['sort']) : 'name'; -$sql='SELECT grp.*,count(DISTINCT staff.staff_id) as users, count(DISTINCT dept.dept_id) as depts ' - .' FROM '.GROUP_TABLE.' grp ' - .' LEFT JOIN '.STAFF_TABLE.' staff ON(staff.group_id=grp.group_id) ' - .' LEFT JOIN '.GROUP_DEPT_TABLE.' dept ON(dept.group_id=grp.group_id) ' - .' WHERE 1'; -$sortOptions=array('name'=>'grp.group_name','status'=>'grp.group_enabled', - 'users'=>'users', 'depts'=>'depts', 'created'=>'grp.created','updated'=>'grp.updated'); -$orderWays=array('DESC'=>'DESC','ASC'=>'ASC'); -$sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'name'; //Sorting options... -if($sort && $sortOptions[$sort]) { - $order_column =$sortOptions[$sort]; +if ($sort && $sortOptions[$sort]) { + $order_column = $sortOptions[$sort]; } -$order_column=$order_column?$order_column:'grp.group_name'; -if($_REQUEST['order'] && $orderWays[strtoupper($_REQUEST['order'])]) { - $order=$orderWays[strtoupper($_REQUEST['order'])]; +$order_column = $order_column ? $order_column : 'name'; + +if ($_REQUEST['order'] && isset($orderWays[strtoupper($_REQUEST['order'])])) { + $order = $orderWays[strtoupper($_REQUEST['order'])]; +} else { + $order = 'ASC'; } -$order=$order?$order:'ASC'; -if($order_column && strpos($order_column,',')){ +if ($order_column && strpos($order_column,',')) { $order_column=str_replace(','," $order,",$order_column); } $x=$sort.'_sort'; $$x=' class="'.strtolower($order).'" '; -$order_by="$order_column $order "; - +$page = ($_GET['p'] && is_numeric($_GET['p'])) ? $_GET['p'] : 1; +$count = Group::objects()->count(); +$pageNav = new Pagenate($count, $page, PAGE_LIMIT); +$_qstr = $qstr.'&sort='.urlencode($_REQUEST['sort']).'&order='.urlencode($_REQUEST['order']); +$pageNav->setURL('groups.php', $_qstr); +$showing = $pageNav->showing().' '._N('group', 'groups', $count); $qstr.='&order='.($order=='DESC'?'ASC':'DESC'); -$query="$sql GROUP BY grp.group_id ORDER BY $order_by"; -$res=db_query($query); -if($res && ($num=db_num_rows($res))) - $showing=sprintf(__('Showing 1-%1$d of %2$d groups'), $num, $num); -else - $showing=__('No groups found!'); - ?> <div class="pull-left" style="width:700px;padding-top:5px;"> <h2><?php echo __('Agent Groups');?> @@ -67,31 +68,47 @@ else <tbody> <?php $total=0; - $ids=($errors && is_array($_POST['ids']))?$_POST['ids']:null; - if($res && db_num_rows($res)) { - while ($row = db_fetch_array($res)) { + $ids = ($errors && is_array($_POST['ids'])) ? $_POST['ids'] : null; + if ($count) { + $groups= Group::objects() + ->annotate(array( + 'members_count'=>SqlAggregate::COUNT('members', true), + 'depts_count'=>SqlAggregate::COUNT('depts', true), + 'isenabled'=>new SqlExpr(array( + 'flags__hasbit' => Group::FLAG_ENABLED)) + )) + ->order_by(sprintf('%s%s', + strcasecmp($order, 'DESC') ? '' : '-', + $order_column)) + ->limit($pageNav->getLimit()) + ->offset($pageNav->getStart()); + + foreach ($groups as $group) { $sel=false; - if($ids && in_array($row['group_id'],$ids)) + $id = $group->getId(); + if($ids && in_array($id, $ids)) $sel=true; ?> - <tr id="<?php echo $row['group_id']; ?>"> + <tr id="<?php echo $id; ?>"> <td width=7px> - <input type="checkbox" class="ckb" name="ids[]" value="<?php echo $row['group_id']; ?>" - <?php echo $sel?'checked="checked"':''; ?>> </td> - <td><a href="groups.php?id=<?php echo $row['group_id']; ?>"><?php echo $row['group_name']; ?></a> </td> - <td> <?php echo $row['group_enabled']?__('Active'):'<b>'.__('Disabled').'</b>'; ?></td> + <input type="checkbox" class="ckb" name="ids[]" + value="<?php echo $id; ?>" + <?php echo $sel?'checked="checked"':''; ?>> </td> + <td><a href="groups.php?id=<?php echo $id; ?>"><?php echo + $group->getName(); ?></a> </td> + <td> <?php echo $group->isenabled ? __('Active') : '<b>'.__('Disabled').'</b>'; ?></td> <td style="text-align:right;padding-right:30px"> - <?php if($row['users']>0) { ?> - <a href="staff.php?gid=<?php echo $row['group_id']; ?>"><?php echo $row['users']; ?></a> - <?php }else{ ?> 0 + <?php if ($num=$group->members_count) { ?> + <a href="staff.php?gid=<?php echo $id; ?>"><?php echo $num; ?></a> + <?php } else { ?> 0 <?php } ?> </td> <td style="text-align:right;padding-right:30px"> - <?php echo $row['depts']; ?> + <?php echo $group->depts_count; ?> </td> - <td><?php echo Format::date($row['created']); ?> </td> - <td><?php echo Format::datetime($row['updated']); ?> </td> + <td><?php echo Format::date($group->getCreateDate()); ?> </td> + <td><?php echo Format::datetime($group->getUpdateDate()); ?> </td> </tr> <?php } //end of while. @@ -99,7 +116,7 @@ else <tfoot> <tr> <td colspan="7"> - <?php if($res && $num){ ?> + <?php if ($count) { ?> <?php echo __('Select');?>: <a id="selectAll" href="#ckb"><?php echo __('All');?></a> <a id="selectNone" href="#ckb"><?php echo __('None');?></a> @@ -112,7 +129,8 @@ else </tfoot> </table> <?php -if($res && $num): //Show options.. +if ($count): + echo '<div> '.__('Page').':'.$pageNav->getPageLinks().' </div>'; ?> <p class="centered" id="actions"> <input class="button" type="submit" name="enable" value="<?php echo __('Enable');?>" > diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php index 665797a0cc6e8343cfb6949853dae92c68b19c89..1bc7ca1d675f14a7be2c5346d14f173c9a1e3949 100644 --- a/include/staff/staff.inc.php +++ b/include/staff/staff.inc.php @@ -234,7 +234,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <select name="group_id" id="group_id"> <option value="0">— <?php echo __('Select Group');?> —</option> <?php - foreach (Group::getGroupNames() as $id=>$name) { + foreach (Group::getGroups() as $id=>$name) { $sel=($info['group_id']==$id)?'selected="selected"':''; echo sprintf('<option value="%d" %s>%s</option>', $id, $sel, $name); diff --git a/scp/css/scp.css b/scp/css/scp.css index b97e1cc2bcfdc37b4a840095165b790d043311dc..add15fde893acb7e58be9e9a6f639e2492f61424 100644 --- a/scp/css/scp.css +++ b/scp/css/scp.css @@ -489,8 +489,12 @@ table.list tbody tr:hover td, table.list tbody tr.highlight td { background: #F table.list tbody tr:hover td.nohover, table.list tbody tr.highlight td.nohover {} -table.list tfoot td { +table tfoot td { background:#eee; + padding: 1px; +} + +table.list tfoot td { padding: 2px; } @@ -1952,7 +1956,7 @@ tr.disabled th { .tab_content { position: relative; - padding: 10px; + padding: 5px 0; } .left-tabs { margin-left: 48px; diff --git a/scp/groups.php b/scp/groups.php index 8f273e1b11db8bf69320f2f94f4d209f0f9d5af0..494824bb108c2c83b5477ab56ed95d073f772361 100644 --- a/scp/groups.php +++ b/scp/groups.php @@ -22,39 +22,52 @@ if($_REQUEST['id'] && !($group=Group::lookup($_REQUEST['id']))) if($_POST){ switch(strtolower($_POST['do'])){ case 'update': - if(!$group){ + if (!$group) { $errors['err']=sprintf(__('%s: Unknown or invalid'), __('group')); - }elseif($group->update($_POST,$errors)){ + } elseif (!$_POST['isactive'] + && ($thisstaff->getGroupId() == $group->getId())) { + $errors['err'] = sprintf( + __("As an admin, you cannot %s a group you belong to - you might lockout all admins!"), + __('disable')); + } elseif ($group->update($_POST, $errors)) { $msg=sprintf(__('Successfully updated %s'), __('this group')); - }elseif(!$errors['err']){ + } elseif (!$errors['err']) { $errors['err']=sprintf(__('Unable to update %s. Correct error(s) below and try again!'), __('this group')); } break; - case 'create': - $group = Group::create(); - if(($group->update($_POST,$errors))){ + case 'add': + $_group = Group::create(); + if (($_group->update($_POST,$errors))) { $msg=sprintf(__('Successfully added %s'),Format::htmlchars($_POST['name'])); $_REQUEST['a']=null; - }elseif(!$errors['err']){ + } elseif(!$errors['err']) { $errors['err']=sprintf(__('Unable to add %s. Correct error(s) below and try again.'), __('this group')); } break; case 'mass_process': - if(!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) { + $action = strtolower($_POST['a']); + if (!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) { $errors['err'] = sprintf(__('You must select at least %s.'), __('one group')); - } elseif(in_array($thisstaff->getGroupId(), $_POST['ids'])) { - $errors['err'] = __("As an admin, you cannot disable/delete a group you belong to - you might lockout all admins!"); + } elseif(in_array($thisstaff->getGroupId(), $_POST['ids']) + && in_array($action, array('disable', 'delete'))) { + $errors['err'] = sprintf( + __("As an admin, you cannot %s a group you belong to - you might lockout all admins!"), + __('disable or delete')); } else { - $count=count($_POST['ids']); - switch(strtolower($_POST['a'])) { + $count = count($_POST['ids']); + switch($action) { case 'enable': - $sql='UPDATE '.GROUP_TABLE.' SET group_enabled=1, updated=NOW() ' - .' WHERE group_id IN ('.implode(',', db_input($_POST['ids'])).')'; - - if(db_query($sql) && ($num=db_affected_rows())){ + $num = Group::objects()->filter(array( + 'id__in' => $_POST['ids'] + ))->update(array( + 'flags'=> SqlExpression::bitor( + new SqlField('flags'), + Group::FLAG_ENABLED) + )); + if ($num) { if($num==$count) $msg = sprintf(__('Successfully activated %s'), _N('selected group', 'selected groups', $count)); @@ -67,9 +80,15 @@ if($_POST){ } break; case 'disable': - $sql='UPDATE '.GROUP_TABLE.' SET group_enabled=0, updated=NOW() ' - .' WHERE group_id IN ('.implode(',', db_input($_POST['ids'])).')'; - if(db_query($sql) && ($num=db_affected_rows())) { + $num = Group::objects()->filter(array( + 'id__in' => $_POST['ids'] + ))->update(array( + 'flags'=> SqlExpression::bitand( + new SqlField('flags'), + (~Group::FLAG_ENABLED)) + )); + + if ($num) { if($num==$count) $msg = sprintf(__('Successfully disabled %s'), _N('selected group', 'selected groups', $count)); diff --git a/setup/inc/streams/core/install-mysql.sql b/setup/inc/streams/core/install-mysql.sql index 900a1f47f9c399f633ca18e4ef24b68c74130aa2..e35b6a364b6e6de4ee4af0ff4ed01eda630f50ee 100644 --- a/setup/inc/streams/core/install-mysql.sql +++ b/setup/inc/streams/core/install-mysql.sql @@ -388,27 +388,17 @@ CREATE TABLE `%TABLE_PREFIX%file_chunk` ( PRIMARY KEY (`file_id`, `chunk_id`) ) DEFAULT CHARSET=utf8; -DROP TABLE IF EXISTS `%TABLE_PREFIX%groups`; -CREATE TABLE `%TABLE_PREFIX%groups` ( - `group_id` int(10) unsigned NOT NULL auto_increment, - `group_enabled` tinyint(1) unsigned NOT NULL default '1', - `group_name` varchar(50) NOT NULL default '', - `can_create_tickets` tinyint(1) unsigned NOT NULL default '1', - `can_edit_tickets` tinyint(1) unsigned NOT NULL default '1', - `can_post_ticket_reply` tinyint( 1 ) unsigned NOT NULL DEFAULT '1', - `can_delete_tickets` tinyint(1) unsigned NOT NULL default '0', - `can_close_tickets` tinyint(1) unsigned NOT NULL default '1', - `can_assign_tickets` tinyint(1) unsigned NOT NULL default '1', - `can_transfer_tickets` tinyint(1) unsigned NOT NULL default '1', - `can_ban_emails` tinyint(1) unsigned NOT NULL default '0', - `can_manage_premade` tinyint(1) unsigned NOT NULL default '0', - `can_manage_faq` tinyint(1) unsigned NOT NULL default '0', - `can_view_staff_stats` tinyint( 1 ) unsigned NOT NULL DEFAULT '0', +DROP TABLE IF EXISTS `%TABLE_PREFIX%group`; +CREATE TABLE `%TABLE_PREFIX%group` ( + `id` int(10) unsigned NOT NULL auto_increment, + `role_id` int(11) unsigned NOT NULL, + `flags` int(11) unsigned NOT NULL default '1', + `name` varchar(120) NOT NULL default '', `notes` text, `created` datetime NOT NULL, `updated` datetime NOT NULL, - PRIMARY KEY (`group_id`), - KEY `group_active` (`group_enabled`) + PRIMARY KEY (`id`), + KEY `role_id` (`role_id`) ) DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `%TABLE_PREFIX%role`; @@ -427,8 +417,10 @@ DROP TABLE IF EXISTS `%TABLE_PREFIX%group_dept_access`; CREATE TABLE `%TABLE_PREFIX%group_dept_access` ( `group_id` int(10) unsigned NOT NULL default '0', `dept_id` int(10) unsigned NOT NULL default '0', + `role_id` int(10) unsigned NOT NULL default '0', UNIQUE KEY `group_dept` (`group_id`,`dept_id`), - KEY `dept_id` (`dept_id`) + KEY `dept_id` (`dept_id`), + KEY `role_id` (`role_id`) ) DEFAULT CHARSET=utf8; DROP TABLE IF EXISTS `%TABLE_PREFIX%help_topic`;