diff --git a/include/class.dept.php b/include/class.dept.php index 5a2babdd3da4021a7b81c736a79210fdf11f1d97..2a4b6eb1bf32740eebcfabe032b29fb1168a01c2 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -89,22 +89,31 @@ class Dept { return $this->getNumStaff(); } - function getAvailableMembers(){ - - if(!$this->members && $this->getNumStaff()){ - $sql='SELECT m.staff_id FROM '.STAFF_TABLE.' m ' - .'WHERE m.dept_id='.db_input($this->getId()) - .' AND m.staff_id IS NOT NULL ' - .'ORDER BY m.lastname, m.firstname'; - if(($res=db_query($sql)) && db_num_rows($res)){ - while(list($id)=db_fetch_row($res)) - if(($staff=Staff::lookup($id)) && $staff->isAvailable()) - $this->members[]= $staff; + function getMembers() { + + if(!$this->members && $this->getNumStaff()) { + $sql='SELECT DISTINCT s.staff_id, s.dept_id FROM '.STAFF_TABLE.' s ' + .' LEFT JOIN '.GROUP_DEPT_TABLE.' g ON(s.group_id=g.group_id) ' + .' INNER JOIN '.DEPT_TABLE.' d ON(d.dept_id=s.dept_id OR d.manager_id=s.staff_id OR d.dept_id=g.dept_id) ' + .' WHERE d.dept_id='.db_input($this->getId()) + .' ORDER BY s.lastname, s.firstname'; + + if(($res=db_query($sql)) && db_num_rows($res)) { + while(list($staffId, $deptId)=db_fetch_row($res)) { + if(!$this->enableGroupMembership() + && $deptId!=$this->getId() + && $staffId!=$this->getManagerId()) continue; + + $this->members[] = Staff::lookup($staffId); + } } } + return $this->members; } + + function getSLAId(){ return $this->ht['sla_id']; } @@ -179,6 +188,11 @@ class Dept { function noreplyAutoResp(){ return ($this->ht['noreply_autoresp']); } + + + function enableGroupMembership() { + return ($this->ht['group_membership']); + } function getHashtable() { return $this->ht; @@ -214,7 +228,8 @@ class Dept { db_query('UPDATE '.STAFF_TABLE.' SET dept_id='.db_input($cfg->getDefaultDeptId()).' WHERE dept_id='.db_input($id)); //make help topic using the dept default to default-dept. db_query('UPDATE '.TOPIC_TABLE.' SET dept_id='.db_input($cfg->getDefaultDeptId()).' WHERE dept_id='.db_input($id)); - + //Delete group access + db_query('DELETE FROM '.GROUP_DEPT_TABLE.' WHERE dept_id='.db_input($id)); } return $num; @@ -305,6 +320,7 @@ class Dept { .' ,manager_id='.db_input($vars['manager_id']?$vars['manager_id']:0) .' ,dept_name='.db_input(Format::striptags($vars['name'])) .' ,dept_signature='.db_input(Format::striptags($vars['signature'])) + .' ,group_membership='.db_input(isset($vars['group_membership'])?1:0) .' ,ticket_auto_response='.db_input(isset($vars['ticket_auto_response'])?$vars['ticket_auto_response']:1) .' ,message_auto_response='.db_input(isset($vars['message_auto_response'])?$vars['message_auto_response']:1); diff --git a/include/class.group.php b/include/class.group.php index 1b21dce29e4511b469c8dfb70386e7e940626d48..e53cb8538f57edbdb78548c52bfc8cb75e8c7626 100644 --- a/include/class.group.php +++ b/include/class.group.php @@ -19,13 +19,19 @@ class Group { var $id; var $ht; + var $members; + var $departments; + function Group($id){ $this->id=0; return $this->load($id); } - function load($id){ + function load($id=0) { + + if(!$id && !($id=$this->getId())) + return false; $sql='SELECT grp.*,grp.group_name as name, grp.group_enabled as isactive, count(staff.staff_id) as users ' .'FROM '.GROUP_TABLE.' grp ' @@ -37,12 +43,13 @@ class Group { $this->ht=db_fetch_array($res); $this->id=$this->ht['group_id']; $this->members=array(); + $this->departments = array(); return $this->id; } function reload(){ - return $this->load($this->getId()); + return $this->load(); } function getHashtable() { @@ -73,17 +80,85 @@ class Group { function isActive(){ return $this->isEnabled(); } + + //Get members of the group. + function getMembers() { + + if(!$this->members && $this->getNumUsers()) { + $sql='SELECT staff_id FROM '.STAFF_TABLE + .' WHERE group_id='.db_input($this->getId()).' AND staff_id IS NOT NULL ' + .' ORDER BY lastname, firstname'; + if(($res=db_query($sql)) && db_num_rows($res)) { + while(list($id)=db_fetch_row($res)) + if(($staff=Staff::lookup($id))) + $this->members[]= $staff; + } + } + return $this->members; + } + //Get departments the group is allowed to access. + function getDepartments() { - function update($vars,&$errors) { + if(!$this->departments) { + $sql='SELECT dept_id FROM '.GROUP_DEPT_TABLE + .' WHERE group_id='.db_input($this->getId()); + if(($res=db_query($sql)) && db_num_rows($res)) { + while(list($id)=db_fetch_row($res)) + $this->departments[]= $id; + } + } - if(Group::save($this->getId(),$vars,$errors)){ - $this->reload(); - return true; + return $this->departments; + } + + + function updateDeptAccess($depts) { + + if($depts) { + foreach($depts as $k=>$id) { + $sql='INSERT IGNORE INTO '.GROUP_DEPT_TABLE + .' SET group_id='.db_input($this->getId()) + .', dept_id='.db_input($id); + db_query($sql); + } } - return false; + $sql='DELETE FROM '.GROUP_DEPT_TABLE.' WHERE group_id='.db_input($this->getId()); + if($depts) // just inserted departments IF any. + $sql.=' AND dept_id NOT IN('.implode(',', db_input($depts)).')'; + + db_query($sql); + + return true; + } + + function update($vars,&$errors) { + + if(!Group::save($this->getId(),$vars,$errors)) + return false; + + $this->updateDeptAccess($vars['depts']); + $this->reload(); + + return true; + } + + function delete() { + + //Can't delete with members + if($this->getNumUsers()) + return false; + + $res = db_query('DELETE FROM '.GROUP_TABLE.' WHERE group_id='.db_input($this->getId()).' LIMIT 1'); + if(!$res || !db_affected_rows($res)) + return false; + + //Remove dept access entry. + db_query('DELETE FROM '.GROUP_DEPT_TABLE.' WHERE group_id='.db_input($this->getId())); + + return true; } /*** Static functions ***/ @@ -99,9 +174,11 @@ class Group { return ($id && is_numeric($id) && ($g= new Group($id)) && $g->getId()==$id)?$g:null; } + function create($vars, &$errors) { + if(($id=self::save(0,$vars,$errors)) && ($group=self::lookup($id))) + $group->updateDeptAccess($vars['depts']); - function create($vars,&$errors) { - return self::save(0,$vars,$errors); + return $id; } function save($id,$vars,&$errors) { @@ -119,19 +196,19 @@ class Group { if($errors) return false; - $sql=' SET updated=NOW(), group_name='.db_input(Format::striptags($vars['name'])). - ', group_enabled='.db_input($vars['isactive']). - ', dept_access='.db_input($vars['depts']?implode(',',$vars['depts']):''). - ', can_create_tickets='.db_input($vars['can_create_tickets']). - ', can_delete_tickets='.db_input($vars['can_delete_tickets']). - ', can_edit_tickets='.db_input($vars['can_edit_tickets']). - ', can_assign_tickets='.db_input($vars['can_assign_tickets']). - ', can_transfer_tickets='.db_input($vars['can_transfer_tickets']). - ', can_close_tickets='.db_input($vars['can_close_tickets']). - ', can_ban_emails='.db_input($vars['can_ban_emails']). - ', can_manage_premade='.db_input($vars['can_manage_premade']). - ', can_manage_faq='.db_input($vars['can_manage_faq']). - ', notes='.db_input($vars['notes']); + $sql=' SET updated=NOW() ' + .', group_name='.db_input(Format::striptags($vars['name'])) + .', group_enabled='.db_input($vars['isactive']) + .', can_create_tickets='.db_input($vars['can_create_tickets']) + .', can_delete_tickets='.db_input($vars['can_delete_tickets']) + .', can_edit_tickets='.db_input($vars['can_edit_tickets']) + .', can_assign_tickets='.db_input($vars['can_assign_tickets']) + .', can_transfer_tickets='.db_input($vars['can_transfer_tickets']) + .', can_close_tickets='.db_input($vars['can_close_tickets']) + .', can_ban_emails='.db_input($vars['can_ban_emails']) + .', can_manage_premade='.db_input($vars['can_manage_premade']) + .', can_manage_faq='.db_input($vars['can_manage_faq']) + .', notes='.db_input($vars['notes']); if($id) { diff --git a/include/class.staff.php b/include/class.staff.php index 6e163266dffda7f5f1b610ba0ef6556bfee7b1b4..669a41836511274b39889a8368962bdba2331e69 100644 --- a/include/class.staff.php +++ b/include/class.staff.php @@ -25,6 +25,8 @@ class Staff { var $id; var $dept; + var $departments; + var $group; var $teams; var $timezone; var $stats; @@ -51,8 +53,9 @@ class Staff { $this->ht=db_fetch_array($res); $this->id = $this->ht['staff_id']; - $this->teams = $this->ht['teams']= array(); - $this->stats=array(); + $this->teams = $this->ht['teams'] = array(); + $this->group = $this->dept = null; + $this->departments = $this->stats = array(); //WE have to patch info here to support upgrading from old versions. if(($time=strtotime($this->ht['passwdreset']?$this->ht['passwdreset']:$this->ht['added']))) @@ -154,10 +157,6 @@ class Staff { return $this->ht['lastname']; } - function getGroupId() { - return $this->ht['group_id']; - } - function getSignature() { return $this->ht['signature']; } @@ -174,13 +173,46 @@ class Staff { return ($this->ht['change_passwd']); } + function getDepartments() { + + if($this->departments) + return $this->departments; + + //Departments the staff is "allowed" to access... + // based on the group they belong to + user's primary dept + user's managed depts. + $sql='SELECT DISTINCT d.dept_id FROM '.STAFF_TABLE.' s ' + .' LEFT JOIN '.GROUP_DEPT_TABLE.' g ON(s.group_id=g.group_id) ' + .' INNER JOIN '.DEPT_TABLE.' d ON(d.dept_id=s.dept_id OR d.manager_id=s.staff_id OR d.dept_id=g.dept_id) ' + .' WHERE s.staff_id='.db_input($this->getId()); + + $depts = array(); + if(($res=db_query($sql)) && db_num_rows($res)) { + while(list($id)=db_fetch_row($res)) + $depts[] = $id; + } else { //Neptune help us! (fallback) + $depts = array_merge($this->getGroup()->getDepartments(), array($this->getDeptId())); + } + + $this->departments = array_filter(array_unique($depts)); + + + return $this->departments; + } + function getDepts() { - //Departments the user is allowed to access...based on the group they belong to + user's dept. - return array_filter(array_unique(array_merge(explode(',', $this->ht['dept_access']), array($this->getDeptId())))); //Neptune help us + return $this->getDepartments(); + } + + function getGroupId() { + return $this->ht['group_id']; } - function getDepartments() { - return $this->getDepts(); + function getGroup() { + + if(!$this->group && $this->getGroupId()) + $this->group = Group::lookup($this->getGroupId()); + + return $this->group; } function getDeptId() { diff --git a/include/class.ticket.php b/include/class.ticket.php index 0d9a8ced06a145b71f218af47be20c58fbfa27a1..c5460953e136c8c2472c14c8497ba7e53dd365c4 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -866,7 +866,7 @@ class Ticket{ //Only alerts dept members if the ticket is NOT assigned. if($cfg->alertDeptMembersONNewTicket() && !$this->isAssigned()) { - if(($members=$dept->getAvailableMembers())) + if(($members=$dept->getMembers())) $recipients=array_merge($recipients, $members); } @@ -877,6 +877,7 @@ class Ticket{ if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue; $alert = str_replace("%staff",$staff->getFirstName(),$body); $email->send($staff->getEmail(),$subj,$alert); + $sentlist[] = $staff->getEmail(); } @@ -1029,8 +1030,8 @@ class Ticket{ if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue; $alert = str_replace('%staff', $staff->getFirstName(), $body); $email->send($staff->getEmail(), $subj, $alert); + $sentlist[] = $staff->getEmail(); } - print_r($sentlist); } return true; @@ -1072,7 +1073,7 @@ class Ticket{ $recipients=array_merge($recipients, $members); } elseif($cfg->alertDeptMembersONOverdueTicket() && !$this->isAssigned()) { //Only alerts dept members if the ticket is NOT assigned. - if(($members=$dept->getAvailableMembers())) + if(($members=$dept->getMembers())) $recipients=array_merge($recipients, $members); } //Always alert dept manager?? @@ -1084,6 +1085,7 @@ class Ticket{ if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue; $alert = str_replace("%staff",$staff->getFirstName(),$body); $email->send($staff->getEmail(),$subj,$alert); + $sentlist[] = $staff->getEmail(); } } @@ -1200,7 +1202,7 @@ class Ticket{ $recipients+=$members; } elseif($cfg->alertDeptMembersONTransfer() && !$this->isAssigned()) { //Only alerts dept members if the ticket is NOT assigned. - if(($members=$dept->getAvailableMembers())) + if(($members=$dept->getMembers())) $recipients+=$members; } @@ -1213,6 +1215,7 @@ class Ticket{ if(!is_object($staff) || !$staff->isAvailable() || in_array($staff->getEmail(),$sentlist)) continue; $alert = str_replace("%staff",$staff->getFirstName(),$body); $email->send($staff->getEmail(),$subj,$alert); + $sentlist[] = $staff->getEmail(); } } @@ -1361,7 +1364,7 @@ class Ticket{ if(!$staff || !$staff->getEmail() || !$staff->isAvailable() && in_array($staff->getEmail(),$sentlist)) continue; $alert = str_replace("%staff",$staff->getFirstName(),$body); $email->send($staff->getEmail(),$subj,$alert); - $sentlist[]=$staff->getEmail(); + $sentlist[] = $staff->getEmail(); } } @@ -1544,7 +1547,7 @@ class Ticket{ if(in_array($staff->getEmail(),$sentlist) || ($thisstaff && $thisstaff->getId()==$staff->getId())) continue; $alert = str_replace('%staff',$staff->getFirstName(),$body); $email->send($staff->getEmail(),$subj,$alert); - $sentlist[]=$staff->getEmail(); + $sentlist[] = $staff->getEmail(); } } diff --git a/include/class.upgrader.php b/include/class.upgrader.php index 4487e53b26844c8094b72406c5f739cb67702bf3..054377b1945d86a3c8911adfa7ac293ef2fc66d7 100644 --- a/include/class.upgrader.php +++ b/include/class.upgrader.php @@ -275,17 +275,21 @@ class Upgrader extends SetupWizard { 'desc' => 'Transitioning to db-backed sessions'); break; case '98ae1ed2-e342f869': //v1.6 RC1-4 -> v1.6 RC5 - $task[] = array('func' => 'migrateAPIKeys', - 'desc' => 'Migrating API keys to a new table'); + $tasks[] = array('func' => 'migrateAPIKeys', + 'desc' => 'Migrating API keys to a new table'); + break; + case '435c62c3-5499e513': + $tasks[] = array('func' => 'migrateGroupDeptAccess', + 'desc' => 'Migrating group\'s department access to a new table'); break; } - //Check IF SQL cleanup is exists. + //Check IF SQL cleanup exists. $file=$this->getSQLDir().$phash.'.cleanup.sql'; if(file_exists($file)) - $tasks[] = array('func' => 'cleanup', 'desc' => 'Post-upgrade cleanup!', - 'phash' => $phash); - + $tasks[] = array('func' => 'cleanup', + 'desc' => 'Post-upgrade cleanup!', + 'phash' => $phash); return $tasks; } @@ -336,7 +340,7 @@ class Upgrader extends SetupWizard { list($whitelist, $key) = db_fetch_row($res); - $ips=array_filter(explode(',', ereg_replace(' ', '', $whitelist))); + $ips=array_filter(array_map('trim', explode(',', $whitelist))); foreach($ips as $ip) { $sql='INSERT INTO '.API_KEY_TABLE.' SET created=NOW(), updated=NOW(), isactive=1 ' .',ipaddr='.db_input($ip) @@ -346,5 +350,26 @@ class Upgrader extends SetupWizard { return 0; } + + function migrateGroupDeptAccess($taskId) { + + $res = db_query('SELECT group_id, dept_access FROM '.GROUP_TABLE); + if(!$res || !db_num_rows($res)) + return 0; //No groups?? + + while(list($groupId, $access) = db_fetch_row($res)) { + $depts=array_filter(array_map('trim', explode(',', $access))); + foreach($depts as $deptId) { + $sql='INSERT INTO '.GROUP_DEPT_TABLE + .' SET dept_id='.db_input($deptId).', group_id='.db_input($groupId); + db_query($sql); + } + } + + return 0; + + + + } } ?> diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php index 521cee9bf9e9eb7446420c26c4e0ab03a1c3ad69..a41c271b12a43d3bc046c87ae6ec84f27a4cb266 100644 --- a/include/staff/department.inc.php +++ b/include/staff/department.inc.php @@ -2,7 +2,7 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied'); $info=array(); $qstr=''; -if($dept && $_REQUEST['a']!='add'){ +if($dept && $_REQUEST['a']!='add') { //Editing Department. $title='Update Department'; $action='update'; @@ -10,7 +10,7 @@ if($dept && $_REQUEST['a']!='add'){ $info=$dept->getInfo(); $info['id']=$dept->getId(); $qstr.='&id='.$dept->getId(); -}else { +} else { $title='Add New Department'; $action='create'; $submit_text='Create Dept'; @@ -128,8 +128,9 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <option value="0">— None —</option> <option value="0" disabled="disabled">Select Department Manager (Optional)</option> <?php - $sql='SELECT staff_id,CONCAT_WS(" ",firstname,lastname) as name FROM '.STAFF_TABLE.' staff '. - 'WHERE dept_id='.db_input($dept->getId()).' ORDER by name'; + $sql='SELECT staff_id,CONCAT_WS(", ",lastname, firstname) as name ' + .' FROM '.STAFF_TABLE.' staff ' + .' ORDER by name'; if(($res=db_query($sql)) && db_num_rows($res)){ while(list($id,$name)=db_fetch_row($res)){ $selected=($info['manager_id'] && $id==$info['manager_id'])?'selected="selected"':''; @@ -141,7 +142,18 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <span class="error"> <?php echo $errors['manager_id']; ?></span> </td> </tr> - <?php } ?> + <?php + } ?> + + <tr> + <td width="180"> + Group Membership: + </td> + <td> + <input type="checkbox" name="group_membership" value="0" <?php echo $info['group_membership']?'checked="checked"':''; ?> > + Extend membership to groups with access. <i>(Alerts and notices will include groups)</i> + </td> + </tr> <tr> <th colspan="2"> <em><strong>Auto Response Settings</strong>: Overwrite global auto-response settings for tickets routed to the Dept.</em> @@ -197,7 +209,7 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <tr> <td colspan=2> <textarea name="signature" cols="21" rows="5" style="width: 60%;"><?php echo $info['signature']; ?></textarea> - <br><em>Signature is made available as a choice, on ticket reply, for public departments.</em> + <br><em>Signature is made available as a choice, for public departments, on ticket reply.</em> </td> </tr> </tbody> diff --git a/include/staff/group.inc.php b/include/staff/group.inc.php index afb574f5f3cea7ff161dc34e90c05fa77f955b51..83220475de4bf388cd2368774a9cccaba1022896 100644 --- a/include/staff/group.inc.php +++ b/include/staff/group.inc.php @@ -8,7 +8,7 @@ if($group && $_REQUEST['a']!='add'){ $submit_text='Save Changes'; $info=$group->getInfo(); $info['id']=$group->getId(); - $info['depts']=$info['dept_access']?explode(',',$info['dept_access']):array(); + $info['depts']=$group->getDepartments(); $qstr.='&id='.$group->getId(); }else { $title='Add New Group'; diff --git a/include/staff/tickets.inc.php b/include/staff/tickets.inc.php index 63f2fb31c4a871f60ca13d3fff0f66e5a2c11ae9..8397a4988d504f7394afa6a6ba0a05da7584eb16 100644 --- a/include/staff/tickets.inc.php +++ b/include/staff/tickets.inc.php @@ -63,6 +63,7 @@ $qwhere =''; $depts=$thisstaff->getDepts(); $qwhere =' WHERE ( ' .' ticket.staff_id='.db_input($thisstaff->getId()); + if(!$thisstaff->showAssignedOnly()) $qwhere.=' OR ticket.dept_id IN ('.($depts?implode(',',$depts):0).')'; diff --git a/scp/groups.php b/scp/groups.php index 7a4f959169160f6f41f0ebce70db6c6ced266695..4a0b9f157960398ddb9bfc8683629af39a83d3a6 100644 --- a/scp/groups.php +++ b/scp/groups.php @@ -64,7 +64,7 @@ if($_POST){ } }elseif($_POST['delete']){ foreach($_POST['ids'] as $k=>$v) { - if(($t=Group::lookup($v)) && $t->delete()) + if(($g=Group::lookup($v)) && $g->delete()) $i++; }