From 3944b51d59eb1259bc0ac7ae5b243f0c1b283f2f Mon Sep 17 00:00:00 2001 From: aydreeihn <adriane@enhancesoft.com> Date: Mon, 5 Jun 2017 17:01:17 -0500 Subject: [PATCH] functionality to archive help topics and departments --- include/class.dept.php | 89 +++++++-- include/class.email.php | 8 + include/class.filter.php | 18 +- include/class.filter_action.php | 42 ++-- include/class.forms.php | 48 ++++- include/class.staff.php | 4 + include/class.ticket.php | 7 +- include/class.topic.php | 220 ++++++++++++--------- include/client/view.inc.php | 3 +- include/staff/cannedresponse.inc.php | 2 +- include/staff/department.inc.php | 39 +++- include/staff/departments.inc.php | 54 +++++- include/staff/email.inc.php | 23 ++- include/staff/filter.inc.php | 22 ++- include/staff/helptopic.inc.php | 28 ++- include/staff/helptopics.inc.php | 18 +- include/staff/staff.inc.php | 18 +- include/staff/ticket-edit.inc.php | 10 +- include/staff/ticket-open.inc.php | 2 +- scp/departments.php | 280 +++++++++++++++++---------- scp/filters.php | 16 ++ scp/helptopics.php | 59 +++++- scp/staff.php | 4 + setup/inc/install-prereq.inc.php | 2 +- 24 files changed, 745 insertions(+), 271 deletions(-) diff --git a/include/class.dept.php b/include/class.dept.php index 8f09237c4..99c79ec24 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -61,11 +61,14 @@ implements TemplateVariable { var $autorespEmail; const ALERTS_DISABLED = 2; + const DISPLAY_DISABLED = 2; const ALERTS_DEPT_AND_EXTENDED = 1; const ALERTS_DEPT_ONLY = 0; const FLAG_ASSIGN_MEMBERS_ONLY = 0x0001; const FLAG_DISABLE_AUTO_CLAIM = 0x0002; + const FLAG_ACTIVE = 0x0004; + const FLAG_ARCHIVED = 0x0008; function asVar() { return $this->getName(); @@ -128,6 +131,24 @@ implements TemplateVariable { return self::getNameById($this->getId()); } + function getStatus() { + if($this->flags & self::FLAG_ACTIVE) + return __('Active'); + elseif($this->flags & self::FLAG_ARCHIVED) + return __('Archived'); + else + return __('Disabled'); + } + + function allowsReopen() { + return !($this->flags & self::FLAG_ARCHIVED); + } + + function isActive() + { + return !!($this->flags & self::FLAG_ACTIVE); + } + function getEmailId() { return $this->email_id; } @@ -361,6 +382,7 @@ implements TemplateVariable { $ht['assign_members_only'] = $this->assignMembersOnly(); $ht['disable_auto_claim'] = $this->disableAutoClaim(); + $ht['status'] = $this->getStatus(); return $ht; } @@ -465,7 +487,7 @@ implements TemplateVariable { * */ - private function setFlag($flag, $val) { + public function setFlag($flag, $val) { if ($val) $this->flags |= $flag; @@ -486,7 +508,7 @@ implements TemplateVariable { } function getNameById($id) { - $names = static::getDepartments(); + $names = Dept::getDepartments(); return $names[$id]; } @@ -500,8 +522,8 @@ implements TemplateVariable { : null; } - static function getDepartments( $criteria=null, $localize=true) { - static $depts = null; + static function getDepartments($criteria=null, $localize=true, $disabled=true) { + $depts = null; if (!isset($depts) || $criteria) { // XXX: This will upset the static $depts array @@ -509,7 +531,7 @@ implements TemplateVariable { $query = self::objects(); if (isset($criteria['publiconly'])) $query->filter(array( - 'ispublic' => ($criteria['publiconly'] ? 1 : 0))); + 'flags__hasbit' => Dept::FLAG_ACTIVE)); if ($manager=$criteria['manager']) $query->filter(array( @@ -524,10 +546,15 @@ implements TemplateVariable { } $query->order_by('name') - ->values('id', 'pid', 'name', 'parent'); + ->values('id', 'pid', 'flags', 'name', 'parent'); foreach ($query as $row) - $depts[$row['id']] = $row; + { + $display = ($row['flags'] & self::FLAG_ACTIVE); + + $depts[$row['id']] = array('id' => $row['id'], 'pid'=>$row['pid'], 'name'=>$row['name'], + 'parent'=>$row['parent'], 'disabled' => !$display); + } $localize_this = function($id, $default) use ($localize) { if (!$localize) @@ -554,21 +581,32 @@ implements TemplateVariable { // Fetch local names $names[$id] = $localize_this($id, $name); } - asort($names); - // TODO: Use locale-aware sorting mechanism + // Apply requested filters + $requested_names = array(); + foreach ($names as $id=>$n) { + $info = $depts[$id]; + if (!$disabled && $info['disabled']) + continue; + if ($disabled === self::DISPLAY_DISABLED && $info['disabled']) + $n .= " - ".__("(disabled)"); + $requested_names[$id] = $n; + } + asort($requested_names); + + // TODO: Use locale-aware sorting mechanism if ($criteria) - return $names; + return $requested_names; - $depts = $names; + $depts = $requested_names; } - return $depts; + return $requested_names; } static function getPublicDepartments() { - static $depts =null; + $depts =null; if (!$depts) $depts = self::getDepartments(array('publiconly'=>true)); @@ -620,6 +658,10 @@ implements TemplateVariable { if ($vars['pid'] && !($p = static::lookup($vars['pid']))) $errors['pid'] = __('Department selection is required'); + $dept = Dept::lookup($vars['pid']); + if($dept && !$dept->isActive()) + $errors['dept_id'] = sprintf(__('%s selected must be active'), __('Parent Department')); + // Format access update as [array(dept_id, role_id, alerts?)] $access = array(); if (isset($vars['members'])) { @@ -645,10 +687,27 @@ implements TemplateVariable { $this->group_membership = $vars['group_membership']; $this->ticket_auto_response = isset($vars['ticket_auto_response'])?$vars['ticket_auto_response']:1; $this->message_auto_response = isset($vars['message_auto_response'])?$vars['message_auto_response']:1; - $this->flags = 0; $this->setFlag(self::FLAG_ASSIGN_MEMBERS_ONLY, isset($vars['assign_members_only'])); $this->setFlag(self::FLAG_DISABLE_AUTO_CLAIM, isset($vars['disable_auto_claim'])); + switch ($vars['status']) + { + case __('Active'): + $this->setFlag(self::FLAG_ACTIVE, true); + $this->setFlag(self::FLAG_ARCHIVED, false); + break; + + case __('Disabled'): + $this->setFlag(self::FLAG_ACTIVE, false); + $this->setFlag(self::FLAG_ARCHIVED, false); + break; + + case __('Archived'): + $this->setFlag(self::FLAG_ACTIVE, false); + $this->setFlag(self::FLAG_ARCHIVED, true); + break; + } + $this->path = $this->getFullPath(); $wasnew = $this->__new__; @@ -736,7 +795,7 @@ extends Form { 'default' => 0, 'choices' => array(0 => '— '.__('Top-Level Department').' —') - + Dept::getDepartments() + + Dept::getPublicDepartments() )), 'name' => new TextboxField(array( 'required' => true, diff --git a/include/class.email.php b/include/class.email.php index c1542113e..7df0f5ea3 100644 --- a/include/class.email.php +++ b/include/class.email.php @@ -264,6 +264,14 @@ class Email extends VerySimpleModel { if(!$vars['name']) $errors['name']=__('Email name required'); + $dept = Dept::lookup($vars['dept_id']); + if($dept && !$dept->isActive()) + $errors['dept_id'] = ''; + + $topic = Topic::lookup($vars['topic_id']); + if($topic && !$topic->isActive()) + $errors['topic_id'] = ''; + if($vars['mail_active'] || ($vars['smtp_active'] && $vars['smtp_auth'])) { if(!$vars['userid']) $errors['userid']=__('Username missing'); diff --git a/include/class.filter.php b/include/class.filter.php index 29f49d904..4adab8206 100644 --- a/include/class.filter.php +++ b/include/class.filter.php @@ -457,6 +457,22 @@ class Filter { } function save($id,$vars,&$errors) { + if ($this) + { + foreach ($this->getActions() as $A) { + if ($A->type == 'dept') + $dept = Dept::lookup($A->parseConfiguration($vars)['dept_id']); + + if ($A->type == 'topic') + $topic = Topic::lookup($A->parseConfiguration($vars)['topic_id']); + } + } + + if($dept && !$dept->isActive()) + $errors['err'] = sprintf(__('%s selected for %s must be active'), __('Department'), __('Filter Action')); + + if($topic && !$topic->isActive()) + $errors['err'] = sprintf(__('%s selected for %s must be active'), __('Help Topic'), __('Filter Action')); if(!$vars['execorder']) $errors['execorder'] = __('Order required'); @@ -542,7 +558,7 @@ class Filter { $I->setConfiguration($errors, $vars); $I->save(); break; - case 'I': # exiting filter action + case 'I': # existing filter action if ($I = FilterAction::lookup($info)) { $I->setConfiguration($errors, $vars); $I->sort = (int) $sort; diff --git a/include/class.filter_action.php b/include/class.filter_action.php index f5dc14abb..dc4eeafd7 100644 --- a/include/class.filter_action.php +++ b/include/class.filter_action.php @@ -41,15 +41,28 @@ class FilterAction extends VerySimpleModel { return $this->_config; } - function setConfiguration(&$errors=array(), $source=false) { - $config = array(); - foreach ($this->getImpl()->getConfigurationForm($source ?: $_POST) - ->getFields() as $name=>$field) { - if (!$field->hasData()) - continue; + function parseConfiguration($source, &$errors=array()) + { + if (!$source) + return $this->getConfiguration(); + + $config = array(); + foreach ($this->getImpl()->getConfigurationForm($source) + ->getFields() as $name=>$field) { + if (!$field->hasData()) + continue; + if($field->to_php($field->getClean())) $config[$name] = $field->to_php($field->getClean()); - $errors = array_merge($errors, $field->errors()); - } + else + $config[$name] = $field->getClean(); + + $errors = array_merge($errors, $field->errors()); + } + return $config; + } + + function setConfiguration(&$errors=array(), $source=false) { + $config = $this->parseConfiguration($source ?: $_POST, $errors); if (count($errors) === 0) $this->set('configuration', JsonDataEncoder::encode($config)); return count($errors) === 0; @@ -279,14 +292,11 @@ class FA_RouteDepartment extends TriggerAction { function getConfigurationOptions() { return array( - 'dept_id' => new ChoiceField(array( - 'configuration' => array( - 'prompt' => __('Unchanged'), - 'data' => array('quick-add' => 'department'), - ), - 'choices' => - Dept::getDepartments() + - array(':new:' => '— '.__('Add New').' —'), + 'dept_id' => new DepartmentField(array( + 'configuration' => array( + 'prompt' => __('Unchanged'), + 'data' => array('quick-add' => 'department'), + ), 'validators' => function($self, $clean) { if ($clean === ':new:') $self->addError(__('Select a department')); diff --git a/include/class.forms.php b/include/class.forms.php index c097dd995..3278a128a 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -2355,10 +2355,52 @@ class DepartmentField extends ChoiceField { function getChoices($verbose=false) { global $cfg; + $selected = self::getWidget(); + if($selected && $selected->value) + { + if(is_array($selected->value)) + { + foreach ($selected->value as $k => $v) + { + $current_id = $k; + $current_name = $v; + } + } + else { + $current_id = $selected->value; + $current_name = Dept::getNameById($current_id); + $addNew = true; + } + } + + $active_depts = array(); + if($current_id) + $active_depts = Dept::objects() + ->filter(array('flags__hasbit' => Dept::FLAG_ACTIVE)) + ->values('id', 'name'); + $choices = array(); - if (($depts = Dept::getDepartments())) - foreach ($depts as $id => $name) - $choices[$id] = $name; + if ($depts = Dept::getDepartments(null, true, Dept::DISPLAY_DISABLED)) + { + //create array w/queryset + $active = array(); + foreach ($active_depts as $dept) + $active[$dept['id']] = $dept['name']; + + //add selected dept to list + $active[$current_id] = $current_name; + + + foreach ($depts as $id => $name) + { + $choices[$id] = $name; + if(!array_key_exists($id, $active) && $current_id) + unset($choices[$id]); + } + + } + if($addNew) + $choices[':new:'] = '— '.__('Add New').' —'; return $choices; } diff --git a/include/class.staff.php b/include/class.staff.php index e5ed7e775..5fa529388 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -1002,6 +1002,10 @@ implements AuthenticatedUser, EmailContact, TemplateVariable { if(!$vars['role_id']) $errors['role_id']=__('Role for primary department is required'); + $dept = Dept::lookup($vars['dept_id']); + if(!$dept->isActive()) + $errors['dept_id'] = sprintf(__('%s selected must be active'), __('Department')); + // Ensure we will still have an administrator with access if ($vars['isadmin'] !== '1' || $vars['islocked'] === '1') { $sql = 'select count(*), max(staff_id) from '.STAFF_TABLE diff --git a/include/class.ticket.php b/include/class.ticket.php index 7cc661f95..3b4920f71 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -297,7 +297,8 @@ implements RestrictedAccess, Threadable { } function isReopenable() { - return $this->getStatus()->isReopenable(); + return ($this->getStatus()->isReopenable() + && $this->getDept()->allowsReopen()); } function isClosed() { @@ -2780,6 +2781,10 @@ implements RestrictedAccess, Threadable { $errors['source'] = sprintf( __('Invalid source given - %s'), Format::htmlchars($vars['source'])); + $topic = Topic::lookup($vars['topicId']); + if($topic && !$topic->isActive()) + $errors['topicId']= sprintf(__('%s selected must be active'), __('Help Topic')); + // Validate dynamic meta-data $forms = DynamicFormEntry::forTicket($this->getId()); foreach ($forms as $form) { diff --git a/include/class.topic.php b/include/class.topic.php index c25ab788a..fd865acf9 100644 --- a/include/class.topic.php +++ b/include/class.topic.php @@ -67,6 +67,8 @@ implements TemplateVariable { const FORM_USE_PARENT = 4294967295; const FLAG_CUSTOM_NUMBERS = 0x0001; + const FLAG_ACTIVE = 0x0002; + const FLAG_ARCHIVED = 0x0004; const SORT_ALPHA = 'a'; const SORT_MANUAL = 'm'; @@ -124,6 +126,11 @@ implements TemplateVariable { return $this->dept_id; } + function getDept() { + + return $this->getDeptId() ? Dept::lookup($this->getDeptId()) : null; + } + function getSLAId() { return $this->sla_id; } @@ -172,30 +179,22 @@ implements TemplateVariable { return $this->isActive(); } - /** - * Determine if the help topic is currently enabled. The ancestry of - * this topic will be considered to see if any of the parents are - * disabled. If any are disabled, then this topic will be considered - * disabled. - * - * Parameters: - * $chain - array<id:bool> recusion chain used to detect loops. The - * chain should be maintained and passed to a parent's ::isActive() - * method. When consulting a parent, if the local topic ID is a key - * in the chain, then this topic has already been considered, and - * there is a loop in the ancestry - */ - function isActive(array $chain=array()) { - if (!$this->isactive) - return false; + function isActive() + { + return !!($this->flags & self::FLAG_ACTIVE); + } - if (!isset($chain[$this->getId()]) && ($p = $this->getParent())) { - $chain[$this->getId()] = true; - return $p->isActive($chain); - } - else { - return $this->isactive; - } + function getStatus() { + if($this->flags & self::FLAG_ACTIVE) + return 'Active'; + elseif($this->flags & self::FLAG_ARCHIVED) + return 'Archived'; + else + return 'Disabled'; + } + + function allowsReopen() { + return !($this->flags & self::FLAG_ARCHIVED); } function isPublic() { @@ -209,6 +208,7 @@ implements TemplateVariable { function getInfo() { $base = $this->getHashtable(); $base['custom-numbers'] = $this->hasFlag(self::FLAG_CUSTOM_NUMBERS); + $base['status'] = $this->getStatus(); return $base; } @@ -291,75 +291,91 @@ implements TemplateVariable { return $topic; } - static function getHelpTopics($publicOnly=false, $disabled=false, $localize=true) { - global $cfg; - static $topics, $names = array(); - - // If localization is specifically requested, then rebuild the list. - if (!$names || $localize) { - $objects = self::objects()->values_flat( - 'topic_id', 'topic_pid', 'ispublic', 'isactive', 'topic' - ) - ->order_by('sort'); - - // Fetch information for all topics, in declared sort order - $topics = array(); - foreach ($objects as $T) { - list($id, $pid, $pub, $act, $topic) = $T; - $topics[$id] = array('pid'=>$pid, 'public'=>$pub, - 'disabled'=>!$act, 'topic'=>$topic); - } - - $localize_this = function($id, $default) use ($localize) { - if (!$localize) - return $default; - - $tag = _H("topic.name.{$id}"); - $T = CustomDataTranslation::translate($tag); - return $T != $tag ? $T : $default; - }; - - // Resolve parent names - foreach ($topics as $id=>$info) { - $name = $localize_this($id, $info['topic']); - $loop = array($id=>true); - $parent = false; - while (($pid = $info['pid']) && ($info = $topics[$info['pid']])) { - $name = sprintf('%s / %s', $localize_this($pid, $info['topic']), - $name); - if ($parent && $parent['disabled']) - // Cascade disabled flag - $topics[$id]['disabled'] = true; - if (isset($loop[$info['pid']])) - break; - $loop[$info['pid']] = true; - $parent = $info; - } - $names[$id] = $name; - } - } - - // Apply requested filters - $requested_names = array(); - foreach ($names as $id=>$n) { - $info = $topics[$id]; - if ($publicOnly && !$info['public']) - continue; - if (!$disabled && $info['disabled']) - continue; - if ($disabled === self::DISPLAY_DISABLED && $info['disabled']) - $n .= " - ".__("(disabled)"); - $requested_names[$id] = $n; - } + /** + * setFlag + * + * Utility method to set/unset flag bits + * + */ + public function setFlag($flag, $val) { - // If localization requested and the current locale is not the - // primary, the list may need to be sorted. Caching is ok here, - // because the locale is not going to be changed within a single - // request. - if ($localize && $cfg->getTopicSortMode() == self::SORT_ALPHA) - return Internationalization::sortKeyedList($requested_names); + if ($val) + $this->flags |= $flag; + else + $this->flags &= ~$flag; + } - return $requested_names; + static function getHelpTopics($publicOnly=false, $disabled=false, $localize=true) { + global $cfg; + static $topics, $names = array(); + + // If localization is specifically requested, then rebuild the list. + if (!$names || $localize) { + $objects = self::objects()->values_flat( + 'topic_id', 'topic_pid', 'ispublic', 'flags', 'topic' + ) + ->order_by('sort'); + + // Fetch information for all topics, in declared sort order + $topics = array(); + foreach ($objects as $T) { + list($id, $pid, $pub, $flags, $topic) = $T; + + $display = ($flags & self::FLAG_ACTIVE); + $topics[$id] = array('pid'=>$pid, 'public'=>$pub, + 'disabled'=>!$display, 'topic'=>$topic); + } + + $localize_this = function($id, $default) use ($localize) { + if (!$localize) + return $default; + + $tag = _H("topic.name.{$id}"); + $T = CustomDataTranslation::translate($tag); + return $T != $tag ? $T : $default; + }; + + // Resolve parent names + foreach ($topics as $id=>$info) { + $name = $localize_this($id, $info['topic']); + $loop = array($id=>true); + $parent = false; + while (($pid = $info['pid']) && ($info = $topics[$info['pid']])) { + $name = sprintf('%s / %s', $localize_this($pid, $info['topic']), + $name); + if ($parent && $parent['disabled']) + // Cascade disabled flag + $topics[$id]['disabled'] = true; + if (isset($loop[$info['pid']])) + break; + $loop[$info['pid']] = true; + $parent = $info; + } + $names[$id] = $name; + } + } + + // Apply requested filters + $requested_names = array(); + foreach ($names as $id=>$n) { + $info = $topics[$id]; + if ($publicOnly && !$info['public']) + continue; + if (!$disabled && $info['disabled']) + continue; + if ($disabled === self::DISPLAY_DISABLED && $info['disabled']) + $n .= " - ".__("(disabled)"); + $requested_names[$id] = $n; + } + + // If localization requested and the current locale is not the + // primary, the list may need to be sorted. Caching is ok here, + // because the locale is not going to be changed within a single + // request. + if ($localize && $cfg->getTopicSortMode() == self::SORT_ALPHA) + return Internationalization::sortKeyedList($requested_names); + + return $requested_names; } static function getPublicHelpTopics() { @@ -401,6 +417,10 @@ implements TemplateVariable { && (!isset($this->topic_id) || $tid!=$this->getId())) $errors['topic']=__('Topic already exists'); + $dept = Dept::lookup($vars['dept_id']); + if(!$dept->isActive()) + $errors['dept_id'] = sprintf(__('%s selected must be active'), __('Department')); + if (!is_numeric($vars['dept_id'])) $errors['dept_id']=__('Department selection is required'); @@ -422,10 +442,28 @@ implements TemplateVariable { $this->ispublic = !!$vars['ispublic']; $this->sequence_id = $vars['custom-numbers'] ? $vars['sequence_id'] : 0; $this->number_format = $vars['custom-numbers'] ? $vars['number_format'] : ''; - $this->flags = $vars['custom-numbers'] ? self::FLAG_CUSTOM_NUMBERS : 0; + $this->flags = $vars['custom-numbers'] ? self::FLAG_CUSTOM_NUMBERS : $this->flags; $this->noautoresp = !!$vars['noautoresp']; $this->notes = Format::sanitize($vars['notes']); + switch ($vars['status']) + { + case __('Active'): + $this->setFlag(self::FLAG_ACTIVE, true); + $this->setFlag(self::FLAG_ARCHIVED, false); + break; + + case __('Disabled'): + $this->setFlag(self::FLAG_ACTIVE, false); + $this->setFlag(self::FLAG_ARCHIVED, false); + break; + + case __('Archived'): + $this->setFlag(self::FLAG_ACTIVE, false); + $this->setFlag(self::FLAG_ARCHIVED, true); + break; + } + //Auto assign ID is overloaded... if ($vars['assign'] && $vars['assign'][0] == 's') { $this->team_id = 0; diff --git a/include/client/view.inc.php b/include/client/view.inc.php index 2aa01d019..37548ca1e 100644 --- a/include/client/view.inc.php +++ b/include/client/view.inc.php @@ -174,7 +174,8 @@ echo $attrs; ?>><?php echo $draft ?: $info['message']; print $attachments->render(array('client'=>true)); } ?> </div> -<?php if ($ticket->isClosed()) { ?> +<?php + if ($ticket->isClosed() && $ticket->isReopenable()) { ?> <div class="warning-banner"> <?php echo __('Ticket will be reopened on message post'); ?> </div> diff --git a/include/staff/cannedresponse.inc.php b/include/staff/cannedresponse.inc.php index 20818d994..981eef289 100644 --- a/include/staff/cannedresponse.inc.php +++ b/include/staff/cannedresponse.inc.php @@ -57,7 +57,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <select name="dept_id"> <option value="0">— <?php echo __('All Departments');?> —</option> <?php - if (($depts=Dept::getDepartments())) { + if (($depts=Dept::getDepartments(array('publiconly' => true)))) { foreach($depts as $id => $name) { $selected=($info['dept_id'] && $id==$info['dept_id'])?'selected="selected"':''; echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name); diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php index 2ea8825e3..19364945b 100644 --- a/include/staff/department.inc.php +++ b/include/staff/department.inc.php @@ -59,14 +59,27 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info); <td> <select name="pid"> <option value="">— <?php echo __('Top-Level Department'); ?> —</option> -<?php foreach (Dept::getDepartments() as $id=>$name) { - if ($info['id'] && $id == $info['id']) - continue; ?> - <option value="<?php echo $id; ?>" <?php - if ($info['pid'] == $id) echo 'selected="selected"'; - ?>><?php echo $name; ?></option> -<?php } ?> - </select> + <?php + if($info['pid']) + $current_name = Dept::getNameById($info['pid']); + if ($depts=Dept::getPublicDepartments()) + { + if(!array_key_exists($info['pid'], $depts) && $info['pid']) + { + $depts[$info['pid']] = $current_name; + $warn = sprintf(__('%s selected must be active'), __('Parent Department')); + } + foreach ($depts as $id=>$name) { + $selected=($info['pid'] && $id==$info['pid'])?'selected="selected"':''; + echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name); + } + } + ?> + </select> + <?php + if($warn) { ?> + <span class="error">* <?php echo $warn; ?></span> + <?php } ?> </td> </tr> <tr> @@ -80,6 +93,16 @@ $info = Format::htmlchars(($errors && $_POST) ? $_POST : $info); <span class="error">* <?php echo $errors['name']; ?></span> </td> </tr> + <tr> + <td width="180" class="required"> + <?php echo __('Status');?>: + </td> + <td> + <input type="radio" name="status" value="Active" <?php echo $info['status'] == 'Active'?'checked="checked"':''; ?>> <?php echo __('Active'); ?> + <input type="radio" name="status" value="Disabled" <?php echo $info['status'] == 'Disabled'?'checked="checked"':''; ?>> <?php echo __('Disabled'); ?> + <input type="radio" name="status" value="Archived" <?php echo $info['status'] == 'Archived'?'checked="checked"':''; ?>> <?php echo __('Archived'); ?> + </td> + </tr> <tr> <td width="180" class="required"> <?php echo __('Type');?>: diff --git a/include/staff/departments.inc.php b/include/staff/departments.inc.php index 2924eea68..4fd4a34c9 100644 --- a/include/staff/departments.inc.php +++ b/include/staff/departments.inc.php @@ -5,6 +5,7 @@ if (!defined('OSTADMININC') || !$thisstaff->isAdmin()) $qs = array(); $sortOptions=array( 'name' => 'name', + 'status' => 'flags', 'type' => 'ispublic', 'members'=> 'members_count', 'email'=> 'email__name', @@ -53,9 +54,28 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count); </span> <div id="action-dropdown-more" class="action-dropdown anchor-right"> <ul id="actions"> + <li> + <a class="confirm" data-name="enable" href="departments.php?a=enable"> + <i class="icon-ok-sign icon-fixed-width"></i> + <?php echo __( 'Enable'); ?> + </a> + </li> + <li> + <a class="confirm" data-name="disable" href="departments.php?a=disable"> + <i class="icon-ban-circle icon-fixed-width"></i> + <?php echo __( 'Disable'); ?> + </a> + </li> + <li> + <a class="confirm" data-name="archive" href="departments.php?a=archive"> + <i class="icon-folder-close icon-fixed-width"></i> + <?php echo __( 'Archive'); ?> + </a> + </li> <li class="danger"><a class="confirm" data-name="delete" href="departments.php?a=delete"> <i class="icon-trash icon-fixed-width"></i> - <?php echo __('Delete'); ?></a></li> + <?php echo __('Delete'); ?></a> + </li> </ul> </div> </div> @@ -70,8 +90,11 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count); <tr> <th width="4%"> </th> <th width="28%"><a <?php echo $name_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=name"><?php echo __('Name');?></a></th> + <th width="8%"><a <?php echo $status_sort; ?> href="departments.php?<?php echo $qstr;?>&sort=status"><?php echo __('Status');?></a></th> + <!-- <th style="padding-left:4px;vertical-align:middle" width="8%"><?php echo __('Status'); ?></th> --> <th width="8%"><a <?php echo $type_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=type"><?php echo __('Type');?></a></th> - <th width="8%"><a <?php echo $users_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=users"><?php echo __('Agents');?></a></th> + <!-- <th width="8%"><a <?php echo $users_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=users"><?php echo __('Agents');?></a></th> --> + <th width="8%"><a <?php echo $users_sort; ?>href="departments.php?<?php echo $qstr; ?>&sort=members"><?php echo __('Agents');?></a></th> <th width="30%"><a <?php echo $email_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=email"><?php echo __('Email Address');?></a></th> <th width="22%"><a <?php echo $manager_sort; ?> href="departments.php?<?php echo $qstr; ?>&sort=manager"><?php echo __('Manager');?></a></th> </tr> @@ -115,8 +138,17 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count); <?php echo $sel? 'checked="checked"' : ''; ?> <?php echo $default? 'disabled="disabled"' : ''; ?> > </td> - <td><a href="departments.php?id=<?php echo $id; ?>"><?php - echo Dept::getNameById($id); ?></a> <?php echo $default; ?></td> + <td> + <a href="departments.php?id=<?php echo $id; ?>"><?php + echo Dept::getNameById($id); ?></a> <?php echo $default; ?> + </td> + <td><?php + if($dept->getStatus() == __('Active')) + echo $dept->getStatus(); + else + echo '<b>'.$dept->getStatus(); + ?> + </td> <td><?php echo $dept->isPublic() ? __('Public') :'<b>'.__('Private').'</b>'; ?></td> <td> <b> @@ -136,7 +168,7 @@ $showing = $pageNav->showing().' '._N('department', 'departments', $count); } ?> <tfoot> <tr> - <td colspan="6"> + <td colspan="7"> <?php if ($count) { ?> <?php echo __('Select');?>: @@ -170,6 +202,18 @@ endif; <?php echo sprintf(__('Are you sure you want to make %s <b>private</b> (internal)?'), _N('selected department', 'selected departments', 2));?> </p> + <p class="confirm-action" style="display:none;" id="enable-confirm"> + <?php echo sprintf(__('Are you sure you want to <b>enable</b> %s?'), + _N('selected department', 'selected departments', 2));?> + </p> + <p class="confirm-action" style="display:none;" id="disable-confirm"> + <?php echo sprintf(__('Are you sure you want to <b>disable</b> %s?'), + _N('selected department', 'selected departments', 2));?> + </p> + <p class="confirm-action" style="display:none;" id="archive-confirm"> + <?php echo sprintf(__('Are you sure you want to <b>archive</b> %s?'), + _N('selected department', 'selected departments', 2));?> + </p> <p class="confirm-action" style="display:none;" id="delete-confirm"> <font color="red"><strong><?php echo sprintf(__('Are you sure you want to DELETE %s?'), _N('selected department', 'selected departments', 2));?></strong></font> diff --git a/include/staff/email.inc.php b/include/staff/email.inc.php index 3653f06a7..86ac887a0 100644 --- a/include/staff/email.inc.php +++ b/include/staff/email.inc.php @@ -87,7 +87,13 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <option value="0" selected="selected">— <?php echo __('System Default'); ?> —</option> <?php - if (($depts=Dept::getDepartments())) { + if ($depts=Dept::getPublicDepartments()) { + if($info['dept_id'] && !array_key_exists($info['dept_id'], $depts)) + { + $depts[$info['dept_id']] = $email->dept; + $warn = sprintf(__('%s selected must be active'), __('Department')); + } + foreach ($depts as $id => $name) { $selected=($info['dept_id'] && $id==$info['dept_id'])?'selected="selected"':''; echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name); @@ -95,9 +101,12 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); } ?> </select> + <?php + if($warn) { ?> + <span class="error">* <?php echo $warn; ?></span> + <?php } ?> <i class="help-tip icon-question-sign" href="#new_ticket_department"></i> </span> - <span class="error"><?php echo $errors['dept_id']; ?></span> </td> </tr> <tr> @@ -133,12 +142,22 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <select name="topic_id"> <option value="0" selected="selected">— <?php echo __('System Default'); ?> —</option> <?php + $warn = ''; $topics = Topic::getHelpTopics(); + if($info['topic_id'] && !array_key_exists($info['topic_id'], $topics)) + { + $topics[$info['topic_id']] = $email->topic; + $warn = sprintf(__('%s selected must be active'), __('Help Topic')); + } while (list($id,$topic) = each($topics)) { ?> <option value="<?php echo $id; ?>"<?php echo ($info['topic_id']==$id)?'selected':''; ?>><?php echo $topic; ?></option> <?php } ?> </select> + <?php + if($warn) { ?> + <span class="error">* <?php echo $warn; ?></span> + <?php } ?> <i class="help-tip icon-question-sign" href="#new_ticket_help_topic"></i> </span> <span class="error"> diff --git a/include/staff/filter.inc.php b/include/staff/filter.inc.php index 2330fc47d..c04ad7014 100644 --- a/include/staff/filter.inc.php +++ b/include/staff/filter.inc.php @@ -238,7 +238,25 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <?php $existing = array(); if ($filter) { foreach ($filter->getActions() as $A) { + $_warn = ''; $existing[] = $A->type; + if($A->type == 'dept') + { + $errors['topic_id'] = ''; + // $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); + $dept_config = $A->parseConfiguration($_POST); + $dept = Dept::lookup($dept_config['dept_id']); + if($dept && !$dept->isActive()) + $_warn = sprintf(__('%s must be active'), __('Department')); + } + elseif($A->type == 'topic') + { + $errors['dept_id'] = ''; + $topic_config = $A->parseConfiguration($_POST); + $topic = Topic::lookup($topic_config['topic_id']); + if($topic && !$topic->isActive()) + $_warn = sprintf(__('%s must be active'), __('Help Topic')); + } ?> <tr style="background-color:white"><td><i class="icon-sort icon-large icon-muted"></i> <?php echo $A->getImpl()->getName(); ?>:</td> @@ -248,7 +266,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); // XXX: Drop this when the ORM supports proper caching $form->isValid(); include STAFFINC_DIR . 'templates/dynamic-form-simple.tmpl.php'; - ?> + if($_warn) { + ?> <span class="error">* <?php echo $_warn; ?></span> + <?php } ?> <input type="hidden" name="actions[]" value="I<?php echo $A->getId(); ?>"/> <div class="pull-right" style="position:absolute;top:2px;right:2px;"> <a href="#" title="<?php echo __('clear'); ?>" onclick="javascript: diff --git a/include/staff/helptopic.inc.php b/include/staff/helptopic.inc.php index 8cb90850d..15a7cb217 100644 --- a/include/staff/helptopic.inc.php +++ b/include/staff/helptopic.inc.php @@ -15,7 +15,7 @@ if($topic && $_REQUEST['a']!='add') { $title=__('Add New Help Topic'); $action='create'; $submit_text=__('Add Topic'); - $info['isactive']=isset($info['isactive'])?$info['isactive']:1; + // $info['isactive']=isset($info['isactive'])?$info['isactive']:1; $info['ispublic']=isset($info['ispublic'])?$info['ispublic']:1; $qs += array('a' => $_REQUEST['a']); $forms = TicketForm::objects(); @@ -60,8 +60,9 @@ $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"':''; ?>> <?php echo __('Active'); ?> - <input type="radio" name="isactive" value="0" <?php echo !$info['isactive']?'checked="checked"':''; ?>> <?php echo __('Disabled'); ?> + <input type="radio" name="status" value="Active" <?php echo $info['status'] == 'Active'?'checked="checked"':''; ?>> <?php echo __('Active'); ?> + <input type="radio" name="status" value="Disabled" <?php echo $info['status'] == 'Disabled'?'checked="checked"':''; ?>> <?php echo __('Disabled'); ?> + <input type="radio" name="status" value="Archived" <?php echo $info['status'] == 'Archived'?'checked="checked"':''; ?>> <?php echo __('Archived'); ?> <span class="error">* </span> <i class="help-tip icon-question-sign" href="#status"></i> </td> </tr> @@ -82,7 +83,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <td> <select name="topic_pid"> <option value="">— <?php echo __('Top-Level Topic'); ?> —</option><?php - $topics = Topic::getAllHelpTopics(); + $topics = Topic::getHelpTopics(); while (list($id,$topic) = each($topics)) { if ($id == $info['topic_id']) continue; ?> @@ -122,13 +123,26 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <select name="dept_id" data-quick-add="department"> <option value="0">— <?php echo __('System Default'); ?> —</option> <?php - foreach (Dept::getDepartments() as $id=>$name) { + if($info['dept_id']) + $current_name = Dept::getNameById($info['dept_id']); + if ($depts=Dept::getPublicDepartments()) { + if(!array_key_exists($info['dept_id'], $depts) && $info['dept_id']) + { + $depts[$info['dept_id']] = $current_name; + $warn = sprintf(__('%s selected must be active'), __('Department')); + } + foreach ($depts as $id=>$name) { $selected=($info['dept_id'] && $id==$info['dept_id'])?'selected="selected"':''; echo sprintf('<option value="%d" %s>%s</option>',$id,$selected,$name); - } ?> + } + } + ?> <option value="0" data-quick-add>— <?php echo __('Add New');?> —</option> </select> - <span class="error"> <?php echo $errors['dept_id']; ?></span> + <?php + if($warn) { ?> + <span class="error">* <?php echo $warn; ?></span> + <?php } ?> <i class="help-tip icon-question-sign" href="#department"></i> </td> </tr> diff --git a/include/staff/helptopics.inc.php b/include/staff/helptopics.inc.php index 0b5c58580..8978b97e3 100644 --- a/include/staff/helptopics.inc.php +++ b/include/staff/helptopics.inc.php @@ -41,6 +41,12 @@ $order_by = 'sort'; <?php echo __( 'Disable'); ?> </a> </li> + <li> + <a class="confirm" data-name="archive" href="helptopics.php?a=archive"> + <i class="icon-folder-close icon-fixed-width"></i> + <?php echo __( 'Archive'); ?> + </a> + </li> <li class="danger"> <a class="confirm" data-name="delete" href="helptopics.php?a=delete"> <i class="icon-trash icon-fixed-width"></i> @@ -142,7 +148,13 @@ $order_by = 'sort'; <a href="helptopics.php?id=<?php echo $id; ?>"><?php echo Topic::getTopicName($id); ?></a> </td> - <td><?php echo $topic->isactive ? __('Active') : '<b>'.__('Disabled').'</b>'; ?></td> + <td><?php + if($topic->getStatus() == __('Active')) + echo $topic->getStatus(); + else + echo '<b>'.$topic->getStatus(); + ?> + </td> <td><?php echo $topic->ispublic ? __('Public') : '<b>'.__('Private').'</b>'; ?></td> <td><?php echo $priority; ?></td> <td><a href="departments.php?id=<?php echo $deptId; @@ -189,6 +201,10 @@ endif; <?php echo sprintf(__('Are you sure you want to <b>disable</b> %s?'), _N('selected help topic', 'selected help topics', 2));?> </p> + <p class="confirm-action" style="display:none;" id="archive-confirm"> + <?php echo sprintf(__('Are you sure you want to <b>archive</b> %s?'), + _N('selected help topic', 'selected help topics', 2));?> + </p> <p class="confirm-action" style="display:none;" id="delete-confirm"> <font color="red"><strong><?php echo sprintf(__('Are you sure you want to DELETE %s?'), _N('selected help topic', 'selected help topics', 2));?></strong></font> diff --git a/include/staff/staff.inc.php b/include/staff/staff.inc.php index 4fce85b4f..217daa065 100644 --- a/include/staff/staff.inc.php +++ b/include/staff/staff.inc.php @@ -228,15 +228,25 @@ if (count($bks) > 1) { <select name="dept_id" id="dept_id" data-quick-add="department"> <option value="0">— <?php echo __('Select Department');?> —</option> <?php - foreach (Dept::getDepartments() as $id=>$name) { - $sel=($staff->dept_id==$id)?'selected="selected"':''; - echo sprintf('<option value="%d" %s>%s</option>',$id,$sel,$name); + if($depts = Dept::getPublicDepartments()) { + if($staff->dept_id && !array_key_exists($staff->dept_id, $depts)) + { + $depts[$staff->dept_id] = $staff->dept; + $warn = sprintf(__('%s selected must be active'), __('Department')); + } + foreach($depts as $id =>$name) { + $sel=($staff->dept_id==$id)?'selected="selected"':''; + echo sprintf('<option value="%d" %s>%s</option>',$id,$sel,$name); + } } ?> <option value="0" data-quick-add>— <?php echo __('Add New');?> —</option> </select> <i class="offset help-tip icon-question-sign" href="#primary_department"></i> - <div class="error"><?php echo $errors['dept_id']; ?></div> + <?php + if($warn) { ?> + <span class="error">* <?php echo $warn; ?></span> + <?php } ?> </td> <td style="vertical-align:top"> <select name="role_id" data-quick-add="role"> diff --git a/include/staff/ticket-edit.inc.php b/include/staff/ticket-edit.inc.php index e15e8554d..ecd09a6a2 100644 --- a/include/staff/ticket-edit.inc.php +++ b/include/staff/ticket-edit.inc.php @@ -94,6 +94,11 @@ if ($_POST) <option value="" selected >— <?php echo __('Select Help Topic');?> —</option> <?php if($topics=Topic::getHelpTopics()) { + if(!array_key_exists($ticket->topic_id, $topics)) + { + $topics[$ticket->topic_id] = $ticket->topic; + $warn = sprintf(__('%s selected must be active'), __('Help Topic')); + } foreach($topics as $id =>$name) { echo sprintf('<option value="%d" %s>%s</option>', $id, ($info['topicId']==$id)?'selected="selected"':'',$name); @@ -101,7 +106,10 @@ if ($_POST) } ?> </select> - <font class="error"><b>*</b> <?php echo $errors['topicId']; ?></font> + <?php + if($warn) { ?> + <font class="error"><b>*</b> <?php echo $warn; ?></font> + <?php } ?> </td> </tr> <tr> diff --git a/include/staff/ticket-open.inc.php b/include/staff/ticket-open.inc.php index 6d383e580..850725755 100644 --- a/include/staff/ticket-open.inc.php +++ b/include/staff/ticket-open.inc.php @@ -190,7 +190,7 @@ if ($_POST) <select name="deptId"> <option value="" selected >— <?php echo __('Select Department'); ?>—</option> <?php - if($depts=Dept::getDepartments(array('dept_id' => $thisstaff->getDepts()))) { + if($depts=Dept::getPublicDepartments()) { foreach($depts as $id =>$name) { if (!($role = $thisstaff->getRole($id)) || !$role->hasPerm(Ticket::PERM_CREATE) diff --git a/scp/departments.php b/scp/departments.php index c1d860488..5bb8e0dd4 100644 --- a/scp/departments.php +++ b/scp/departments.php @@ -19,118 +19,196 @@ $dept=null; if($_REQUEST['id'] && !($dept=Dept::lookup($_REQUEST['id']))) $errors['err']=sprintf(__('%s: Unknown or invalid ID.'), __('department')); -if($_POST){ - switch(strtolower($_POST['do'])){ - case 'update': - if(!$dept){ - $errors['err']=sprintf(__('%s: Unknown or invalid'), __('department')); - }elseif($dept->update($_POST,$errors)){ - $msg=sprintf(__('Successfully updated %s.'), - __('this department')); - }elseif(!$errors['err']){ - $errors['err'] = sprintf('%s %s', - sprintf(__('Unable to update %s.'), __('this department')), - __('Correct any errors below and try again.')); - } - break; - case 'create': - $_dept = Dept::create(); - if(($_dept->update($_POST,$errors))){ - $msg=sprintf(__('Successfully added %s.'),Format::htmlchars($_POST['name'])); - $_REQUEST['a']=null; - }elseif(!$errors['err']){ - $errors['err']=sprintf('%s %s', - sprintf(__('Unable to add %s.'), __('this department')), - __('Correct any errors below and try again.')); - } - break; - case 'mass_process': - if(!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) { - $errors['err'] = sprintf(__('You must select at least %s.'), - __('one department')); - }elseif(in_array($cfg->getDefaultDeptId(),$_POST['ids'])) { - $errors['err'] = __('You cannot disable/delete a default department. Select a new default department and try again.'); - }else{ - $count=count($_POST['ids']); - switch(strtolower($_POST['a'])) { - case 'make_public': - $sql='UPDATE '.DEPT_TABLE.' SET ispublic=1 ' - .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')'; - if(db_query($sql) && ($num=db_affected_rows())){ - if($num==$count) - $msg=sprintf(__('Successfully made %s PUBLIC'), - _N('selected department', 'selected departments', $count)); - else - $warn=sprintf(__( - /* Phrase will read: - <a> of <b> <selected objects> made PUBLIC */ - '%1$d of %2$d %3$s made PUBLIC'), $num, $count, - _N('selected department', 'selected departments', $count)); - } else { - $errors['err']=sprintf(__('Unable to make %s PUBLIC.'), - _N('selected department', 'selected departments', $count)); - } - break; - case 'make_private': - $sql='UPDATE '.DEPT_TABLE.' SET ispublic=0 ' - .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).') ' - .' AND dept_id!='.db_input($cfg->getDefaultDeptId()); - if(db_query($sql) && ($num=db_affected_rows())) { - if($num==$count) - $msg = sprintf(__('Successfully made %s PRIVATE'), - _N('selected department', 'selected epartments', $count)); - else - $warn = sprintf(__( - /* Phrase will read: - <a> of <b> <selected objects> made PRIVATE */ - '%1$d of %2$d %3$s made PRIVATE'), $num, $count, + if($_POST){ + switch(strtolower($_POST['do'])){ + case 'update': + if(!$dept){ + $errors['err']=sprintf(__('%s: Unknown or invalid'), __('department')); + }elseif($dept->update($_POST,$errors)){ + $msg=sprintf(__('Successfully updated %s.'), + __('this department')); + }elseif(!$errors['err']){ + $errors['err'] = sprintf('%s %s', + sprintf(__('Unable to update %s.'), __('this department')), + __('Correct any errors below and try again.')); + } + break; + case 'create': + $_dept = Dept::create(); + if(($_dept->update($_POST,$errors))){ + $msg=sprintf(__('Successfully added %s.'),Format::htmlchars($_POST['name'])); + $_REQUEST['a']=null; + }elseif(!$errors['err']){ + $errors['err']=sprintf('%s %s', + sprintf(__('Unable to add %s.'), __('this department')), + __('Correct any errors below and try again.')); + } + break; + case 'mass_process': + if(!$_POST['ids'] || !is_array($_POST['ids']) || !count($_POST['ids'])) { + $errors['err'] = sprintf(__('You must select at least %s.'), + __('one department')); + }elseif(in_array($cfg->getDefaultDeptId(),$_POST['ids'])) { + $errors['err'] = __('You cannot disable/delete a default department. Select a new default department and try again.'); + }else{ + $count=count($_POST['ids']); + switch(strtolower($_POST['a'])) { + case 'make_public': + $sql='UPDATE '.DEPT_TABLE.' SET ispublic=1 ' + .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')'; + if(db_query($sql) && ($num=db_affected_rows())){ + if($num==$count) + $msg=sprintf(__('Successfully made %s PUBLIC'), + _N('selected department', 'selected departments', $count)); + else + $warn=sprintf(__( + /* Phrase will read: + <a> of <b> <selected objects> made PUBLIC */ + '%1$d of %2$d %3$s made PUBLIC'), $num, $count, + _N('selected department', 'selected departments', $count)); + } else { + $errors['err']=sprintf(__('Unable to make %s PUBLIC.'), _N('selected department', 'selected departments', $count)); - } else { - $errors['err'] = sprintf(__('Unable to make %s private. Possibly already private!'), - _N('selected department', 'selected departments', $count)); - } - break; - case 'delete': - //Deny all deletes if one of the selections has members in it. - $sql='SELECT count(staff_id) FROM '.STAFF_TABLE - .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')'; - list($members)=db_fetch_row(db_query($sql)); - if($members) - $errors['err']=__('Departments with agents can not be deleted. Move the agents first.'); - else { - $i=0; - foreach($_POST['ids'] as $k=>$v) { - if($v!=$cfg->getDefaultDeptId() && ($d=Dept::lookup($v)) && $d->delete()) - $i++; } - if($i && $i==$count) - $msg = sprintf(__('Successfully deleted %s.'), + break; + case 'make_private': + $sql='UPDATE '.DEPT_TABLE.' SET ispublic=0 ' + .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).') ' + .' AND dept_id!='.db_input($cfg->getDefaultDeptId()); + if(db_query($sql) && ($num=db_affected_rows())) { + if($num==$count) + $msg = sprintf(__('Successfully made %s PRIVATE'), + _N('selected department', 'selected epartments', $count)); + else + $warn = sprintf(__( + /* Phrase will read: + <a> of <b> <selected objects> made PRIVATE */ + '%1$d of %2$d %3$s made PRIVATE'), $num, $count, + _N('selected department', 'selected departments', $count)); + } else { + $errors['err'] = sprintf(__('Unable to make %s private. Possibly already private!'), _N('selected department', 'selected departments', $count)); - elseif($i>0) - $warn = sprintf(__( - /* Phrase will read: - <a> of <b> <selected objects> deleted */ - '%1$d of %2$d %3$s deleted'), $i, $count, + } + break; + case 'enable': + $depts = Dept::objects()->filter(array( + 'id__in'=>$_POST['ids'], + ))->exclude(array( + 'id'=>$cfg->getDefaultDeptId() + )); + foreach ($depts as $d) + { + $d->setFlag(Dept::FLAG_ARCHIVED, false); + $d->setFlag(Dept::FLAG_ACTIVE, true); + if($d->save()) + $num++; + } + + if ($num > 0) { + if($num==$count) + $msg = sprintf(__('Successfully enabled %s'), + _N('selected department', 'selected departments', $count)); + else + $warn = sprintf(__('%1$d of %2$d %3$s enabled'), $num, $count, + _N('selected department', 'selected departments', $count)); + } else { + $errors['err'] = sprintf(__('Unable to enable %s'), _N('selected department', 'selected departments', $count)); - elseif(!$errors['err']) - $errors['err'] = sprintf(__('Unable to delete %s.'), + } + break; + case 'disable': + $depts = Dept::objects()->filter(array( + 'id__in'=>$_POST['ids'], + ))->exclude(array( + 'id'=>$cfg->getDefaultDeptId() + )); + foreach ($depts as $d) + { + $d->setFlag(Dept::FLAG_ARCHIVED, false); + $d->setFlag(Dept::FLAG_ACTIVE, false); + if($d->save()) + $num++; + } + if ($num > 0) { + if($num==$count) + $msg = sprintf(__('Successfully disabled %s'), + _N('selected department', 'selected departments', $count)); + else + $warn = sprintf(__('%1$d of %2$d %3$s disabled'), $num, $count, + _N('selected department', 'selected departments', $count)); + } else { + $errors['err'] = sprintf(__('Unable to disable %s'), _N('selected department', 'selected departments', $count)); - } - break; - default: - $errors['err']=sprintf('%s - %s', __('Unknown action'), __('Get technical help!')); + } + break; + case 'archive': + $depts = Dept::objects()->filter(array( + 'id__in'=>$_POST['ids'], + ))->exclude(array( + 'id'=>$cfg->getDefaultDeptId() + )); + foreach ($depts as $d) + { + $d->setFlag(Dept::FLAG_ARCHIVED, true); + $d->setFlag(Dept::FLAG_ACTIVE, false); + if($d->save()) + $num++; + } + if ($num > 0) { + if($num==$count) + $msg = sprintf(__('Successfully archived %s'), + _N('selected department', 'selected departments', $count)); + else + $warn = sprintf(__('%1$d of %2$d %3$s archived'), $num, $count, + _N('selected department', 'selected departments', $count)); + } else { + $errors['err'] = sprintf(__('Unable to archive %s'), + _N('selected department', 'departments', $count)); + } + break; + case 'delete': + //Deny all deletes if one of the selections has members in it. + $sql='SELECT count(staff_id) FROM '.STAFF_TABLE + .' WHERE dept_id IN ('.implode(',', db_input($_POST['ids'])).')'; + list($members)=db_fetch_row(db_query($sql)); + if($members) + $errors['err']=__('Departments with agents can not be deleted. Move the agents first.'); + else { + $i=0; + foreach($_POST['ids'] as $k=>$v) { + if($v!=$cfg->getDefaultDeptId() && ($d=Dept::lookup($v)) && $d->delete()) + $i++; + } + if($i && $i==$count) + $msg = sprintf(__('Successfully deleted %s.'), + _N('selected department', 'selected departments', $count)); + elseif($i>0) + $warn = sprintf(__( + /* Phrase will read: + <a> of <b> <selected objects> deleted */ + '%1$d of %2$d %3$s deleted'), $i, $count, + _N('selected department', 'selected departments', $count)); + elseif(!$errors['err']) + $errors['err'] = sprintf(__('Unable to delete %s.'), + _N('selected department', 'selected departments', $count)); + } + break; + } } - } - break; - default: - $errors['err']=__('Unknown action'); - break; + break; + default: + $errors['err']=__('Unknown action'); + break; + } } -} $page='departments.inc.php'; $tip_namespace = 'staff.department'; if($dept || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) { + + if ($dept && ($pid=$dept->getParent()) && !$pid->isActive()) + $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Department'), __('Parent Department')); + $page='department.inc.php'; } diff --git a/scp/filters.php b/scp/filters.php index 9e4d63193..9f1a62da3 100644 --- a/scp/filters.php +++ b/scp/filters.php @@ -116,6 +116,22 @@ if($_POST){ $page='filters.inc.php'; $tip_namespace = 'manage.filter'; if($filter || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) { + if($filter) { + foreach ($filter->getActions() as $A) { + if($A->type == 'dept') + $dept = Dept::lookup($A->parseConfiguration($_POST)['dept_id']); + + if($A->type == 'topic') + $topic = Topic::lookup($A->parseConfiguration($_POST)['topic_id']); + } + } + + if($dept && !$dept->isActive()) + $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Ticket Filter'), __('Department')); + + if($topic && !$topic->isActive()) + $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Ticket Filter'), __('Help Topic')); + $page='filter.inc.php'; } diff --git a/scp/helptopics.php b/scp/helptopics.php index b00c231d5..c64a995f0 100644 --- a/scp/helptopics.php +++ b/scp/helptopics.php @@ -63,11 +63,16 @@ if($_POST){ switch(strtolower($_POST['a'])) { case 'enable': - $num = Topic::objects()->filter(array( - 'topic_id__in' => $_POST['ids'], - ))->update(array( - 'isactive' => true, + $topics = Topic::objects()->filter(array( + 'topic_id__in'=>$_POST['ids'], )); + foreach ($topics as $t) + { + $t->setFlag(Topic::FLAG_ARCHIVED, false); + $t->setFlag(Topic::FLAG_ACTIVE, true); + if($t->save()) + $num++; + } if ($num > 0) { if($num==$count) @@ -82,13 +87,18 @@ if($_POST){ } break; case 'disable': - $num = Topic::objects()->filter(array( - 'topic_id__in'=>$_POST['ids'], + $topics = Topic::objects()->filter(array( + 'topic_id__in'=>$_POST['ids'], ))->exclude(array( - 'topic_id'=>$cfg->getDefaultTopicId(), - ))->update(array( - 'isactive' => false, + 'topic_id'=>$cfg->getDefaultTopicId() )); + foreach ($topics as $t) + { + $t->setFlag(Topic::FLAG_ARCHIVED, false); + $t->setFlag(Topic::FLAG_ACTIVE, false); + if($t->save()) + $num++; + } if ($num > 0) { if($num==$count) $msg = sprintf(__('Successfully disabled %s'), @@ -101,6 +111,31 @@ if($_POST){ _N('selected help topic', 'selected help topics', $count)); } break; + case 'archive': + $topics = Topic::objects()->filter(array( + 'topic_id__in'=>$_POST['ids'], + ))->exclude(array( + 'topic_id'=>$cfg->getDefaultTopicId() + )); + foreach ($topics as $t) + { + $t->setFlag(Topic::FLAG_ARCHIVED, true); + $t->setFlag(Topic::FLAG_ACTIVE, false); + if($t->save()) + $num++; + } + if ($num > 0) { + if($num==$count) + $msg = sprintf(__('Successfully archived %s'), + _N('selected help topic', 'selected help topics', $count)); + else + $warn = sprintf(__('%1$d of %2$d %3$s archived'), $num, $count, + _N('selected help topic', 'selected help topics', $count)); + } else { + $errors['err'] = sprintf(__('Unable to archive %s'), + _N('selected help topic', 'selected help topics', $count)); + } + break; case 'delete': $i = Topic::objects()->filter(array( 'topic_id__in'=>$_POST['ids'] @@ -150,7 +185,11 @@ if($_POST){ $page='helptopics.inc.php'; $tip_namespace = 'manage.helptopic'; -if($topic || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) { +if($topic || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) +{ + if ($topic && ($dept=$topic->getDept()) && !$dept->isActive()) + $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Help Topic'), __('Department')); + $page='helptopic.inc.php'; } diff --git a/scp/staff.php b/scp/staff.php index 9b2f4a999..fd744ab90 100644 --- a/scp/staff.php +++ b/scp/staff.php @@ -172,6 +172,10 @@ if($_POST){ $page='staffmembers.inc.php'; $tip_namespace = 'staff.agent'; if($staff || ($_REQUEST['a'] && !strcasecmp($_REQUEST['a'],'add'))) { + + if ($staff && ($pdept=$staff->getDept()) && !$pdept->isActive()) + $warn = sprintf(__('%s is assigned a %s that is not active.'), __('Agent'), __('Primary Department')); + $page='staff.inc.php'; } diff --git a/setup/inc/install-prereq.inc.php b/setup/inc/install-prereq.inc.php index f4346e3f2..97d7a13c4 100644 --- a/setup/inc/install-prereq.inc.php +++ b/setup/inc/install-prereq.inc.php @@ -9,7 +9,7 @@ if(!defined('SETUPINC')) die('Kwaheri!'); <p><?php echo __('We are delighted you have chosen osTicket for your customer support ticketing system!');?></p> <p><?php echo __("The installer will guide you every step of the way in the installation process. You're minutes away from your awesome customer support system!");?></p> </div> - <h3><?php echo __('Prerequisites');?>:</h3> + <h2><?php echo __('Prerequisites');?></h3> <p><?php echo __("Before we begin, we'll check your server configuration to make sure you meet the minimum requirements to run the latest version of osTicket.");?></p> <h3><?php echo __('Required');?>: <font color="red"><?php echo $errors['prereq']; ?></font></h3> <?php echo __('These items are necessary in order to install and use osTicket.');?> -- GitLab