Skip to content
Snippets Groups Projects
class.staff.php 24.4 KiB
Newer Older
  • Learn to ignore specific revisions
  • Jared Hancock's avatar
    Jared Hancock committed
    <?php
    /*********************************************************************
        class.staff.php
    
        Everything about staff.
    
        Peter Rotich <peter@osticket.com>
    
        Copyright (c)  2006-2013 osTicket
    
    Jared Hancock's avatar
    Jared Hancock committed
        http://www.osticket.com
    
        Released under the GNU General Public License WITHOUT ANY WARRANTY.
        See LICENSE.TXT for details.
    
        vim: expandtab sw=4 ts=4 sts=4:
    **********************************************************************/
    
    include_once(INCLUDE_DIR.'class.ticket.php');
    
    Jared Hancock's avatar
    Jared Hancock committed
    include_once(INCLUDE_DIR.'class.dept.php');
    
    include_once(INCLUDE_DIR.'class.error.php');
    
    Jared Hancock's avatar
    Jared Hancock committed
    include_once(INCLUDE_DIR.'class.team.php');
    include_once(INCLUDE_DIR.'class.group.php');
    include_once(INCLUDE_DIR.'class.passwd.php');
    
    include_once(INCLUDE_DIR.'class.user.php');
    
    Jared Hancock's avatar
    Jared Hancock committed
    include_once(INCLUDE_DIR.'class.auth.php');
    
    Jared Hancock's avatar
    Jared Hancock committed
    class Staff extends VerySimpleModel
    implements AuthenticatedUser {
    
    
        static $meta = array(
            'table' => STAFF_TABLE,
            'pk' => array('staff_id'),
    
    Jared Hancock's avatar
    Jared Hancock committed
            'select_related' => array('group'),
    
            'joins' => array(
                'dept' => array(
                    'constraint' => array('dept_id' => 'Dept.dept_id'),
                ),
    
    Jared Hancock's avatar
    Jared Hancock committed
                'group' => array(
                    'constraint' => array('group_id' => 'Group.group_id'),
                ),
    
    Jared Hancock's avatar
    Jared Hancock committed
                'teams' => array(
    
    Peter Rotich's avatar
    Peter Rotich committed
                    'null' => true,
                    'list' => true,
                    'reverse' => 'TeamMember.staff',
    
    Jared Hancock's avatar
    Jared Hancock committed
                ),
    
    Jared Hancock's avatar
    Jared Hancock committed
        var $authkey;
    
    Peter Rotich's avatar
    Peter Rotich committed
        var $departments;
    
    Jared Hancock's avatar
    Jared Hancock committed
        var $stats = array();
        var $_extra;
    
    Jared Hancock's avatar
    Jared Hancock committed
        var $passwd_change;
    
    Peter Rotich's avatar
    Peter Rotich committed
        var $_teams = null;
    
    Jared Hancock's avatar
    Jared Hancock committed
        function __onload() {
            // WE have to patch info here to support upgrading from old versions.
            if ($time=strtotime($this->passwdreset ?: (isset($this->added) ? $this->added : '')))
                $this->passwd_change = time()-$time; //XXX: check timezone issues.
    
    Peter Rotich's avatar
    Peter Rotich committed
        function __toString() {
            return (string) $this->getName();
        }
    
    
        function asVar() {
    
    Peter Rotich's avatar
    Peter Rotich committed
            return $this->__toString();
    
        function getHashtable() {
    
            $base = $this->ht;
            $base['group'] = $base['group_id'];
            return $base;
    
        function getInfo() {
    
            return $this->getHashtable();
    
        // AuthenticatedUser implementation...
        // TODO: Move to an abstract class that extends Staff
        function getRole() {
            return 'staff';
        }
    
    
        function getAuthBackend() {
            list($authkey, ) = explode(':', $this->getAuthKey());
            return StaffAuthenticationBackend::getBackend($authkey);
    
    Jared Hancock's avatar
    Jared Hancock committed
        function setAuthKey($key) {
            $this->authkey = $key;
        }
    
        function getAuthKey() {
            return $this->authkey;
        }
    
        // logOut the user
        function logOut() {
    
            if ($bk = $this->getAuthBackend())
                return $bk->signOut($this);
    
            return false;
        }
    
    
    Jared Hancock's avatar
    Jared Hancock committed
        /*compares user password*/
    
        function check_passwd($password, $autoupdate=true) {
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            /*bcrypt based password match*/
    
            if(Passwd::cmp($password, $this->getPasswd()))
    
    Jared Hancock's avatar
    Jared Hancock committed
                return true;
    
    
            //Fall back to MD5
            if(!$password || strcmp($this->getPasswd(), MD5($password)))
                return false;
    
            //Password is a MD5 hash: rehash it (if enabled) otherwise force passwd change.
    
    Jared Hancock's avatar
    Jared Hancock committed
            $this->passwd = Passwd::hash($password);
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$autoupdate || !$this->save())
    
    Jared Hancock's avatar
    Jared Hancock committed
                $this->forcePasswdRest();
    
    
        function cmp_passwd($password) {
            return $this->check_passwd($password, false);
    
        function hasPassword() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return (bool) $this->passwd;
    
    Jared Hancock's avatar
    Jared Hancock committed
        function forcePasswdRest() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            $this->change_passwd = 1;
            return $this->update();
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        /* check if passwd reset is due. */
    
        function isPasswdResetDue() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            global $cfg;
    
            return ($cfg && $cfg->getPasswdResetPeriod()
    
    Jared Hancock's avatar
    Jared Hancock committed
                        && $this->passwd_change>($cfg->getPasswdResetPeriod()*30*24*60*60));
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function isPasswdChangeDue() {
            return $this->isPasswdResetDue();
        }
    
    
        function getRefreshRate() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->auto_refresh_rate;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function getPageLimit() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->max_page_size;
    
        function getId() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->staff_id;
    
        function getEmail() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->email;
    
        function getUserName() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->username;
    
        function getPasswd() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->passwd;
    
        function getName() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return new PersonsName($this->firstname.' '.$this->lastname);
    
        function getFirstName() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->firstname;
    
        function getLastName() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->lastname;
    
        function getSignature() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->signature;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function getDefaultSignatureType() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->default_signature_type;
    
        function getDefaultPaperSize() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->default_paper_size;
    
        function forcePasswdChange() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->change_passwd;
    
    Peter Rotich's avatar
    Peter Rotich committed
        function getDepartments() {
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            if (isset($this->departments))
    
    Peter Rotich's avatar
    Peter Rotich committed
                return $this->departments;
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            // Departments the staff is "allowed" to access...
    
    Peter Rotich's avatar
    Peter Rotich committed
            // based on the group they belong to + user's primary dept + user's managed depts.
    
    Jared Hancock's avatar
    Jared Hancock committed
            $dept_ids = array();
            $depts = Dept::objects()
                ->filter(Q::any(array(
                    'dept_id' => $this->dept_id,
                    'groups__group_id' => $this->group_id,
                    'manager_id' => $this->getId(),
                )))
                ->values_flat('dept_id');
    
            foreach ($depts as $row) {
                list($id) = $row;
                $dept_ids[] = $id;
    
    Jared Hancock's avatar
    Jared Hancock committed
            if (!$dept_ids) { //Neptune help us! (fallback)
                $dept_ids = array_merge($this->getGroup()->getDepartments(), array($this->getDeptId()));
            }
            return $this->departments = array_filter(array_unique($dept_ids));
    
        function getDepts() {
    
    Peter Rotich's avatar
    Peter Rotich committed
            return $this->getDepartments();
        }
    
    
        function getManagedDepartments() {
    
            return ($depts=Dept::getDepartments(
                        array('manager' => $this->getId())
                        ))?array_keys($depts):array();
        }
    
    Peter Rotich's avatar
    Peter Rotich committed
        function getGroupId() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group_id;
    
    Peter Rotich's avatar
    Peter Rotich committed
        function getGroup() {
            return $this->group;
    
        function getDeptId() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->dept_id;
    
        function getDept() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->dept;
        }
    
    
        function getLanguage() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->lang;
    
        function getTimezone() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->timezone;
    
        }
    
        function getLocale() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->locale;
    
        function isManager() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return (($dept=$this->getDept()) && $dept->getManagerId()==$this->getId());
        }
    
    
        function isStaff() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return TRUE;
        }
    
    
        function isGroupActive() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->group_enabled;
    
        function isactive() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->isactive;
    
        function isVisible() {
    
    Jared Hancock's avatar
    Jared Hancock committed
             return $this->isvisible;
    
        function onVacation() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->onvacation;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function isAvailable() {
            return ($this->isactive() && $this->isGroupActive() && !$this->onVacation());
        }
    
    
        function showAssignedOnly() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->assigned_only;
    
    
        function isAccessLimited() {
            return $this->showAssignedOnly();
        }
    
        function isAdmin() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->isadmin;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function isTeamMember($teamId) {
    
            return ($teamId && in_array($teamId, $this->getTeams()));
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function canAccessDept($deptId) {
    
            return ($deptId && in_array($deptId, $this->getDepts()) && !$this->isAccessLimited());
    
        function canCreateTickets() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_create_tickets;
    
        function canEditTickets() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_edit_tickets;
    
        function canDeleteTickets() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_delete_tickets;
    
        function canCloseTickets() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_close_tickets;
    
        function canPostReply() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_post_ticket_reply;
    
        }
    
        function canViewStaffStats() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_view_staff_stats;
    
    Jared Hancock's avatar
    Jared Hancock committed
        function canAssignTickets() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_assign_tickets;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function canTransferTickets() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_transfer_tickets;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function canBanEmails() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_ban_emails;
    
        function canManageTickets() {
    
            return ($this->isAdmin()
                     || $this->canDeleteTickets()
    
    Jared Hancock's avatar
    Jared Hancock committed
                        || $this->canCloseTickets());
        }
    
    
        function canManagePremade() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_manage_premade;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function canManageCannedResponses() {
            return $this->canManagePremade();
        }
    
    
        function canManageFAQ() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->group->can_manage_faq;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function canManageFAQs() {
            return $this->canManageFAQ();
        }
    
    
        function showAssignedTickets() {
    
            return $this->show_assigned_tickets;
    
        function getTeams() {
    
    Peter Rotich's avatar
    Peter Rotich committed
            if (!isset($this->_teams)) {
                $this->_teams = array();
                foreach ($this->teams as $team)
                     $this->_teams[] = $team->team_id;
    
    Peter Rotich's avatar
    Peter Rotich committed
            return $this->_teams;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
        /* stats */
    
        function resetStats() {
            $this->stats = array();
        }
    
        /* returns staff's quick stats - used on nav menu...etc && warnings */
        function getTicketsStats() {
    
            if(!$this->stats['tickets'])
                $this->stats['tickets'] = Ticket::getStaffStats($this);
    
            return  $this->stats['tickets'];
        }
    
        function getNumAssignedTickets() {
            return ($stats=$this->getTicketsStats())?$stats['assigned']:0;
        }
    
        function getNumClosedTickets() {
            return ($stats=$this->getTicketsStats())?$stats['closed']:0;
        }
    
    
        function getExtraAttr($attr=false, $default=null) {
            if (!isset($this->_extra))
    
    Jared Hancock's avatar
    Jared Hancock committed
                $this->_extra = JsonDataParser::decode($this->extra);
    
            return $attr ? (@$this->_extra[$attr] ?: $default) : $this->_extra;
    
        }
    
        function setExtraAttr($attr, $value, $commit=true) {
            $this->getExtraAttr();
    
    Jared Hancock's avatar
    Jared Hancock committed
            $this->_extra[$attr] = $value;
    
    Jared Hancock's avatar
    Jared Hancock committed
                $this->extra = JsonDataEncoder::encode($this->_extra);
                $this->save();
    
            }
        }
    
        function onLogin($bk) {
            // Update last apparent language preference
            $this->setExtraAttr('browser_lang',
                Internationalization::getCurrentLanguage(),
                false);
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            $this->lastlogin = SqlFunction::NOW();
            $this->save();
    
    Jared Hancock's avatar
    Jared Hancock committed
        //Staff profile update...unfortunately we have to separate it from admin update to avoid potential issues
    
        function updateProfile($vars, &$errors) {
    
            global $cfg;
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            $vars['firstname']=Format::striptags($vars['firstname']);
            $vars['lastname']=Format::striptags($vars['lastname']);
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            if (isset($this->staff_id) && $this->getId() != $vars['id'])
    
                $errors['err']=__('Internal error occurred');
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            if(!$vars['firstname'])
    
                $errors['firstname']=__('First name is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$vars['lastname'])
    
                $errors['lastname']=__('Last name is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            if(!$vars['email'] || !Validator::is_email($vars['email']))
    
                $errors['email']=__('Valid email is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            elseif(Email::getIdByEmail($vars['email']))
    
                $errors['email']=__('Already in-use as system email');
    
    Jared Hancock's avatar
    Jared Hancock committed
            elseif (($uid=static::getIdByEmail($vars['email']))
                    && (!isset($this->staff_id) || $uid!=$this->getId()))
    
                $errors['email']=__('Email already in-use by another agent');
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            if($vars['phone'] && !Validator::is_phone($vars['phone']))
    
                $errors['phone']=__('Valid phone number is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            if($vars['mobile'] && !Validator::is_phone($vars['mobile']))
    
                $errors['mobile']=__('Valid phone number is required');
    
            if($vars['passwd1'] || $vars['passwd2'] || $vars['cpasswd']) {
    
    Jared Hancock's avatar
    Jared Hancock committed
    
                if(!$vars['passwd1'])
    
                    $errors['passwd1']=__('New password is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
                elseif($vars['passwd1'] && strlen($vars['passwd1'])<6)
    
                    $errors['passwd1']=__('Password must be at least 6 characters');
    
                elseif($vars['passwd1'] && strcmp($vars['passwd1'], $vars['passwd2']))
    
                    $errors['passwd2']=__('Passwords do not match');
    
                if (($rtoken = $_SESSION['_staff']['reset-token'])) {
                    $_config = new Config('pwreset');
                    if ($_config->get($rtoken) != $this->getId())
                        $errors['err'] =
    
                            __('Invalid reset token. Logout and try again');
    
                    elseif (!($ts = $_config->lastModified($rtoken))
                            && ($cfg->getPwResetWindow() < (time() - strtotime($ts))))
                        $errors['err'] =
    
                            __('Invalid reset token. Logout and try again');
    
                }
                elseif(!$vars['cpasswd'])
    
                    $errors['cpasswd']=__('Current password is required');
    
                elseif(!$this->cmp_passwd($vars['cpasswd']))
    
                    $errors['cpasswd']=__('Invalid current password!');
    
                elseif(!strcasecmp($vars['passwd1'], $vars['cpasswd']))
    
                    $errors['passwd1']=__('New password MUST be different from the current password!');
    
    Jared Hancock's avatar
    Jared Hancock committed
            }
    
            if($vars['default_signature_type']=='mine' && !$vars['signature'])
    
                $errors['default_signature_type'] = __("You don't have a signature");
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            if($errors) return false;
    
    
            $_SESSION['staff:lang'] = null;
    
            TextDomain::configureForUser($this);
    
    Jared Hancock's avatar
    Jared Hancock committed
            $this->firstname = $vars['firstname'];
            $this->lastname = $vars['lastname'];
            $this->email = $vars['email'];
            $this->phone = Format::phone($vars['phone']);
            $this->phone_ext = $vars['phone_ext'];
            $this->mobile = Format::phone($vars['mobile']);
            $this->signature = Format::sanitize($vars['signature']);
            $this->timezone = $vars['timezone'];
            $this->locale = $vars['locale'];
            $this->show_assigned_tickets = isset($vars['show_assigned_tickets'])?1:0;
            $this->max_page_size = $vars['max_page_size'];
            $this->auto_refresh_rate = $vars['auto_refresh_rate'];
            $this->default_signature_type = $vars['default_signature_type'];
            $this->default_paper_size = $vars['default_paper_size'];
            $this->lang = $vars['lang'];
    
            if ($vars['passwd1']) {
                $this->change_passwd = 0;
                $this->passwdreset = SqlFunction::NOW();
                $this->passwd = Passwd::hash($vars['passwd1']);
    
                $info = array('password' => $vars['passwd1']);
                Signal::send('auth.pwchange', $this, $info);
    
                $this->cancelResetTokens();
            }
    
    Jared Hancock's avatar
    Jared Hancock committed
            return $this->save();
        }
    
        function updateTeams($team_ids) {
    
    Peter Rotich's avatar
    Peter Rotich committed
    
            if (is_array($team_ids)) {
                $members = TeamMember::objects()
    
    Jared Hancock's avatar
    Jared Hancock committed
                    ->filter(array('staff_id' => $this->getId()));
    
    Peter Rotich's avatar
    Peter Rotich committed
                foreach ($members as $member) {
    
    Jared Hancock's avatar
    Jared Hancock committed
                    if ($idx = array_search($member->team_id, $team_ids)) {
                        unset($team_ids[$idx]);
    
    Peter Rotich's avatar
    Peter Rotich committed
                    } else {
    
    Jared Hancock's avatar
    Jared Hancock committed
                        $member->delete();
                    }
                }
    
    Jared Hancock's avatar
    Jared Hancock committed
                foreach ($team_ids as $id) {
    
    Peter Rotich's avatar
    Peter Rotich committed
                    TeamMember::create(array(
                        'staff_id'=>$this->getId(),
                        'team_id'=>$id
    
    Jared Hancock's avatar
    Jared Hancock committed
                    ))->save();
    
    Peter Rotich's avatar
    Peter Rotich committed
            } else {
                TeamMember::objects()
                    ->filter(array('staff_id'=>$this->getId()))
                    ->delete();
    
    Jared Hancock's avatar
    Jared Hancock committed
            return true;
        }
    
    
    Jared Hancock's avatar
    Jared Hancock committed
        function delete() {
            global $thisstaff;
    
    Peter Rotich's avatar
    Peter Rotich committed
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            if (!$thisstaff || $this->getId() == $thisstaff->getId())
    
    Jared Hancock's avatar
    Jared Hancock committed
                return false;
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            if (!parent::delete())
                return false;
    
    Jared Hancock's avatar
    Jared Hancock committed
            // DO SOME HOUSE CLEANING
            //Move remove any ticket assignments...TODO: send alert to Dept. manager?
            db_query('UPDATE '.TICKET_TABLE.' SET staff_id=0 WHERE staff_id='.db_input($this->getId()));
    
    Jared Hancock's avatar
    Jared Hancock committed
            //Update the poster and clear staff_id on ticket thread table.
            db_query('UPDATE '.TICKET_THREAD_TABLE
                    .' SET staff_id=0, poster= '.db_input($this->getName()->getOriginal())
                    .' WHERE staff_id='.db_input($this->getId()));
    
    Jared Hancock's avatar
    Jared Hancock committed
            // Cleanup Team membership table.
    
    Peter Rotich's avatar
    Peter Rotich committed
            $this->updateTeams(array());
    
    Jared Hancock's avatar
    Jared Hancock committed
            return true;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        /**** Static functions ********/
    
    Jared Hancock's avatar
    Jared Hancock committed
        static function lookup($var) {
            if (is_array($var))
                return parent::lookup($var);
            elseif (is_numeric($var))
                return parent::lookup(array('staff_id'=>$var));
            elseif (Validator::is_email($var))
                return parent::lookup(array('email'=>$var));
            elseif (is_string($var))
                return parent::lookup(array('username'=>$var));
            else
                return null;
        }
    
        static function getStaffMembers($availableonly=false) {
    
    Jared Hancock's avatar
    Jared Hancock committed
            $members = static::objects()->order_by('lastname', 'firstname');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if ($availableonly) {
                $members = $members->filter(array(
                    'group__group_enabled' => 1,
                    'onvacation' => 0,
                    'isactive' => 1,
                ));
    
    Jared Hancock's avatar
    Jared Hancock committed
            }
    
            $users=array();
    
    Jared Hancock's avatar
    Jared Hancock committed
            foreach ($members as $M) {
    
    Peter Rotich's avatar
    Peter Rotich committed
                $users[$M->id] = $M->getName();
    
        static function getAvailableStaffMembers() {
    
    Jared Hancock's avatar
    Jared Hancock committed
            return self::getStaffMembers(true);
        }
    
    
    Jared Hancock's avatar
    Jared Hancock committed
        static function getIdByUsername($username) {
            $row = static::objects()->filter(array('username' => $username))
                ->values_flat('staff_id')->first();
            return $row ? $row[0] : 0;
    
    Jared Hancock's avatar
    Jared Hancock committed
        function getIdByEmail($email) {
            $row = static::objects()->filter(array('email' => $email))
                ->values_flat('staff_id')->first();
            return $row ? $row[0] : 0;
    
    Jared Hancock's avatar
    Jared Hancock committed
        static function create($vars=false) {
            $staff = parent::create($vars);
            $staff->created = SqlFunction::NOW();
            return $staff;
    
        function cancelResetTokens() {
            // TODO: Drop password-reset tokens from the config table for
            //       this user id
            $sql = 'DELETE FROM '.CONFIG_TABLE.' WHERE `namespace`="pwreset"
                AND `value`='.db_input($this->getId());
    
            db_query($sql, false);
    
            unset($_SESSION['_staff']['reset-token']);
        }
    
    
        function sendResetEmail($template='pwreset-staff') {
    
            global $ost, $cfg;
    
    
            $content = Page::lookupByType($template);
    
            $token = Misc::randCode(48); // 290-bits
    
                return new Error(/* @trans */ 'Unable to retrieve password reset email template');
    
            $vars = array(
    
                'url' => $ost->getConfig()->getBaseUrl(),
                'token' => $token,
    
                'recipient' => $this,
    
                'reset_link' => sprintf(
                    "%s/scp/pwreset.php?token=%s",
                    $ost->getConfig()->getBaseUrl(),
                    $token),
    
            $vars['link'] = &$vars['reset_link'];
    
            if (!($email = $cfg->getAlertEmail()))
    
                $email = $cfg->getDefaultEmail();
    
    
            $info = array('email' => $email, 'vars' => &$vars, 'log'=>true);
    
            Signal::send('auth.pwreset.email', $this, $info);
    
    
            if ($info['log'])
    
                $ost->logWarning(_S('Agent Password Reset'), sprintf(
                 _S('Password reset was attempted for agent: %1$s<br><br>
    
                    Requested-User-Id: %2$s<br>
                    Source-Ip: %3$s<br>
                    Email-Sent-To: %4$s<br>
                    Email-Sent-Via: %5$s'),
    
                    $this->getName(),
                    $_POST['userid'],
                    $_SERVER['REMOTE_ADDR'],
                    $this->getEmail(),
                    $email->getEmail()
                ), false);
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            $lang = $this->lang ?: $this->getExtraAttr('browser_lang');
    
            $msg = $ost->replaceTemplateVariables(array(
    
                'subj' => $content->getLocalName($lang),
                'body' => $content->getLocalBody($lang),
    
    
            $_config = new Config('pwreset');
    
            $_config->set($vars['token'], $this->getId());
    
            $email->send($this->getEmail(), Format::striptags($msg['subj']),
    
    Jared Hancock's avatar
    Jared Hancock committed
        function save($refetch=false) {
            if ($this->dirty)
                $this->updated = SqlFunction::NOW();
            return parent::save($refetch || $this->dirty);
        }
    
        function update($vars, &$errors) {
    
    Jared Hancock's avatar
    Jared Hancock committed
            $vars['username']=Format::striptags($vars['username']);
            $vars['firstname']=Format::striptags($vars['firstname']);
            $vars['lastname']=Format::striptags($vars['lastname']);
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            if (isset($this->staff_id) && $this->getId() != $vars['id'])
    
                $errors['err']=__('Internal Error');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$vars['firstname'])
    
                $errors['firstname']=__('First name required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$vars['lastname'])
    
                $errors['lastname']=__('Last name required');
    
            $error = '';
            if(!$vars['username'] || !Validator::is_username($vars['username'], $error))
    
                $errors['username']=($error) ? $error : __('Username is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            elseif (($uid=static::getIdByUsername($vars['username']))
                    && (!isset($this->staff_id) || $uid!=$this->getId()))
    
                $errors['username']=__('Username already in use');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$vars['email'] || !Validator::is_email($vars['email']))
    
                $errors['email']=__('Valid email is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            elseif(Email::getIdByEmail($vars['email']))
    
                $errors['email']=__('Already in use system email');
    
    Jared Hancock's avatar
    Jared Hancock committed
            elseif (($uid=static::getIdByEmail($vars['email']))
                    && (!isset($this->staff_id) || $uid!=$this->getId()))
    
                $errors['email']=__('Email already in use by another agent');
    
    Jared Hancock's avatar
    Jared Hancock committed
    
            if($vars['phone'] && !Validator::is_phone($vars['phone']))
    
                $errors['phone']=__('Valid phone number is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if($vars['mobile'] && !Validator::is_phone($vars['mobile']))
    
                $errors['mobile']=__('Valid phone number is required');
    
    Peter Rotich's avatar
    Peter Rotich committed
            if($vars['passwd1'] || $vars['passwd2'] || !$vars['id']) {
    
    Jared Hancock's avatar
    Jared Hancock committed
                if($vars['passwd1'] && strcmp($vars['passwd1'], $vars['passwd2'])) {
    
                    $errors['passwd2']=__('Passwords do not match');
    
                elseif ($vars['backend'] != 'local' || $vars['welcome_email']) {
    
    Jared Hancock's avatar
    Jared Hancock committed
                    // Password can be omitted
                }
    
    Peter Rotich's avatar
    Peter Rotich committed
                elseif(!$vars['passwd1'] && !$vars['id']) {
    
                    $errors['passwd1']=__('Temporary password is required');
    
                    $errors['temppasswd']=__('Required');
    
                } elseif($vars['passwd1'] && strlen($vars['passwd1'])<6) {
    
                    $errors['passwd1']=__('Password must be at least 6 characters');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$vars['dept_id'])
    
                $errors['dept_id']=__('Department is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if(!$vars['group_id'])
    
                $errors['group_id']=__('Group is required');
    
    Jared Hancock's avatar
    Jared Hancock committed
            if ($errors)
                return false;
    
    Jared Hancock's avatar
    Jared Hancock committed
            $this->isadmin = $vars['isadmin'];
            $this->isactive = $vars['isactive'];
            $this->isvisible = isset($vars['isvisible'])?1:0;
            $this->onvacation = isset($vars['onvacation'])?1:0;
            $this->assigned_only = isset($vars['assigned_only'])?1:0;
            $this->dept_id = $vars['dept_id'];
            $this->group_id = $vars['group_id'];
            $this->timezone = $vars['timezone'];
            $this->username = $vars['username'];
            $this->firstname = $vars['firstname'];
            $this->lastname = $vars['lastname'];
            $this->email = $vars['email'];
            $this->backend = $vars['backend'];
            $this->phone = Format::phone($vars['phone']);
            $this->phone_ext = $vars['phone_ext'];
            $this->mobile = Format::phone($vars['mobile']);
            $this->signature = Format::sanitize($vars['signature']);
            $this->notes = Format::sanitize($vars['notes']);
    
            if ($vars['passwd1']) {
                $this->passwd = Passwd::hash($vars['passwd1']);
                if (isset($vars['change_passwd']))
                    $this->change_passwd = 1;
            }
            elseif (!isset($vars['change_passwd'])) {
                $this->change_passwd = 0;
    
    Jared Hancock's avatar
    Jared Hancock committed
            if ($this->save() && $this->updateTeams($vars['teams'])) {
                if ($vars['welcome_email'])
                    $this->sendResetEmail('registration-staff');
                return true;
            }
    
    Jared Hancock's avatar
    Jared Hancock committed
            if (isset($this->staff_id)) {
    
                $errors['err']=sprintf(__('Unable to update %s.'), __('this agent'))
                   .' '.__('Internal error occurred');
    
                $errors['err']=sprintf(__('Unable to create %s.'), __('this agent'))
                   .' '.__('Internal error occurred');
    
    Jared Hancock's avatar
    Jared Hancock committed
            }
            return false;
        }
    }
    ?>