diff --git a/include/class.dept.php b/include/class.dept.php index 5a2babdd3da4021a7b81c736a79210fdf11f1d97..00609db105ccd781491997e61e5eb302aadfbfae 100644 --- a/include/class.dept.php +++ b/include/class.dept.php @@ -19,6 +19,9 @@ class Dept { var $email; var $sla; var $manager; + var $members; + var $groups; + var $ht; function Dept($id){ @@ -47,7 +50,7 @@ class Dept { $this->id=$this->ht['dept_id']; $this->email=$this->sla=$this->manager=null; $this->getEmail(); //Auto load email struct. - $this->members=array(); + $this->members=$this->groups=array(); return true; } @@ -89,22 +92,30 @@ class Dept { return $this->getNumStaff(); } - function getAvailableMembers(){ + function getMembers() { - 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; + 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 +190,11 @@ class Dept { function noreplyAutoResp(){ return ($this->ht['noreply_autoresp']); } + + + function enableGroupMembership() { + return ($this->ht['group_membership']); + } function getHashtable() { return $this->ht; @@ -188,14 +204,53 @@ class Dept { return $this->getHashtable(); } - function update($vars,&$errors){ - if($this->save($this->getId(),$vars,$errors)) { - $this->reload(); - return true; + + function getAllowedGroups() { + + if($this->groups) return $this->groups; + + $sql='SELECT group_id FROM '.GROUP_DEPT_TABLE + .' WHERE dept_id='.db_input($this->getId()); + + if(($res=db_query($sql)) && db_num_rows($res)) { + while(list($id)=db_fetch_row($res)) + $this->groups[] = $id; } - return false; + return $this->groups; + } + + function updateAllowedGroups($groups) { + + if($groups) { + foreach($groups as $k=>$id) { + $sql='INSERT IGNORE INTO '.GROUP_DEPT_TABLE + .' SET dept_id='.db_input($this->getId()).', group_id='.db_input($id); + db_query($sql); + } + } + + + $sql='DELETE FROM '.GROUP_DEPT_TABLE.' WHERE dept_id='.db_input($this->getId()); + if($groups) + $sql.=' AND group_id NOT IN('.implode(',', db_input($groups)).')'; + + db_query($sql); + + return true; + + } + + function update($vars,&$errors){ + + if(!$this->save($this->getId(),$vars,$errors)) + return false; + + $this->updateAllowedGroups($vars['groups']); + $this->reload(); + + return true; } function delete() { @@ -214,7 +269,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; @@ -267,7 +323,10 @@ class Dept { } function create($vars,&$errors) { - return Dept::save(0,$vars,$errors); + if(($id=self::save(0, $vars, $errors)) && ($dept=self::lookup($id))) + $dept->updateAllowedGroups($vars['groups']); + + return $id; } function save($id,$vars,&$errors) { @@ -305,6 +364,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 b95329fa69c3191c69fdc65006785fc420ff2ed0..b607f6eac145aa7e7c13547218d936f7662ceb8a 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 7e53ec51bd10247932fbd6e416e4afed1939deee..683ab25c46e69e83e0150baee01c329e90c5f7e4 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..c886bb0ab927f2e59e1dd656b7e593b6f4ae490b 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-6007d45b': + $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/mysql.php b/include/mysql.php index 06489242a71d78d7e8fae590ed8960ddfa74dee8..65adb6298a632ebe0d8c0a127d2c0af8982bf546 100644 --- a/include/mysql.php +++ b/include/mysql.php @@ -38,12 +38,12 @@ return $dblink; } - function db_close(){ + function db_close() { global $dblink; return @mysql_close($dblink); } - function db_version(){ + function db_version() { $version=0; if(preg_match('/(\d{1,2}\.\d{1,2}\.\d{1,2})/', @@ -59,7 +59,7 @@ } function db_get_variable($variable, $type='session') { - $sql =sprintf('SELECT @@%s.%s',$type,$variable); + $sql =sprintf('SELECT @@%s.%s', $type, $variable); return db_result(db_query($sql)); } @@ -74,112 +74,105 @@ } function db_create_database($database, $charset='utf8', $collate='utf8_unicode_ci') { - return @mysql_query(sprintf('CREATE DATABASE %s DEFAULT CHARACTER SET %s COLLATE %s',$database,$charset,$collate)); + return @mysql_query(sprintf('CREATE DATABASE %s DEFAULT CHARACTER SET %s COLLATE %s', $database, $charset, $collate)); } // execute sql query - function db_query($query, $database="", $conn=""){ + function db_query($query, $database="", $conn="") { global $ost; if($conn) { /* connection is provided*/ - $result = ($database)?mysql_db_query($database, $query, $conn):mysql_query($query, $conn); + $res = ($database)?mysql_db_query($database, $query, $conn):mysql_query($query, $conn); } else { - $result = ($database)?mysql_db_query($database, $query):mysql_query($query); + $res = ($database)?mysql_db_query($database, $query):mysql_query($query); } - if(!$result && $ost) { //error reporting + if(!$res && $ost) { //error reporting $msg='['.$query.']'."\n\n".db_error(); $ost->logDBError('DB Error #'.db_errno(), $msg); //echo $msg; #uncomment during debuging or dev. } - return $result; + return $res; } - function db_squery($query){ //smart db query...utilizing args and sprintf + function db_squery($query) { //smart db query...utilizing args and sprintf $args = func_get_args(); $query = array_shift($args); $query = str_replace("?", "%s", $query); $args = array_map('db_real_escape', $args); - array_unshift($args,$query); - $query = call_user_func_array('sprintf',$args); + array_unshift($args, $query); + $query = call_user_func_array('sprintf', $args); return db_query($query); } - function db_count($query){ + function db_count($query) { return db_result(db_query($query)); } - function db_result($result,$row=0) { - return ($result)?mysql_result($result,$row):NULL; + function db_result($res, $row=0) { + return ($res)?mysql_result($res, $row):NULL; } - function db_fetch_array($result,$mode=false) { - return ($result)?db_output(mysql_fetch_array($result,($mode)?$mode:MYSQL_ASSOC)):NULL; + function db_fetch_array($res, $mode=false) { + return ($res)?db_output(mysql_fetch_array($res, ($mode)?$mode:MYSQL_ASSOC)):NULL; } - function db_fetch_row($result) { - return ($result)?db_output(mysql_fetch_row($result)):NULL; + function db_fetch_row($res) { + return ($res)?db_output(mysql_fetch_row($res)):NULL; } - function db_fetch_field($result) { - return ($result)?mysql_fetch_field($result):NULL; + function db_fetch_field($res) { + return ($res)?mysql_fetch_field($res):NULL; } - function db_assoc_array($result,$mode=false) { - if($result && db_num_rows($result)) { - while ($row=db_fetch_array($result,$mode)) - $results[]=$row; + function db_assoc_array($res, $mode=false) { + if($res && db_num_rows($res)) { + while ($row=db_fetch_array($res, $mode)) + $result[]=$row; } - return $results; + return $result; } - function db_num_rows($result) { - return ($result)?mysql_num_rows($result):0; + function db_num_rows($res) { + return ($res)?mysql_num_rows($res):0; } function db_affected_rows() { return mysql_affected_rows(); } - function db_data_seek($result, $row_number) { - return mysql_data_seek($result, $row_number); + function db_data_seek($res, $row_number) { + return mysql_data_seek($res, $row_number); } - function db_data_reset($result) { - return mysql_data_seek($result,0); + function db_data_reset($res) { + return mysql_data_seek($res,0); } function db_insert_id() { return mysql_insert_id(); } - function db_free_result($result) { - return mysql_free_result($result); + function db_free_result($res) { + return mysql_free_result($res); } - function db_output($param) { + function db_output($var) { if(!function_exists('get_magic_quotes_runtime') || !get_magic_quotes_runtime()) //Sucker is NOT on - thanks. - return $param; + return $var; - if (is_array($param)) { - reset($param); - while(list($key, $value) = each($param)) - $param[$key] = db_output($value); + if (is_array($var)) + return array_map('db_output', $var); - return $param; + return (!is_numeric($var))?stripslashes($var):$var; - }elseif(!is_numeric($param)) { - $param=trim(stripslashes($param)); - } - - return $param; - } + } //Do not call this function directly...use db_input - function db_real_escape($val,$quote=false){ + function db_real_escape($val, $quote=false) { //Magic quotes crap is taken care of in main.inc.php $val=mysql_real_escape_string($val); @@ -187,29 +180,21 @@ return ($quote)?"'$val'":$val; } - function db_input($param,$quote=true) { - - //is_numeric doesn't work all the time...9e8 is considered numeric..which is correct...but not expected. - if($param && preg_match("/^\d+(\.\d+)?$/",$param)) - return $param; + function db_input($var, $quote=true) { - if($param && is_array($param)) { - reset($param); - while (list($key, $value) = each($param)) { - $param[$key] = db_input($value,$quote); - } - - return $param; - } + if(is_array($var)) + return array_map('db_input', $var, array_fill(0, count($var), $quote)); + elseif($var && preg_match("/^\d+(\.\d+)?$/", $var)) + return $var; - return db_real_escape($param,$quote); + return db_real_escape($var, $quote); } - function db_error(){ + function db_error() { return mysql_error(); } - function db_errno(){ + function db_errno() { return mysql_errno(); } ?> diff --git a/include/staff/department.inc.php b/include/staff/department.inc.php index 943bfc90bd08d5a46632bcf5b62034e2bbf7ac91..2c1ff86ca75f3b6467e44fa3b86fe98652a808e7 100644 --- a/include/staff/department.inc.php +++ b/include/staff/department.inc.php @@ -2,15 +2,17 @@ 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'; $submit_text='Save Changes'; $info=$dept->getInfo(); $info['id']=$dept->getId(); + $info['groups'] = $dept->getAllowedGroups(); + $qstr.='&id='.$dept->getId(); -}else { +} else { $title='Add New Department'; $action='create'; $submit_text='Create Dept'; @@ -129,8 +131,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"':''; @@ -142,7 +145,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> @@ -190,6 +204,29 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info); <span class="error"> <?php echo $errors['autoresp_email_id']; ?></span> </td> </tr> + <tr> + <th colspan="2"> + <em><strong>Department Access</strong>: Check all groups allowed to access department.</em> + </th> + </tr> + <tr><td colspan=2><em>Primary department members and manager will always have access regarless of group selection or assignment.</em></td></tr> + <?php + $sql='SELECT group_id, group_name, count(staff.staff_id) as members ' + .' FROM '.GROUP_TABLE.' grp ' + .' LEFT JOIN '.STAFF_TABLE. ' staff USING(group_id) ' + .' GROUP by grp.group_id ' + .' ORDER BY group_name'; + if(($res=db_query($sql)) && db_num_rows($res)){ + while(list($id, $name, $members) = db_fetch_row($res)) { + if($members>0) + $members=sprintf('<a href="staff.php?a=filter&gid=%d">%d</a>', $id, $members); + + $ck=($info['groups'] && in_array($id,$info['groups']))?'checked="checked"':''; + echo sprintf('<tr><td colspan=2> <label><input type="checkbox" name="groups[]" value="%d" %s> %s</label> (%s)</td></tr>', + $id, $ck, $name, $members); + } + } + ?> <tr> <th colspan="2"> <em><strong>Department Signature</strong>: Optional signature used on outgoing emails. <span class="error"> <?php echo $errors['signature']; ?></span></em> @@ -198,7 +235,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 8e2e992430fee1bbb0f373a034a478efba2e44a8..a442c3ce02e91c249636d4c762cd9a9ed54b6c89 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/groups.inc.php b/include/staff/groups.inc.php index 95745e70cd98defcd512cc8c20d97daab56dc591..ccb16257bf74660ae43d4a6abad2013984323221 100644 --- a/include/staff/groups.inc.php +++ b/include/staff/groups.inc.php @@ -3,10 +3,13 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access $qstr=''; -$sql='SELECT grp.*,count(staff.staff_id) as users ' - .' FROM '.GROUP_TABLE.' grp LEFT JOIN '.STAFF_TABLE.' staff USING(group_id) '; -$sql.=' WHERE 1'; -$sortOptions=array('name'=>'grp.group_name','status'=>'grp.group_enabled','users'=>'users','created'=>'grp.created','updated'=>'grp.updated'); +$sql='SELECT grp.*,count(staff.staff_id) as users, count(dept.dept_id) as depts ' + .' FROM '.GROUP_TABLE.' grp ' + .' LEFT JOIN '.STAFF_TABLE.' staff ON(staff.group_id=grp.group_id) ' + .' LEFT JOIN '.GROUP_DEPT_TABLE.' dept ON(dept.group_id=grp.group_id) ' + .' WHERE 1'; +$sortOptions=array('name'=>'grp.group_name','status'=>'grp.group_enabled', + 'users'=>'users', 'depts'=>'depts', 'created'=>'grp.created','updated'=>'grp.updated'); $orderWays=array('DESC'=>'DESC','ASC'=>'ASC'); $sort=($_REQUEST['sort'] && $sortOptions[strtolower($_REQUEST['sort'])])?strtolower($_REQUEST['sort']):'name'; //Sorting options... @@ -50,9 +53,10 @@ else <thead> <tr> <th width="7px"> </th> - <th width="250"><a <?php echo $name_sort; ?> href="groups.php?<?php echo $qstr; ?>&sort=name">Group Name</a></th> - <th width="80"><a <?php echo $status_sort; ?> href="groups.php?<?php echo $qstr; ?>&sort=status">Group Status</a></th> + <th width="200"><a <?php echo $name_sort; ?> href="groups.php?<?php echo $qstr; ?>&sort=name">Group Name</a></th> + <th width="80"><a <?php echo $status_sort; ?> href="groups.php?<?php echo $qstr; ?>&sort=status">Status</a></th> <th width="80" style="text-align:center;"><a <?php echo $users_sort; ?>href="groups.php?<?php echo $qstr; ?>&sort=users">Members</a></th> + <th width="80" style="text-align:center;"><a <?php echo $depts_sort; ?>href="groups.php?<?php echo $qstr; ?>&sort=depts">Departments</a></th> <th width="100"><a <?php echo $created_sort; ?> href="groups.php?<?php echo $qstr; ?>&sort=created">Created On</a></th> <th width="120"><a <?php echo $updated_sort; ?> href="groups.php?<?php echo $qstr; ?>&sort=updated">Last Updated</a></th> </tr> @@ -82,6 +86,9 @@ else <?php } ?> </td> + <td style="text-align:right;padding-right:30px"> + <?php echo $row['depts']; ?> + </td> <td><?php echo Format::db_date($row['created']); ?> </td> <td><?php echo Format::db_datetime($row['updated']); ?> </td> </tr> 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/include/upgrader/done.inc.php b/include/upgrader/done.inc.php index ddd5cab75e09b7d5c654b41284860038d5d6387b..f4a55538991d4b8fd6f6814bcb7f08c31e390b7f 100644 --- a/include/upgrader/done.inc.php +++ b/include/upgrader/done.inc.php @@ -1,5 +1,7 @@ <?php if(!defined('OSTSCPINC') || !$thisstaff || !$thisstaff->isAdmin()) die('Access Denied'); +//Destroy the upgrader - we're done! +$_SESSION['ost_upgrader']=null; ?> <div id="upgrader"> <div id="main"> diff --git a/include/upgrader/patches/435c62c3-6007d45b.cleanup.sql b/include/upgrader/patches/435c62c3-6007d45b.cleanup.sql new file mode 100644 index 0000000000000000000000000000000000000000..75192e141510d052fda52b338170ea7b8bc52e4c --- /dev/null +++ b/include/upgrader/patches/435c62c3-6007d45b.cleanup.sql @@ -0,0 +1 @@ +ALTER TABLE `%TABLE_PREFIX%groups` DROP `dept_access`; diff --git a/include/upgrader/patches/435c62c3-6007d45b.patch.sql b/include/upgrader/patches/435c62c3-6007d45b.patch.sql new file mode 100644 index 0000000000000000000000000000000000000000..a973c9b25b2bdaa343997df09f5ac3914f0fb64b --- /dev/null +++ b/include/upgrader/patches/435c62c3-6007d45b.patch.sql @@ -0,0 +1,30 @@ +/** + * Move dept_access from group table to group_dept_access table. + * + * @version 1.7-rc1 Dept_Access + */ + +-- Group department access table +CREATE TABLE `%TABLE_PREFIX%group_dept_access` ( + `group_id` int(10) unsigned NOT NULL default '0', + `dept_id` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`group_id`,`dept_id`) +) ENGINE=MyISAM; + +-- Extend membership to groups +ALTER TABLE `%TABLE_PREFIX%department` + ADD `group_membership` tinyint( 1 ) unsigned NOT NULL DEFAULT '0' AFTER `ispublic`; + +-- Fix teams dates... +UPDATE `%TABLE_PREFIX%team` + SET `created`=IF(TO_DAYS(`created`), `created`, IF(TO_DAYS(`updated`), `updated`, NOW())), + `updated`=IF(TO_DAYS(`updated`), `updated`, NOW()); + +-- Fix groups dates... +UPDATE `%TABLE_PREFIX%groups` + SET `created`=IF(TO_DAYS(`created`), `created`, IF(TO_DAYS(`updated`), `updated`, NOW())), + `updated`=IF(TO_DAYS(`updated`), `updated`, NOW()); + +-- Finished with patch +UPDATE `%TABLE_PREFIX%config` + SET `schema_signature`='6007d45b580c6ac0206514dbed0f28a6'; diff --git a/main.inc.php b/main.inc.php index 1de9c91a3185d6a740cf9832069be71c0a29a805..fb720f7cc1bf49710229d7bd0075d9571091c18d 100644 --- a/main.inc.php +++ b/main.inc.php @@ -63,7 +63,7 @@ #Current version && schema signature (Changes from version to version) define('THIS_VERSION','1.7-DPR4'); //Shown on admin panel - define('SCHEMA_SIGNATURE','435c62c3b23795529bcfae7e7371d82e'); //MD5 signature of the db schema. (used to trigger upgrades) + define('SCHEMA_SIGNATURE','6007d45b580c6ac0206514dbed0f28a6'); //MD5 signature of the db schema. (used to trigger upgrades) #load config info $configfile=''; @@ -136,6 +136,7 @@ define('DEPT_TABLE',TABLE_PREFIX.'department'); define('TOPIC_TABLE',TABLE_PREFIX.'help_topic'); define('GROUP_TABLE',TABLE_PREFIX.'groups'); + define('GROUP_DEPT_TABLE', TABLE_PREFIX.'group_dept_access'); define('TEAM_TABLE',TABLE_PREFIX.'team'); define('TEAM_MEMBER_TABLE',TABLE_PREFIX.'team_member'); diff --git a/scp/groups.php b/scp/groups.php index 4deefd48ca056e1a6ed8fab71bfa3fbef221c2f5..aa2ee2d11332ab850207e4941447d2ef477fcc03 100644 --- a/scp/groups.php +++ b/scp/groups.php @@ -66,7 +66,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++; } diff --git a/setup/inc/sql/osticket-v1.7-mysql.sql b/setup/inc/sql/osticket-v1.7-mysql.sql index ed6ea688e34b1e00a2adb0cbebdfe22a02e6f3d1..662d749b16b3825ec20afd866cb516d77fb92b3e 100644 --- a/setup/inc/sql/osticket-v1.7-mysql.sql +++ b/setup/inc/sql/osticket-v1.7-mysql.sql @@ -175,6 +175,7 @@ CREATE TABLE `%TABLE_PREFIX%department` ( `dept_name` varchar(32) NOT NULL default '', `dept_signature` tinytext NOT NULL, `ispublic` tinyint(1) unsigned NOT NULL default '1', + `group_membership` tinyint(1) NOT NULL default '0', `ticket_auto_response` tinyint(1) NOT NULL default '1', `message_auto_response` tinyint(1) NOT NULL default '0', `updated` datetime NOT NULL, @@ -339,7 +340,6 @@ CREATE TABLE `%TABLE_PREFIX%groups` ( `group_id` int(10) unsigned NOT NULL auto_increment, `group_enabled` tinyint(1) unsigned NOT NULL default '1', `group_name` varchar(50) NOT NULL default '', - `dept_access` varchar(255) NOT NULL default '', `can_create_tickets` tinyint(1) unsigned NOT NULL default '1', `can_edit_tickets` tinyint(1) unsigned NOT NULL default '1', `can_delete_tickets` tinyint(1) unsigned NOT NULL default '0', @@ -356,10 +356,20 @@ CREATE TABLE `%TABLE_PREFIX%groups` ( KEY `group_active` (`group_enabled`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -INSERT INTO `%TABLE_PREFIX%groups` (`group_id`, `group_enabled`, `group_name`, `dept_access`, `can_create_tickets`, `can_edit_tickets`, `can_delete_tickets`, `can_close_tickets`, `can_assign_tickets`, `can_transfer_tickets`, `can_ban_emails`, `can_manage_premade`, `can_manage_faq`, `notes`) VALUES - (1, 1, 'Admins', '2,1', 1, 1, 1, 1, 1, 1, 1, 1, 1, 'overlords'), - (2, 1, 'Managers', '2,1', 1, 1, 1, 1, 1, 1, 1, 1, 1, ''), - (3, 1, 'Staff', '2,1', 1, 1, 0, 1, 1, 1, 0, 0, 0, ''); +INSERT INTO `%TABLE_PREFIX%groups` (`group_id`, `group_enabled`, `group_name`, `can_create_tickets`, `can_edit_tickets`, `can_delete_tickets`, `can_close_tickets`, `can_assign_tickets`, `can_transfer_tickets`, `can_ban_emails`, `can_manage_premade`, `can_manage_faq`, `notes`, `created`, `updated`) VALUES + (1, 1, 'Admins', 1, 1, 1, 1, 1, 1, 1, 1, 1, 'overlords', NOW(), NOW()), + (2, 1, 'Managers', 1, 1, 1, 1, 1, 1, 1, 1, 1, '', NOW(), NOW()), + (3, 1, 'Staff', 1, 1, 0, 1, 1, 1, 0, 0, 0, '', NOW(), NOW()); + +DROP TABLE IF EXISTS `%TABLE_PREFIX%group_dept_access`; +CREATE TABLE `%TABLE_PREFIX%group_dept_access` ( + `group_id` int(10) unsigned NOT NULL default '0', + `dept_id` int(10) unsigned NOT NULL default '0', + PRIMARY KEY (`group_id`,`dept_id`) +) ENGINE=MyISAM; + +INSERT INTO `%TABLE_PREFIX%group_dept_access` (`group_id`, `dept_id`) VALUES + (1, 1), (1, 2), (2, 1), (2, 2), (3, 1), (3, 2); DROP TABLE IF EXISTS `%TABLE_PREFIX%help_topic`; CREATE TABLE `%TABLE_PREFIX%help_topic` ( @@ -520,8 +530,8 @@ CREATE TABLE `%TABLE_PREFIX%team` ( KEY `lead_id` (`lead_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -INSERT INTO `%TABLE_PREFIX%team` (`lead_id`, `isenabled`, `noalerts`, `name`, `notes`) - VALUES (0, 1, 0, 'Level I Support', ''); +INSERT INTO `%TABLE_PREFIX%team` (`lead_id`, `isenabled`, `noalerts`, `name`, `notes`, `created`, `updated`) + VALUES (0, 1, 0, 'Level I Support', '', NOW(), NOW()); DROP TABLE IF EXISTS `%TABLE_PREFIX%team_member`; CREATE TABLE `%TABLE_PREFIX%team_member` ( diff --git a/setup/inc/sql/osticket-v1.7-mysql.sql.md5 b/setup/inc/sql/osticket-v1.7-mysql.sql.md5 index c3f03508703f6860c9628810c3b59ef8af0ce864..bb0024a2a154824e26573a2133737345cadb433a 100644 --- a/setup/inc/sql/osticket-v1.7-mysql.sql.md5 +++ b/setup/inc/sql/osticket-v1.7-mysql.sql.md5 @@ -1 +1 @@ -435c62c3b23795529bcfae7e7371d82e +6007d45b580c6ac0206514dbed0f28a6