Skip to content
Snippets Groups Projects
class.search.php 45.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •     function hasIdValue() {
            return true;
        }
    
    
        function getChoices($verbose=false) {
    
            return Topic::getHelpTopics(false, Topic::DISPLAY_DISABLED);
        }
    }
    
    require_once INCLUDE_DIR . 'class.dept.php';
    
    class DepartmentChoiceField extends AdvancedSearchSelectionField {
    
        var $_choices = null;
    
    
        function getChoices($verbose=false) {
    
            return Dept::getDepartments();
        }
    
    
        function getQuickFilterChoices() {
    
           global $thisstaff;
    
           if (!isset($this->_choices)) {
             $this->_choices = array();
             $depts = $thisstaff ? $thisstaff->getDepts() : array();
             foreach ($this->getChoices() as $id => $name) {
               if (!$depts || in_array($id, $depts))
                   $this->_choices[$id] = $name;
             }
           }
    
           return $this->_choices;
    
        function getSearchMethods() {
            return array(
    
                'includes' =>   __('is'),
                '!includes' =>  __('is not'),
    
    
        function addToQuery($query, $name=false) {
            return $query->values('dept_id', 'dept__name');
        }
    
        function applyOrderBy($query, $reverse=false, $name=false) {
            $reverse = $reverse ? '-' : '';
            return $query->order_by("{$reverse}dept__name");
        }
    
    class AssigneeChoiceField extends ChoiceField {
    
    Peter Rotich's avatar
    Peter Rotich committed
    
        protected $_items;
    
    
    
        function getChoices($verbose=false) {
    
    Peter Rotich's avatar
    Peter Rotich committed
            if (!isset($this->_items)) {
                $items = array(
                    'M' => __('Me'),
                    'T' => __('One of my teams'),
                );
                foreach (Staff::getStaffMembers() as $id=>$name) {
                    // Don't include $thisstaff (since that's 'Me')
                    if ($thisstaff && $thisstaff->getId() == $id)
                        continue;
                    $items['s' . $id] = $name;
                }
                foreach (Team::getTeams() as $id=>$name) {
                    $items['t' . $id] = $name;
                }
    
                $this->_items = $items;
    
    Peter Rotich's avatar
    Peter Rotich committed
    
            return $this->_items;
        }
    
        function getChoice($k) {
            $choices = $this->getChoices();
            return $choices[$k] ?: null;
    
        }
    
        function getSearchMethods() {
            return array(
    
                'assigned' =>   __('assigned'),
                '!assigned' =>  __('unassigned'),
                'includes' =>   __('includes'),
                '!includes' =>  __('does not include'),
    
            );
        }
    
        function getSearchMethodWidgets() {
            return array(
                'assigned' => null,
    
                '!assigned' => null,
                'includes' => array('ChoiceField', array(
    
                    'choices' => $this->getChoices(),
                    'configuration' => array('multiselect' => true),
                )),
    
                '!includes' => array('ChoiceField', array(
    
                    'choices' => $this->getChoices(),
                    'configuration' => array('multiselect' => true),
                )),
            );
        }
    
    
        function getSearchQ($method, $value, $name=false) {
            global $thisstaff;
    
            $Q = new Q();
            switch ($method) {
            case 'assigned':
    
                $Q->negate();
            case '!assigned':
                $Q->add(array('team_id' => 0,
                    'staff_id' => 0));
    
                break;
            case '!includes':
                $Q->negate();
            case 'includes':
                $teams = $agents = array();
                foreach ($value as $id => $ST) {
                    switch ($id[0]) {
                    case 'M':
                        $agents[] = $thisstaff->getId();
                        break;
                    case 's':
                        $agents[] = (int) substr($id, 1);
                        break;
                    case 'T':
                        $teams = array_merge($thisstaff->getTeams());
                        break;
                    case 't':
                        $teams[] = (int) substr($id, 1);
                        break;
                    }
                }
                $constraints = array();
                if ($teams)
                    $constraints['team_id__in'] = $teams;
                if ($agents)
                    $constraints['staff_id__in'] = $agents;
                $Q->add(Q::any($constraints));
            }
            return $Q;
        }
    
    
        function describeSearchMethod($method) {
            switch ($method) {
            case 'assigned':
                return __('assigned');
            case '!assigned':
                return __('unassigned');
            default:
                return parent::describeSearchMethod($method);
            }
        }
    
    
        function addToQuery($query, $name=false) {
    
    
            $fields = array();
            foreach(Staff::getsortby('staff__') as $key)
                 $fields[] = new SqlField($key);
            $fields[] =  new SqlField('team__name');
            $fields[] = 'zzz';
            $expr = call_user_func_array(array('SqlFunction', 'COALESCE'), $fields);
            $query->annotate(array($name ?: 'assignee' => $expr));
    
            return $query->values('staff__firstname', 'staff__lastname', 'team__name', 'team_id');
        }
    
        function from_query($row, $name=false) {
            if ($row['staff__firstname'])
                return new AgentsName(array('first' => $row['staff__firstname'], 'last' => $row['staff__lastname']));
            if ($row['team_id'])
                return Team::getLocalById($row['team_id'], 'name', $row['team__name']);
    
        }
    
        function display($value) {
            return (string) $value;
        }
    
    Peter Rotich's avatar
    Peter Rotich committed
    
        function toString($value) {
            if (!is_array($value))
                 $value = array($value => $value);
            $selection = array();
            foreach ($value as $k => $v)
                $selection[] = $this->getChoice($k) ?: (string) $v;
            return implode(', ', $selection);
        }
    
    class AssignedField extends AssigneeChoiceField {
    
        function getSearchMethods() {
            return array(
                'assigned' =>   __('assigned'),
                '!assigned' =>  __('unassigned'),
            );
        }
    
        function addToQuery($query, $name=false) {
            return $query->values('staff_id', 'team_id');
        }
    
        function from_query($row, $name=false) {
            return ($row['staff_id'] || $row['staff_id'])
                ? __('Yes') : __('No');
        }
    
    }
    
    
    /**
     * Simple trait which changes the SQL for "has a value" and "does not have a
     * value" to check for zero or non-zero. Useful for not nullable fields.
     */
    trait ZeroMeansUnset {
        function getSearchQ($method, $value, $name=false) {
            $name = $name ?: $this->get('name');
            switch ($method) {
            // osTicket commonly uses `0` to represent an unset state, so
            // the set and unset checks need to check for both not null and
            // nonzero
            case 'nset':
                return new Q([$name => 0]);
            case 'set':
                return Q::not([$name => 0]);
            }
            return parent::getSearchQ($method, $value, $name);
        }
    }
    
    
    class AgentSelectionField extends AdvancedSearchSelectionField {
    
        function getChoices($verbose=false) {
    
            return array('M' => __('Me')) + Staff::getStaffMembers();
    
        function toString($value) {
            $choices =  $this->getChoices();
            $selection = array();
            foreach ($value as $k => $v)
                if (isset($choices[$k]))
                    $selection[] = $choices[$k];
    
            return $selection ?  implode(',', $selection) :
                parent::toString($value);
        }
    
    
        function getSearchQ($method, $value, $name=false) {
            global $thisstaff;
            // unpack me
            if (isset($value['M']) && $thisstaff) {
                $value[$thisstaff->getId()] = $thisstaff->getName();
                unset($value['M']);
            }
    
            return parent::getSearchQ($method, $value, $name);
        }
    
    
        function getSortKeys($path='') {
            return Staff::getsortby('staff__');
        }
    
        function applyOrderBy($query, $reverse=false, $name=false) {
            $reverse = $reverse ? '-' : '';
    
            return Staff::nsort($query, "{$reverse}staff__");
    
    class DepartmentManagerSelectionField extends AgentSelectionField {
    
        function getChoices($verbose=false) {
            return Staff::getStaffMembers();
        }
    
        function getSearchQ($method, $value, $name=false) {
            return parent::getSearchQ($method, $value, 'dept__manager_id');
        }
    }
    
    
    class TeamSelectionField extends AdvancedSearchSelectionField {
    
        function getChoices($verbose=false) {
    
            return array('T' => __('One of my teams')) + Team::getTeams();
        }
    
        function getSearchQ($method, $value, $name=false) {
            global $thisstaff;
    
            // Unpack my teams
            if (isset($value['T']) && $thisstaff
                    && ($teams = $thisstaff->getTeams())) {
                unset($value['T']);
                $value = $value + array_flip($teams);
            }
    
            return parent::getSearchQ($method, $value, $name);
    
        function getSortKeys() {
            return array('team__name');
        }
    
    
        function applyOrderBy($query, $reverse=false, $name=false) {
            $reverse = $reverse ? '-' : '';
            return $query->order_by("{$reverse}team__name");
        }
    
    class TicketStateChoiceField extends AdvancedSearchSelectionField {
    
        function getChoices($verbose=false) {
    
            return array(
                'open' => __('Open'),
                'closed' => __('Closed'),
    
                'archived' => _P('ticket state name', 'Archived'),
    
                'deleted' => _P('ticket state name','Deleted'),
    
            );
        }
    
        function getSearchMethods() {
            return array(
                'includes' =>   __('is'),
                '!includes' =>  __('is not'),
            );
        }
    
        function getSearchQ($method, $value, $name=false) {
            return parent::getSearchQ($method, $value, 'status__state');
        }
    }
    
    class TicketFlagChoiceField extends ChoiceField {
    
        function getChoices($verbose=false) {
    
            return array(
                'isanswered' =>   __('Answered'),
                'isoverdue' =>    __('Overdue'),
            );
        }
    
        function getSearchMethods() {
            return array(
                'includes' =>   __('is'),
                '!includes' =>  __('is not'),
            );
        }
    
        function getSearchQ($method, $value, $name=false) {
            $Q = new Q();
            if (isset($value['isanswered']))
                $Q->add(array('isanswered' => 1));
            if (isset($value['isoverdue']))
                $Q->add(array('isoverdue' => 1));
            if ($method == '!includes')
                $Q->negate();
            if ($Q->constraints)
                return $Q;
        }
    
    class TicketSourceChoiceField extends ChoiceField {
    
        function getChoices($verbose=false) {
    
            return Ticket::getSources();
    
        }
    
        function getSearchMethods() {
            return array(
                'includes' =>   __('is'),
                '!includes' =>  __('is not'),
            );
        }
    
        function getSearchQ($method, $value, $name=false) {
            return parent::getSearchQ($method, $value, 'source');
        }
    }
    
    
    class OpenClosedTicketStatusList extends TicketStatusList {
        function getItems($criteria=array()) {
            $rv = array();
            $base = parent::getItems($criteria);
            foreach ($base as $idx=>$S) {
                if (in_array($S->state, array('open', 'closed')))
                    $rv[$idx] = $S;
            }
            return $rv;
        }
    }
    
    class TicketStatusChoiceField extends SelectionField {
        static $widget = 'ChoicesWidget';
    
        function getList() {
    
            return new OpenClosedTicketStatusList(
    
                DynamicList::lookup(
                    array('type' => 'ticket-status'))
            );
        }
    
        function getSearchMethods() {
            return array(
    
                'includes' =>   __('is'),
                '!includes' =>  __('is not'),
    
    
        function getSearchQ($method, $value, $name=false) {
            $name = $name ?: $this->get('name');
    
            if (!$value)
                return false;
    
            switch ($method) {
            case '!includes':
                return Q::not(array("{$name}__in" => array_keys($value)));
            case 'includes':
                return new Q(array("{$name}__in" => array_keys($value)));
            default:
                return parent::getSearchQ($method, $value, $name);
            }
        }
    
    
    interface Searchable {
        // Fetch an array of [ orm__path => Field() ] pairs. The field label is
        // used when this list is rendered in a dropdown, and the field search
        // mechanisms are use to apply query filtering based on the field.
        static function getSearchableFields();
    
    
        // Determine if the object supports abritrary form additions, through
        // the "Manage Forms" dialog usually
        static function supportsCustomData();