diff --git a/include/ajax.staff.php b/include/ajax.staff.php index 871fe9db7fd6846fbdc3c0f5748930adda85ae40..37c71462caa02ec72b20528ec8b71df8f8c0056e 100644 --- a/include/ajax.staff.php +++ b/include/ajax.staff.php @@ -58,4 +58,90 @@ class StaffAjaxAPI extends AjaxController { include STAFFINC_DIR . 'templates/set-password.tmpl.php'; } + + function getAgentPerms($id) { + global $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Agent login required'); + if (!$thisstaff->isAdmin()) + Http::response(403, 'Access denied'); + if (!($staff = Staff::lookup($id))) + Http::response(404, 'No such agent'); + + return $this->encode($staff->getPermissionInfo()); + } + + function resetPermissions() { + global $ost, $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Agent login required'); + if (!$thisstaff->isAdmin()) + Http::response(403, 'Access denied'); + + $form = new ResetAgentPermissionsForm($_POST); + + if (@is_array($_GET['ids'])) { + $perms = new RolePermission(); + $selected = Staff::objects()->filter(array('staff_id__in' => $_GET['ids'])); + foreach ($selected as $staff) + // XXX: This maybe should be intersection rather than union + $perms->merge($staff->getPermission()); + $form->getField('perms')->setValue($perms->getInfo()); + } + + if ($_POST && $form->isValid()) { + $clean = $form->getClean(); + Http::response(201, $this->encode(array('perms' => $clean['perms']))); + } + + $title = __("Reset Agent Permissions"); + $verb = __("Continue"); + $path = ltrim($ost->get_path_info(), '/'); + + include STAFFINC_DIR . 'templates/reset-agent-permissions.tmpl.php'; + } + + function changeDepartment() { + global $ost, $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Agent login required'); + if (!$thisstaff->isAdmin()) + Http::response(403, 'Access denied'); + + $form = new ChangeDepartmentForm($_POST); + + // Preselect reasonable dept and role based on the current settings + // of the received staff ids + if (@is_array($_GET['ids'])) { + $dept_id = null; + $role_id = null; + $selected = Staff::objects()->filter(array('staff_id__in' => $_GET['ids'])); + foreach ($selected as $staff) { + if (!isset($dept_id)) { + $dept_id = $staff->dept_id; + $role_id = $staff->role_id; + } + elseif ($dept_id != $staff->dept_id) + $dept_id = 0; + elseif ($role_id != $staff->role_id) + $role_id = 0; + } + $form->getField('dept_id')->setValue($dept_id); + $form->getField('role_id')->setValue($role_id); + } + + if ($_POST && $form->isValid()) { + $clean = $form->getClean(); + Http::response(201, $this->encode($clean)); + } + + $title = __("Change Primary Department"); + $verb = __("Continue"); + $path = ltrim($ost->get_path_info(), '/'); + + include STAFFINC_DIR . 'templates/quick-add.tmpl.php'; + } } diff --git a/include/class.dept.php b/include/class.dept.php index 6bb8625a27ff7dd2fd7ef8f8ae3611f480b23fd9..d27e5923c62914880e794168e348d31aac38cafc 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -632,10 +632,9 @@ extends Form { 'pid' => new ChoiceField(array( 'label' => '', 'default' => 0, - 'choices' => array_merge( - array(0 => __('Top-Level Department')), - Dept::getDepartments() - ) + 'choices' => + array(0 => '— '.__('Top-Level Department').' —') + + Dept::getDepartments() )), 'name' => new TextboxField(array( 'required' => true, @@ -649,10 +648,9 @@ extends Form { 'email_id' => new ChoiceField(array( 'label' => __('Email Mailbox'), 'default' => 0, - 'choices' => array_merge( - array(0 => '— '.__('System Default').' —'), - Email::getAddresses() - ), + 'choices' => + array(0 => '— '.__('System Default').' —') + + Email::getAddresses(), 'configuration' => array( 'classes' => 'span12', ), diff --git a/include/class.format.php b/include/class.format.php index 85b1fd9aeefccd11387d4d93f3c26999de6b20ba..54b9ae8f55d259331d04ff3935ff2a5de441fc41 100644 --- a/include/class.format.php +++ b/include/class.format.php @@ -777,7 +777,9 @@ class Format { } function relativeTime($to, $from=false, $granularity=1) { - $timestamp = $to ?: Misc::gmtime(); + if (!$to) + return false; + $timestamp = $to; if (gettype($timestamp) === 'string') $timestamp = strtotime($timestamp); $from = $from ?: Misc::gmtime(); diff --git a/include/class.forms.php b/include/class.forms.php index 05df629165b05f9576e32b235b428b7d0ec9300b..5cbdcae5b7de73f80ecf70f6253bf4feb8ff0bdb 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -828,6 +828,11 @@ class FormField { function getAnswer() { return $this->answer; } function setAnswer($ans) { $this->answer = $ans; } + function setValue($value) { + $this->reset(); + $this->getWidget()->value = $value; + } + function getFormName() { if (is_numeric($this->get('id'))) return substr(md5( @@ -3038,6 +3043,8 @@ class BoxChoicesWidget extends Widget { } function emitChoices($choices) { + static $uid = 1; + if (!isset($this->value)) $this->value = $this->field->get('default'); $config = $this->field->getConfiguration(); @@ -3045,14 +3052,13 @@ class BoxChoicesWidget extends Widget { if (isset($config['classes'])) $classes = 'class="'.$config['classes'].'"'; - $i=0; foreach ($choices as $k => $v) { if (is_array($v)) { $this->renderSectionBreak($k); $this->emitChoices($v); continue; } - $id = sprintf("%s-%s", $this->id, $i++); + $id = sprintf("%s-%s", $this->id, $uid++); ?> <label <?php echo $classes; ?> for="<?php echo $id; ?>" style="display:block;"> @@ -3487,7 +3493,8 @@ class FreeTextField extends FormField { class FreeTextWidget extends Widget { function render($options=array()) { $config = $this->field->getConfiguration(); - ?><div class="thread-body" style="padding:0"><?php + $class = $config['classes'] ?: 'thread-body' + ?><div class="<?php echo $class; ?>" style="padding:0"><?php if ($label = $this->field->getLocal('label')) { ?> <h3><?php echo Format::htmlchars($label); diff --git a/include/class.nav.php b/include/class.nav.php index 94f7a7ca44dad7fdec96723d9ee6b29ee9751545..8acff9052bc7d9da1436c2c6e067f50ed802d812 100644 --- a/include/class.nav.php +++ b/include/class.nav.php @@ -154,7 +154,7 @@ class StaffNav { 'iconclass'=>'assignedTickets', 'droponly'=>true); - if ($staff->hasPerm(TicketModel::PERM_CREATE)) + if ($staff->hasPerm(TicketModel::PERM_CREATE, false)) $subnav[]=array('desc'=>__('New Ticket'), 'title' => __('Open a New Ticket'), 'href'=>'tickets.php?a=open', diff --git a/include/class.role.php b/include/class.role.php index 6e9c42a01870f832f4390c9b67b0dbd5e036a3fd..64fdbe07d2c74aebb608e4fdb30e8bcaaeaf9d74 100644 --- a/include/class.role.php +++ b/include/class.role.php @@ -306,6 +306,19 @@ class RolePermission { return $this->perms; } + function merge($perms) { + if ($perms instanceof self) + $perms = $perms->getInfo(); + foreach ($perms as $perm=>$value) { + if (is_numeric($perm)) { + // Array of perm names + $perm = $value; + $value = true; + } + $this->set($perm, $value); + } + } + static function allPermissions() { return static::$_permissions; } @@ -345,10 +358,9 @@ extends AbstractForm { )), 'clone' => new ChoiceField(array( 'default' => 0, - 'choices' => array_merge( - array(0 => '— '.__('Clone an existing role').' —'), - Role::getRoles() - ), + 'choices' => + array(0 => '— '.__('Clone an existing role').' —') + + Role::getRoles(), 'configuration' => array( 'classes' => 'span12', ), diff --git a/include/class.staff.php b/include/class.staff.php index bf3e59a3f711ec743d197ce489f52bea0e8d18f7..4b194946f1ff0d8b2aba8888cdd822bc4ec32e1e 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -367,6 +367,27 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { return $this->dept; } + function setDepartmentId($dept_id, $eavesdrop=false) { + // Grant access to the current department + $old = $this->dept_id; + if ($eavesdrop) { + $da = StaffDeptAccess::create(array( + 'dept_id' => $old, + 'role_id' => $this->role_id, + )); + $da->setAlerts(true); + $this->dept_access->add($da); + } + + // Drop extended access to new department + $this->dept_id = $dept_id; + if ($da = $this->dept_access->findFirst(array( + 'dept_id' => $dept_id)) + ) { + $this->dept_access->remove($da); + } + } + function getLanguage() { return (isset($this->lang)) ? $this->lang : false; } @@ -395,8 +416,15 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { return $this->role; } - function hasPerm($perm) { - return $this->getPermission()->has($perm); + function hasPerm($perm, $global=true) { + if ($global) + return $this->getPermission()->has($perm); + if ($this->getRole()->hasPerm($perm)) + return true; + foreach ($this->dept_access as $da) + if ($da->role->hasPerm($perm)) + return true; + return false; } function canManageTickets() { @@ -915,7 +943,7 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { } // Update some things for ::updateAccess to inspect - $this->dept_id = $vars['dept_id']; + $this->setDepartmentId($vars['dept_id']); // Format access update as [array(dept_id, role_id, alerts?)] $access = array(); @@ -1020,17 +1048,19 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { return !$errors; } - private function updatePerms($vars, &$errors) { + function updatePerms($vars, &$errors) { if (!$vars) { $this->permissions = ''; return; } + $permissions = $this->getPermission(); foreach (RolePermission::allPermissions() as $g => $perms) { foreach ($perms as $k => $v) { $permissions->set($k, in_array($k, $vars) ? 1 : 0); } } $this->permissions = $permissions->toJson(); + return true; } } @@ -1133,3 +1163,100 @@ extends AbstractForm { return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php')); } } + +class ResetAgentPermissionsForm +extends AbstractForm { + function buildFields() { + $permissions = array(); + foreach (RolePermission::allPermissions() as $g => $perms) { + foreach ($perms as $k => $v) { + if (!$v['primary']) + continue; + $permissions[$g][$k] = "{$v['title']} — {$v['desc']}"; + } + } + return array( + 'clone' => new ChoiceField(array( + 'default' => 0, + 'choices' => + array(0 => '— '.__('Clone an existing agent').' —'), + + Staff::getStaffMembers(), + 'configuration' => array( + 'classes' => 'span12', + ), + )), + 'perms' => new ChoiceField(array( + 'choices' => $permissions, + 'widget' => 'TabbedBoxChoicesWidget', + 'configuration' => array( + 'multiple' => true, + 'classes' => 'vertical-pad', + ), + )), + ); + } + + function getClean() { + $clean = parent::getClean(); + // Index permissions as ['ticket.edit' => 1] + $clean['perms'] = array_keys($clean['perms']); + return $clean; + } + + function render($staff=true) { + return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php')); + } +} + +class ChangeDepartmentForm +extends AbstractForm { + function buildFields() { + return array( + 'header' => new FreeTextField(array( + 'configuration' => array( + 'content' => __('Change the primary department and primary role of the selected agents'), + 'classes' => ' ', + ) + )), + 'dept_id' => new ChoiceField(array( + 'default' => 0, + 'required' => true, + 'label' => __('Primary Department'), + 'choices' => + array(0 => '— '.__('Primary Department').' —') + + Dept::getDepartments(), + 'configuration' => array( + 'classes' => 'span12', + ), + )), + 'role_id' => new ChoiceField(array( + 'default' => 0, + 'required' => true, + 'label' => __('Primary Role'), + 'choices' => + array(0 => '— '.__('Corresponding Role').' —') + + Role::getRoles(), + 'configuration' => array( + 'classes' => 'span12', + ), + )), + 'eavesdrop' => new BooleanField(array( + 'configuration' => array( + 'desc' => __('Maintain access to current primary department'), + 'classes' => 'form footer', + ), + )), + // alerts? + ); + } + + function getClean() { + $clean = parent::getClean(); + $clean['eavesdrop'] = $clean['eavesdrop'] ? 1 : 0; + return $clean; + } + + function render($staff=true) { + return parent::render($staff, false, array('template' => 'dynamic-form-simple.tmpl.php')); + } +} diff --git a/include/class.team.php b/include/class.team.php index fe80bd4f997f12222b1b76b81b717186f9b0e54a..c7a66058dd0d5b5ce31196fd09e7b49a025ea4bd 100644 --- a/include/class.team.php +++ b/include/class.team.php @@ -365,10 +365,9 @@ extends AbstractForm { 'lead_id' => new ChoiceField(array( 'label' => __('Optionally select a leader for the team'), 'default' => 0, - 'choices' => array_merge( + 'choices' => array(0 => '— '.__('None').' —'), - Staff::getStaffMembers() - ), + + Staff::getStaffMembers(), 'configuration' => array( 'classes' => 'span12', ), diff --git a/include/i18n/en_US/role.yaml b/include/i18n/en_US/role.yaml index 3be09a6392a5c3f8e92d880c18048812b8c77a0f..ca76b2650513d4ffcf0d5bb48fa57cb07b203757 100644 --- a/include/i18n/en_US/role.yaml +++ b/include/i18n/en_US/role.yaml @@ -32,18 +32,6 @@ task.close, task.delete, canned.manage, - faq.manage, - stats.agents, - emails.banlist, - user.create, - user.edit, - user.delete, - user.manage, - user.dir, - org.create, - org.edit, - org.delete, - search.all, thread.edit] - id: 2 @@ -65,18 +53,7 @@ task.transfer, task.reply, task.close, - canned.manage, - faq.manage, - stats.agents, - emails.banlist, - user.create, - user.edit, - user.delete, - user.manage, - user.dir, - org.create, - org.edit, - org.delete] + canned.manage] - id: 3 flags: 1 @@ -92,9 +69,10 @@ task.create, task.assign, task.transfer, - task.reply, - user.edit, - user.manage, - user.dir, - org.create, - org.edit] + task.reply] + +- id: 4 + flags: 1 + name: View only + notes: Simple role with no permissions + permissions: [] diff --git a/include/staff/staffmembers.inc.php b/include/staff/staffmembers.inc.php index b83c532c06104f4e1560ff0a88c1e32f6b61fd70..c1f12f9ce409a5560dd29c96803eaafad09b4241 100644 --- a/include/staff/staffmembers.inc.php +++ b/include/staff/staffmembers.inc.php @@ -107,13 +107,47 @@ $agents->limit($pageNav->getLimit())->offset($pageNav->getStart()); } ?> </select> - - <input type="submit" name="submit" value="<?php echo __('Apply');?>"/> + <input type="submit" name="submit" class="small" value="<?php echo __('Apply');?>"/> </form> </div> -<div class="pull-right flush-right" style="padding-right:5px;"><b><a href="staff.php?a=add" class="Icon newstaff"><?php echo __('Add New Agent');?></a></b></div> -<div class="clear"></div> -<form action="staff.php" method="POST" name="staff" > + + <form id="mass-actions" action="staff.php" method="POST" name="staff" > + + <div class="pull-right"> + <a class="action-button" href="staff.php?a=add"> + <i class="icon-plus-sign"></i> + <?php echo __('Add New Agent'); ?> + </a> + <span class="action-button" data-dropdown="#action-dropdown-more"> + <i class="icon-caret-down pull-right"></i> + <span ><i class="icon-cog"></i> <?php echo __('More');?></span> + </span> + <div id="action-dropdown-more" class="action-dropdown anchor-right"> + <ul id="actions"> + <li><a class="confirm" data-name="enable" href="staff.php?a=enable"> + <i class="icon-trash icon-fixed-width"></i> + <?php echo __('Enable'); ?></a></li> + <li><a class="confirm" data-name="disable" href="staff.php?a=disable"> + <i class="icon-trash icon-fixed-width"></i> + <?php echo __('Disable'); ?></a></li> + <li><a class="confirm" data-name="delete" href="staff.php?a=delete"> + <i class="icon-trash icon-fixed-width"></i> + <?php echo __('Delete'); ?></a></li> + <li><a class="dialog-first" data-action="permissions" href="#staff/reset-permissions"> + <i class="icon-trash icon-fixed-width"></i> + <?php echo __('Reset Permissions'); ?></a></li> + <li><a class="dialog-first" data-action="department" href="#staff/change-department"> + <i class="icon-trash icon-fixed-width"></i> + <?php echo __('Change Department'); ?></a></li> + <li><a class="dialog-first" href="#staff/reset-access"> + <i class="icon-trash icon-fixed-width"></i> + <?php echo __('Reset Access'); ?></a></li> + </ul> + </div> +</div> + +<div class="clear" style="padding: 3px 0"></div> + <?php csrf_token(); ?> <input type="hidden" name="do" value="mass_process" > <input type="hidden" id="action" name="a" value="" > @@ -145,16 +179,16 @@ $agents->limit($pageNav->getLimit())->offset($pageNav->getStart()); <input type="checkbox" class="ckb" name="ids[]" value="<?php echo $id; ?>" <?php echo $sel ? 'checked="checked"' : ''; ?> > <td><a href="staff.php?id=<?php echo $id; ?>"><?php echo - Format::htmlchars((string) $agent->getName()); ?></a> </td> + Format::htmlchars((string) $agent->getName()); ?></a></td> <td><?php echo $agent->getUserName(); ?></td> - <td><?php echo $agent->isActive() ? __('Active') :'<b>'.__('Locked').'</b>'; ?> <?php + <td><?php echo $agent->isActive() ? __('Active') :'<b>'.__('Locked').'</b>'; ?><?php echo $agent->onvacation ? '<small>(<i>'.__('vacation').'</i>)</small>' : ''; ?></td> <td><a href="departments.php?id=<?php echo $agent->getDeptId(); ?>"><?php echo Format::htmlchars((string) $agent->dept); ?></a></td> <td><?php echo Format::date($agent->created); ?></td> - <td><?php echo Format::datetime($agent->lastlogin); ?> </td> + <td><?php echo Format::relativeTime(Misc::db2gmtime($agent->lastlogin)) ?: '<em class="faded">'.__('never').'</em>'; ?></td> </tr> <?php } //end of foreach @@ -175,18 +209,9 @@ $agents->limit($pageNav->getLimit())->offset($pageNav->getStart()); </tfoot> </table> <?php -if ($count): //Show options.. +if ($count) { //Show options.. echo '<div> '.__('Page').':'.$pageNav->getPageLinks().' </div>'; -?> -<p class="centered" id="actions"> - <input class="button" type="submit" name="enable" value="<?php echo __('Enable');?>" > - - <input class="button" type="submit" name="disable" value="<?php echo __('Lock');?>" > - - <input class="button" type="submit" name="delete" value="<?php echo __('Delete');?>"> -</p> -<?php -endif; +} ?> </form> @@ -220,3 +245,34 @@ endif; </p> <div class="clear"></div> </div> + +<script type="text/javascript"> +$(document).on('click', 'a.dialog-first', function(e) { + e.preventDefault(); + var action = $(this).data('action'), + $form = $('form#mass-actions'); + if ($(':checkbox.ckb:checked', $form).length == 0) { + $.sysAlert(__('Oops'), + __('You need to select at least one item')); + return false; + } + ids = $form.find('.ckb'); + $.dialog('ajax.php/' + $(this).attr('href').substr(1), 201, function (xhr, data) { + $form.find('#action').val(action); + data = JSON.parse(data); + if (data) + $.each(data, function(k, v) { + if (v.length) { + $.each(v, function() { + $form.append($('<input type="hidden">').attr('name', k+'[]').val(this)); + }) + } + else { + $form.append($('<input type="hidden">').attr('name', k).val(v)); + } + }); + $form.submit(); + }, { data: ids.serialize()}); + return false; +}); +</script> diff --git a/include/staff/templates/reset-agent-permissions.tmpl.php b/include/staff/templates/reset-agent-permissions.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..b69dbd72309ab78def3c70f1c7a308874c02d4a4 --- /dev/null +++ b/include/staff/templates/reset-agent-permissions.tmpl.php @@ -0,0 +1,22 @@ +<?php +include 'quick-add.tmpl.php'; +$clone = $form->getField('clone')->getWidget()->name; +$permissions = $form->getField('perms')->getWidget()->name; +?> +<script type="text/javascript"> + $('#_<?php echo $clone; ?>').change(function() { + var $this = $(this), + id = $this.val(), + form = $this.closest('form'); + $.ajax({ + url: 'ajax.php/staff/'+id+'/perms', + dataType: 'json', + success: function(json) { + $('[name="<?php echo $permissions; ?>[]"]', form).prop('checked', false); + $.each(json, function(k, v) { + form.find('[value="'+k+'"]', form).prop('checked', !!v); + }); + } + }); + }); +</script> diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php index 65d4e37a089a479817311d01380e34a495678a64..6e2f9bae14106e8077ff70b189ea9f3bacdb7472 100644 --- a/include/staff/ticket-open.inc.php +++ b/include/staff/ticket-open.inc.php @@ -1,6 +1,6 @@ <?php if (!defined('OSTSCPINC') || !$thisstaff - || !$thisstaff->hasPerm(TicketModel::PERM_CREATE)) + || !$thisstaff->hasPerm(TicketModel::PERM_CREATE, false)) die('Access Denied'); $info=array(); diff --git a/scp/ajax.php b/scp/ajax.php index 72e68d429ae8cd633761be9e484fd4f1f84fc9e0..bc5207be392f96fbb062204e98c52b8bdf40639d 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -233,8 +233,11 @@ $dispatcher = patterns('', )), url_get('^/role/(?P<id>\d+)/perms', 'getRolePerms') )), - url('^/staff/(?P<id>\d+)', patterns('ajax.staff.php:StaffAjaxAPI', - url('^/set-password$', 'setPassword') + url('^/staff', patterns('ajax.staff.php:StaffAjaxAPI', + url('^/(?P<id>\d+)/set-password$', 'setPassword'), + url_get('^/(?P<id>\d+)/perms', 'getAgentPerms'), + url('^/reset-permissions', 'resetPermissions'), + url('^/change-department', 'changeDepartment') )) ); diff --git a/scp/faq.php b/scp/faq.php index bac34c7ceefe4b8cd1c30bd396c93cab2745bc02..7881dbc18edb42484653846f04a18ad9df66ea60 100644 --- a/scp/faq.php +++ b/scp/faq.php @@ -140,17 +140,16 @@ else { } } -$role = $thisstaff->getRole(); $inc='faq-categories.inc.php'; //FAQs landing page. if($faq) { $inc='faq-view.inc.php'; if ($_REQUEST['a']=='edit' - && $role->hasPerm(FAQ::PERM_MANAGE)) + && $thisstaff->hasPerm(FAQ::PERM_MANAGE)) $inc='faq.inc.php'; elseif ($_REQUEST['a'] == 'print') return $faq->printPdf(); }elseif($_REQUEST['a']=='add' - && $role->hasPerm(FAQ::PERM_MANAGE)) { + && $thisstaff->hasPerm(FAQ::PERM_MANAGE)) { $inc='faq.inc.php'; } elseif($category && $_REQUEST['a']!='search') { $inc='faq-category.inc.php'; diff --git a/scp/js/scp.js b/scp/js/scp.js index 7cf9c4254fb11d4ad5081e378792b241ceddd978..608555ef86998caf916d3d1c5282247cb8207921 100644 --- a/scp/js/scp.js +++ b/scp/js/scp.js @@ -103,11 +103,11 @@ var scp_prep = function() { }); $.toggleOverlay(true); $('.dialog#confirm-action .confirm-action').hide(); - $('.dialog#confirm-action p#'+this.name+'-confirm') + $('.dialog#confirm-action p#'+name+'-confirm') .show() .parent('div').show().trigger('click'); } - + e.preventDefault(); return false; }); @@ -596,7 +596,7 @@ $.dialog = function (url, codes, cb, options) { $('div#popup-loading', $popup).show() .find('h1').css({'margin-top':function() { return $popup.height()/3-$(this).height()/3}}); $popup.resize().show(); - $('div.body', $popup).load(url, function () { + $('div.body', $popup).load(url, options.data, function () { $('div#popup-loading', $popup).hide(); $('div.body', $popup).slideDown({ duration: 300, diff --git a/scp/staff.php b/scp/staff.php index 17a106e93c41cbe16da59755ffb0b7fdefd9563b..a0426ea28ca43188ed3612126de46f85eb4b1769 100644 --- a/scp/staff.php +++ b/scp/staff.php @@ -46,18 +46,18 @@ if($_POST){ if(!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) { $errors['err'] = sprintf(__('You must select at least %s.'), __('one agent')); - } elseif(in_array($thisstaff->getId(),$_POST['ids'])) { + } elseif(in_array($_POST['a'], array('disable', 'delete')) + && in_array($thisstaff->getId(),$_POST['ids']) + ) { $errors['err'] = __('You can not disable/delete yourself - you could be the only admin!'); } else { - $count=count($_POST['ids']); + $count = count($_POST['ids']); + $members = Staff::objects()->filter(array( + 'staff_id__in' => $_POST['ids'] + )); switch(strtolower($_POST['a'])) { case 'enable': - $num = Staff::objects()->filter(array( - 'staff_id__in' => $_POST['ids'] - ))->update(array( - 'isactive' => 1 - )); - + $num = $members->update(array('isactive' => 1)); if ($num) { if($num==$count) $msg = sprintf('Successfully activated %s', @@ -70,13 +70,9 @@ if($_POST){ _N('selected agent', 'selected agents', $count)); } break; - case 'disable': - $num = Staff::objects()->filter(array( - 'staff_id__in' => $_POST['ids'] - ))->update(array( - 'isactive' => 0 - )); + case 'disable': + $num = $members->update(array('isactive' => 0)); if ($num) { if($num==$count) $msg = sprintf('Successfully disabled %s', @@ -89,10 +85,11 @@ if($_POST){ _N('selected agent', 'selected agents', $count)); } break; + case 'delete': $i = 0; - foreach($_POST['ids'] as $k=>$v) { - if($v!=$thisstaff->getId() && ($s=Staff::lookup($v)) && $s->delete()) + foreach($members as $s) { + if ($s->staff_id != $thisstaff->getId() && $s->delete()) $i++; } @@ -106,6 +103,48 @@ if($_POST){ $errors['err'] = sprintf(__('Unable to delete %s'), _N('selected agent', 'selected agents', $count)); break; + + case 'permissions': + foreach ($members as $s) + if ($s->updatePerms($_POST['perms'], $errors) && $s->save()) + $i++; + + if($i && $i==$count) + $msg = sprintf(__('Successfully updated %s'), + _N('selected agent', 'selected agents', $count)); + elseif($i>0) + $warn = sprintf(__('%1$d of %2$d %3$s updated'), $i, $count, + _N('selected agent', 'selected agents', $count)); + elseif(!$errors['err']) + $errors['err'] = sprintf(__('Unable to update %s'), + _N('selected agent', 'selected agents', $count)); + break; + + case 'department': + if (!$_POST['dept_id'] || !$_POST['role_id'] + || !Dept::lookup($_POST['dept_id']) + || !Role::lookup($_POST['role_id']) + ) { + $errors['err'] = 'Internal error.'; + break; + } + foreach ($members as $s) { + $s->setDepartmentId((int) $_POST['dept_id'], $_POST['eavesdrop']); + $s->role_id = (int) $_POST['role_id']; + if ($s->save() && $s->dept_access->saveAll()) + $i++; + } + if($i && $i==$count) + $msg = sprintf(__('Successfully updated %s'), + _N('selected agent', 'selected agents', $count)); + elseif($i>0) + $warn = sprintf(__('%1$d of %2$d %3$s updated'), $i, $count, + _N('selected agent', 'selected agents', $count)); + elseif(!$errors['err']) + $errors['err'] = sprintf(__('Unable to update %s'), + _N('selected agent', 'selected agents', $count)); + break; + default: $errors['err'] = __('Unknown action - get technical help.'); } diff --git a/scp/tickets.php b/scp/tickets.php index 8e1d45185b6eace1655b12fe900be0a825cd95ad..7027667a12d6204df6d6ba69f33fb75e2805351d 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -364,7 +364,7 @@ if($_POST && !$errors): case 'open': $ticket=null; if (!$thisstaff || - !$thisstaff->hasPerm(TicketModel::PERM_CREATE)) { + !$thisstaff->hasPerm(TicketModel::PERM_CREATE, false)) { $errors['err'] = sprintf('%s %s', sprintf(__('You do not have permission %s.'), __('to create tickets')), @@ -483,7 +483,7 @@ if (isset($_SESSION['advsearch'])) { (!$_REQUEST['status'] || $_REQUEST['status']=='search')); } -if ($thisstaff->hasPerm(TicketModel::PERM_CREATE)) { +if ($thisstaff->hasPerm(TicketModel::PERM_CREATE, false)) { $nav->addSubMenu(array('desc'=>__('New Ticket'), 'title'=> __('Open a New Ticket'), 'href'=>'tickets.php?a=open', @@ -513,7 +513,7 @@ if($ticket) { } else { $inc = 'tickets.inc.php'; if ($_REQUEST['a']=='open' && - $thisstaff->hasPerm(TicketModel::PERM_CREATE)) + $thisstaff->hasPerm(TicketModel::PERM_CREATE, false)) $inc = 'ticket-open.inc.php'; elseif($_REQUEST['a'] == 'export') { $ts = strftime('%Y%m%d');