Skip to content
Snippets Groups Projects
class.forms.php 174 KiB
Newer Older
  • Learn to ignore specific revisions
  • 
        function supportsQuickFilter() {
            return true;
        }
    
        function getQuickFilterChoices() {
            return $this->getChoices();
        }
    
        function applyQuickFilter($query, $qf_value, $name=false) {
    
    aydreeihn's avatar
    aydreeihn committed
            global $thisstaff;
    
            //special assignment quick filters
            switch (true) {
                case ($qf_value == 'assigned'):
                case ($qf_value == '!assigned'):
                    $result = AssigneeChoiceField::getSearchQ($qf_value, $qf_value);
                    return $query->filter($result);
                case (strpos($qf_value, 's') !== false):
                case (strpos($qf_value, 't') !== false):
                case ($qf_value == 'M'):
                case ($qf_value == 'T'):
                    $value = array($qf_value => $qf_value);
                    $result = AssigneeChoiceField::getSearchQ('includes', $value);
                    return $query->filter($result);
                    break;
            }
    
    
            return $query->filter(array(
                $name ?: $this->get('name') => $qf_value,
            ));
        }
    
    Peter Rotich's avatar
    Peter Rotich committed
    class NumericField extends FormField {
    
        function getSearchMethods() {
            return array(
                'equal' =>   __('Equal'),
                'greater' =>  __('Greater Than'),
                'less' =>  __('Less Than'),
            );
        }
    
        function getSearchMethodWidgets() {
            return array(
                'equal' => array('TextboxField', array(
                        'configuration' => array(
                            'validator' => 'number',
                            'size' => 6
                            ),
                )),
                'greater' => array('TextboxField', array(
                        'configuration' => array(
                            'validator' => 'number',
                            'size' => 6
                            ),
                )),
                'less' => array('TextboxField', array(
                        'configuration' => array(
                            'validator' => 'number',
                            'size' => 6
                            ),
                )),
            );
        }
    }
    
    
    Jared Hancock's avatar
    Jared Hancock committed
    class DatetimeField extends FormField {
    
        static $widget = 'DatetimePickerWidget';
    
    Peter Rotich's avatar
    Peter Rotich committed
        var $min = null;
        var $max = null;
    
    
        static function intervals($count=2, $i='') {
            $intervals = array(
                'i' => _N('minute', 'minutes', $count),
                'h' => _N('hour', 'hours', $count),
                'd' => _N('day','days', $count),
                'w' => _N('week', 'weeks', $count),
                'm' => _N('month', 'months', $count),
            );
            return $i ? $intervals[$i] : $intervals;
        }
    
    
        static function periods($period='') {
            $periods = array(
                    'td' => __('Today'),
                    'yd' => __('Yesterday'),
                    'tw' => __('This Week'),
                    'tm' => __('This Month'),
    
    JediKev's avatar
    JediKev committed
                    'tq' => __('This Quarter'),
    
                    'ty' => __('This Year'),
                    'lw' => __('Last Week'),
                    'lm' => __('Last Month'),
    
    JediKev's avatar
    JediKev committed
                    'lq' => __('Last Quarter'),
    
                    'ly' => __('Last Year'),
            );
            return $period ? $periods[$period] : $periods;
        }
    
    
    Peter Rotich's avatar
    Peter Rotich committed
        // Get php DatateTime object of the field  - null if value is empty
        function getDateTime($value=null) {
            return Format::parseDateTime($value ?: $this->value);
        }
    
    
        // Get effective timezone for the field
        function getTimeZone() {
            global $cfg;
    
            $config = $this->getConfiguration();
            $timezone = new DateTimeZone($config['timezone'] ?:
                    $cfg->getTimezone());
    
            return $timezone;
        }
    
    
    Peter Rotich's avatar
    Peter Rotich committed
        function getMinDateTime() {
    
            if (!isset($this->min)) {
                $config = $this->getConfiguration();
                $this->min = $config['min']
                    ? Format::parseDateTime($config['min']) : false;
            }
    
            return $this->min;
        }
    
        function getMaxDateTime() {
    
            if (!isset($this->max)) {
                $config = $this->getConfiguration();
                $this->max = $config['max']
                    ? Format::parseDateTime($config['max']) : false;
            }
    
            return $this->max;
        }
    
    
    aydreeihn's avatar
    aydreeihn committed
        function getPastPresentLabels() {
          return array(__('Create Date'), __('Reopen Date'),
                        __('Close Date'), __('Last Update'));
        }
    
    
    Jared Hancock's avatar
    Jared Hancock committed
        function to_database($value) {
    
    Peter Rotich's avatar
    Peter Rotich committed
            // Store time in format given by Date Picker (DateTime::W3C)
            return $value;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function to_php($value) {
    
    Peter Rotich's avatar
    Peter Rotich committed
    
    
    Peter Rotich's avatar
    Peter Rotich committed
            if (!is_numeric($value) && strtotime($value) <= 0)
    
    Peter Rotich's avatar
    Peter Rotich committed
                return 0;
    
            return $value;
    
    Peter Rotich's avatar
    Peter Rotich committed
        function display($value) {
            global $cfg;
    
    
            if (!$value || !($datetime = Format::parseDateTime($value)))
    
    Peter Rotich's avatar
    Peter Rotich committed
                return '';
    
            $config = $this->getConfiguration();
    
    Peter Rotich's avatar
    Peter Rotich committed
            $format = $config['format'] ?: false;
    
    Peter Rotich's avatar
    Peter Rotich committed
            if ($config['gmt'])
    
    Peter Rotich's avatar
    Peter Rotich committed
                return $this->format((int) $datetime->format('U'), $format);
    
    Peter Rotich's avatar
    Peter Rotich committed
    
    
            // Force timezone if field has one.
            if ($config['timezone']) {
                $timezone = new DateTimezone($config['timezone']);
                $datetime->setTimezone($timezone);
            }
    
    
    Peter Rotich's avatar
    Peter Rotich committed
            $value = $this->format($datetime->format('U'),
    
    Peter Rotich's avatar
    Peter Rotich committed
                    $datetime->getTimezone()->getName(),
                    $format);
    
    Peter Rotich's avatar
    Peter Rotich committed
            // No need to show timezone
    
    Peter Rotich's avatar
    Peter Rotich committed
            if (!$config['time'] || $format)
    
    Peter Rotich's avatar
    Peter Rotich committed
                return $value;
    
            // Display is NOT timezone aware show entry's timezone.
            return sprintf('%s (%s)',
                    $value, $datetime->format('T'));
    
    Peter Rotich's avatar
    Peter Rotich committed
    
    
        function from_query($row, $name=false) {
    
            $value = parent::from_query($row, $name);
            $timestamp = is_int($value) ? $value : (int) strtotime($value);
            return ($timestamp > 0) ? $timestamp : '';
    
    Peter Rotich's avatar
    Peter Rotich committed
        function format($timestamp, $timezone=false, $format=false) {
    
    Peter Rotich's avatar
    Peter Rotich committed
    
            if (!$timestamp || $timestamp <= 0)
                return '';
    
            $config = $this->getConfiguration();
            if ($config['time'])
    
    Peter Rotich's avatar
    Peter Rotich committed
                $formatted = Format::datetime($timestamp, false, $format,  $timezone);
    
    Peter Rotich's avatar
    Peter Rotich committed
            else
    
    Peter Rotich's avatar
    Peter Rotich committed
                $formatted = Format::date($timestamp, false, $format, $timezone);
    
    Peter Rotich's avatar
    Peter Rotich committed
    
            return $formatted;
    
    Jared Hancock's avatar
    Jared Hancock committed
        }
    
        function toString($value) {
    
    aydreeihn's avatar
    aydreeihn committed
            if (is_array($value))
                return '';
    
    Peter Rotich's avatar
    Peter Rotich committed
    
            $timestamp = is_int($value) ? $value : (int) strtotime($value);
            if ($timestamp <= 0)
                return '';
    
            return $this->format($timestamp);
        }
    
        function asVar($value, $id=false) {
    
    Jared Hancock's avatar
    Jared Hancock committed
            global $cfg;
    
    Peter Rotich's avatar
    Peter Rotich committed
    
    
    Peter Rotich's avatar
    Peter Rotich committed
                return null;
    
            $datetime = $this->getDateTime($value);
            $config = $this->getConfiguration();
            if (!$config['gmt'] || !$config['time'])
                $timezone  = $datetime->getTimezone()->getName();
    
    Peter Rotich's avatar
    Peter Rotich committed
                $timezone  = false;
    
            return  new FormattedDate($value, array(
                        'timezone'  =>  $timezone,
                        'format'    =>  $config['time'] ? 'long' : 'short'
                        )
                    );
        }
    
        function asVarType() {
            return 'FormattedDate';
    
    Jared Hancock's avatar
    Jared Hancock committed
        function getConfigurationOptions() {
            return array(
                'time' => new BooleanField(array(
    
                    'id'=>1, 'label'=>__('Time'), 'required'=>false, 'default'=>false,
    
    Jared Hancock's avatar
    Jared Hancock committed
                    'configuration'=>array(
    
                        'desc'=>__('Show time selection with date picker')))),
    
                'timezone' => new TimezoneField(array(
                    'id'=>2, 'label'=>__('Timezone'), 'required'=>false,
                    'hint'=>__('Timezone of the date time selection'),
                    'configuration' => array('autodetect'=>false,
                        'prompt' => __("User's timezone")),
                   'visibility' => new VisibilityConstraint(
                        new Q(array('time__eq'=> true)),
                        VisibilityConstraint::HIDDEN
                    ),
                    )),
    
    Jared Hancock's avatar
    Jared Hancock committed
                'gmt' => new BooleanField(array(
    
                    'id'=>3, 'label'=>__('Timezone Aware'), 'required'=>false,
    
    Jared Hancock's avatar
    Jared Hancock committed
                    'configuration'=>array(
    
                        'desc'=>__("Show date/time relative to user's timezone")))),
    
    Jared Hancock's avatar
    Jared Hancock committed
                'min' => new DatetimeField(array(
    
                    'id'=>4, 'label'=>__('Earliest'), 'required'=>false,
    
                    'hint'=>__('Earliest date selectable'))),
    
    Jared Hancock's avatar
    Jared Hancock committed
                'max' => new DatetimeField(array(
    
                    'id'=>5, 'label'=>__('Latest'), 'required'=>false,
    
                    'default'=>null, 'hint'=>__('Latest date selectable'))),
    
    Jared Hancock's avatar
    Jared Hancock committed
                'future' => new BooleanField(array(
    
                    'id'=>6, 'label'=>__('Allow Future Dates'), 'required'=>false,
    
    Jared Hancock's avatar
    Jared Hancock committed
                    'default'=>true, 'configuration'=>array(
    
                        'desc'=>__('Allow entries into the future' /* Used in the date field */)),
                )),
    
    Jared Hancock's avatar
    Jared Hancock committed
            );
        }
    
        function validateEntry($value) {
    
    Peter Rotich's avatar
    Peter Rotich committed
            global $cfg;
    
    
    Jared Hancock's avatar
    Jared Hancock committed
            $config = $this->getConfiguration();
            parent::validateEntry($value);
    
            if (!$value || !($datetime = Format::parseDateTime($value)))
    
    Peter Rotich's avatar
    Peter Rotich committed
                return;
    
            // Get configured min/max (if any)
    
            $min = $this->getMinDateTime();
            $max = $this->getMaxDateTime();
    
    Peter Rotich's avatar
    Peter Rotich committed
    
    
            if (!$datetime) {
    
                $this->_errors[] = __('Enter a valid date');
    
            } elseif ($min and $datetime < $min) {
    
    Peter Rotich's avatar
    Peter Rotich committed
                $this->_errors[] = sprintf('%s (%s)',
                        __('Selected date is earlier than permitted'),
                         Format::date($min->getTimestamp(), false, false,
                             $min->getTimezone()->getName() ?: 'UTC')
                         );
    
            } elseif ($max and $datetime > $max) {
    
    Peter Rotich's avatar
    Peter Rotich committed
                $this->_errors[] = sprintf('%s (%s)',
                        __('Selected date is later than permitted'),
                        Format::date($max->getTimestamp(), false, false,
                            $max->getTimezone()->getName() ?: 'UTC')
                        );
            }
    
        // SearchableField interface ------------------------------
    
        function getSearchMethods() {
            return array(
                'set' =>        __('has a value'),
    
                'nset' =>       __('does not have a value'),
    
                'nequal' =>     __('not on'),
    
                'before' =>     __('before'),
                'after' =>      __('after'),
                'between' =>    __('between'),
    
                'period' =>     __('period'),
    
                'ndaysago' =>   __('in the last n days'),
                'ndays' =>      __('in the next n days'),
    
                'future' =>     __('in the future'),
                'past' =>       __('in the past'),
                'distfut' =>    __('more than n days from now'),
                'distpast' =>   __('more than n days ago'),
    
            );
        }
    
        function getSearchMethodWidgets() {
    
            $config_notime = $config = $this->getConfiguration();
            $config_notime['time'] = false;
    
            $nday_form = function($x=5) {
    
                return array(
                    'until' => new TextboxField(array(
                        'configuration' => array('validator'=>'number', 'size'=>4))
                    ),
                    'int' => new ChoiceField(array(
                        'default' => 'd',
    
                        'choices' => self::intervals($x),
    
            return array(
                'set' => null,
    
                'past' => null,
                'future' => null,
    
                'equal' => array('DatetimeField', array(
    
                    'configuration' => $config_notime,
    
                'nequal' => array('DatetimeField', array(
    
                    'configuration' => $config_notime,
    
                )),
                'before' => array('DatetimeField', array(
                    'configuration' => $config,
                )),
                'after' => array('DatetimeField', array(
                    'configuration' => $config,
                )),
                'between' => array('InlineformField', array(
                    'form' => array(
                        'left' => new DatetimeField(),
                        'text' => new FreeTextField(array(
                            'configuration' => array('content' => 'and'))
                        ),
                        'right' => new DatetimeField(),
                    ),
                )),
    
                'period' => array('ChoiceField', array(
                    'choices' => self::periods(),
                )),
    
                'ndaysago' => array('InlineformField', array('form'=>$nday_form())),
                'ndays' => array('InlineformField', array('form'=>$nday_form())),
                'distfut' => array('InlineformField', array('form'=>$nday_form())),
                'distpast' => array('InlineformField', array('form'=>$nday_form())),
    
            );
        }
    
        function getSearchQ($method, $value, $name=false) {
    
            global $cfg;
    
    
            static $intervals = array(
                'm' => 'MONTH',
                'w' => 'WEEK',
                'd' => 'DAY',
                'h' => 'HOUR',
                'i' => 'MINUTE',
            );
    
            $name = $name ?: $this->get('name');
    
            $now = SqlFunction::NOW();
    
            $config = $this->getConfiguration();
    
           if (is_int($value))
              $value = DateTime::createFromFormat('U', !$config['gmt'] ? Misc::gmtime($value) : $value) ?: $value;
    
           elseif (is_string($value) && strlen($value) > 2)
    
               $value = Format::parseDateTime($value) ?: $value;
    
    
            case 'equal':
                $l = clone $value;
                $r = $value->add(new DateInterval('P1D'));
                return new Q(array(
                    "{$name}__gte" => $l,
                    "{$name}__lt" => $r
                ));
            case 'nequal':
                $l = clone $value;
                $r = $value->add(new DateInterval('P1D'));
                return Q::any(array(
                    "{$name}__lt" => $l,
                    "{$name}__gte" => $r,
                ));
    
            case 'after':
                return new Q(array("{$name}__gte" => $value));
    
            case 'before':
                return new Q(array("{$name}__lt" => $value));
            case 'between':
    
                $left = Format::parseDateTime($value['left']);
                $right = Format::parseDateTime($value['right']);
    
                // TODO: allow time selection for between
    
                $left = $left->setTime(00, 00, 00);
                $right = $right->setTime(23, 59, 59);
    
                // Convert time to db timezone
                $dbtz = new DateTimeZone($cfg->getDbTimezone());
                $left->setTimezone($dbtz);
                $right->setTimezone($dbtz);
    
                    "{$name}__gte" =>  $left->format('Y-m-d H:i:s'),
                    "{$name}__lte" =>  $right->format('Y-m-d H:i:s'),
    
                $int = $intervals[$value['int'] ?: 'd'] ?: 'DAY';
                $interval = new SqlInterval($int, $value['until']);
    
                    "{$name}__range" => array($now->minus($interval), $now),
    
                $int = $intervals[$value['int'] ?: 'd'] ?: 'DAY';
                $interval = new SqlInterval($int, $value['until']);
    
                    "{$name}__range" => array($now, $now->plus($interval)),
    
                ));
            // Distant past and future ranges
            case 'distpast':
                $int = $intervals[$value['int'] ?: 'd'] ?: 'DAY';
                $interval = new SqlInterval($int, $value['until']);
                return new Q(array(
                    "{$name}__lte" => $now->minus($interval),
                ));
            case 'distfut':
                $int = $intervals[$value['int'] ?: 'd'] ?: 'DAY';
                $interval = new SqlInterval($int, $value['until']);
                return new Q(array(
                    "{$name}__gte" => $now->plus($interval),
    
            case 'period':
    
                // User's effective timezone
    
                $tz = new DateTimeZone($cfg->getTimezone());
    
                // Get the period range boundaries in user's tz
                $period = Misc::date_range($value, Misc::gmtime('now'), $tz);
    
                // Convert boundaries to db time
                $dbtz = new DateTimeZone($cfg->getDbTimezone());
    
                $start = $period->start->setTimezone($dbtz);
                $end = $period->end->setTimezone($dbtz);
    
                // Set the range
                return new Q(array(
                    "{$name}__range" => array(
                        $start->format('Y-m-d H:i:s'),
                        $end->format('Y-m-d H:i:s')
                        )
                    ));
                break;
    
            default:
                return parent::getSearchQ($method, $value, $name);
            }
        }
    
    
        function describeSearchMethod($method) {
            switch ($method) {
            case 'before':
                return __('%1$s before %2$s' /* occurs before a date and time */);
            case 'after':
                return __('%1$s after %2$s' /* occurs after a date and time */);
            case 'ndays':
                return __('%1$s in the next %2$s' /* occurs within a window (like 3 days) */);
            case 'ndaysago':
                return __('%1$s in the last %2$s' /* occurs within a recent window (like 3 days) */);
    
            case 'distfut':
                return __('%1$s after %2$s from now' /* occurs after a window (like 3 days) */);
            case 'distpast':
                return __('%1$s before %2$s ago' /* occurs previous to a window (like 3 days) */);
    
            case 'between':
                return __('%1$s between %2$s and %3$s');
    
            case 'future':
                return __('%1$s is in the future');
            case 'past':
                return __('%1$s is in the past');
    
            case 'period':
                return __('%1$s is %2$s');
    
            default:
                return parent::describeSearchMethod($method);
            }
        }
    
        function describeSearch($method, $value, $name=false) {
    
    
            $name = $name ?: $this->get('name');
            $desc = $this->describeSearchMethod($method);
            switch ($method) {
                case 'between':
                    return sprintf($desc, $name,
                            $this->toString($value['left']),
                            $this->toString($value['right']));
                case 'ndays':
                case 'ndaysago':
                case 'distfut':
                case 'distpast':
                    $interval = sprintf('%s %s', $value['until'],
                            self::intervals($value['until'], $value['int']));
                    return sprintf($desc, $name, $interval);
                    break;
                case 'future':
                case 'past':
                    return sprintf($desc, $name);
                case 'before':
                case 'after':
                    return sprintf($desc, $name, $this->toString($value));
    
                case 'period':
                    return sprintf($desc, $name, self::periods($value) ?: $value);
    
                default:
                    return parent::describeSearch($method, $value, $name);
    
    
        function supportsQuickFilter() {
            return true;
        }
    
        function getQuickFilterChoices() {
            return array(
                'h' => __('Today'),
                'm' => __('Tomorrow'),
                'g' => __('Yesterday'),
                'l7' => __('Last 7 days'),
                'l30' => __('Last 30 days'),
                'n7' => __('Next 7 days'),
                'n30' => __('Next 30 days'),
                /* Ugh. These boundaries are so difficult in SQL
                'w' =>  __('This Week'),
                'm' =>  __('This Month'),
                'lw' => __('Last Week'),
                'lm' => __('Last Month'),
                'nw' => __('Next Week'),
                'nm' => __('Next Month'),
                */
            );
        }
    
        function applyQuickFilter($query, $qf_value, $name=false) {
            $name = $name ?: $this->get('name');
            $now = SqlFunction::NOW();
            $midnight = Misc::dbtime(time() - (time() % 86400));
            switch ($qf_value) {
            case 'l7':
                return $query->filter([
                    "{$name}__range" => array($now->minus(SqlInterval::DAY(7)), $now),
                ]);
            case 'l30':
                return $query->filter([
                    "{$name}__range" => array($now->minus(SqlInterval::DAY(30)), $now),
                ]);
            case 'n7':
                return $query->filter([
    
    aydreeihn's avatar
    aydreeihn committed
                    "{$name}__range" => array($now, $now->plus(SqlInterval::DAY(7))),
    
                ]);
            case 'n30':
                return $query->filter([
    
    aydreeihn's avatar
    aydreeihn committed
                    "{$name}__range" => array($now, $now->plus(SqlInterval::DAY(30))),
    
                ]);
            case 'g':
                $midnight -= 86400;
                 // Fall through to the today case
            case 'm':
                if ($qf_value === 'm') $midnight += 86400;
                 // Fall through to the today case
            case 'h':
                $midnight = DateTime::createFromFormat('U', $midnight);
                return $query->filter([
                    "{$name}__range" => array($midnight,
                        SqlExpression::plus($midnight, SqlInterval::DAY(1))),
                ]);
            }
        }
    
    /**
     * This is kind-of a special field that doesn't have any data. It's used as
     * a field to provide a horizontal section break in the display of a form
     */
    class SectionBreakField extends FormField {
    
        static $widget = 'SectionBreakWidget';
    
    
        function hasData() {
            return false;
        }
    
        function isBlockLevel() {
            return true;
        }
    }
    
    class ThreadEntryField extends FormField {
    
        static $widget = 'ThreadEntryWidget';
    
    
        function isChangeable() {
            return false;
        }
        function isBlockLevel() {
            return true;
        }
        function isPresentationOnly() {
            return true;
        }
    
        function getMedia() {
            $config = $this->getConfiguration();
            $media = parent::getMedia() ?: array();
            if ($config['attachments'])
                $media = array_merge_recursive($media, FileUploadWidget::$media);
            return $media;
        }
    
    
    Peter Rotich's avatar
    Peter Rotich committed
        function getConfiguration() {
            global $cfg;
            $config = parent::getConfiguration();
    
            $config['html'] = (bool) ($cfg && $cfg->isRichTextEnabled());
    
    Peter Rotich's avatar
    Peter Rotich committed
            return $config;
        }
    
    
        function getConfigurationOptions() {
            global $cfg;
    
            $attachments = new FileUploadField();
    
            $fileupload_config = $attachments->getConfigurationOptions();
    
    Peter Rotich's avatar
    Peter Rotich committed
            if ($cfg->getAllowedFileTypes())
                $fileupload_config['extensions']->set('default', $cfg->getAllowedFileTypes());
    
    
            foreach ($fileupload_config as $C) {
                $C->set('visibility', new VisibilityConstraint(new Q(array(
                    'attachments__eq'=>true,
                )), VisibilityConstraint::HIDDEN));
            }
    
            return array(
                'attachments' => new BooleanField(array(
                    'label'=>__('Enable Attachments'),
    
                    'default'=>$cfg->allowAttachments(),
    
    Peter Rotich's avatar
    Peter Rotich committed
                        'desc'=>__('Enables attachments, regardless of channel'),
    
                    'validators' => function($self, $value) {
                        if (!ini_get('file_uploads'))
                            $self->addError(__('The "file_uploads" directive is disabled in php.ini'));
                    }
    
            + $fileupload_config;
    
    
        function isAttachmentsEnabled() {
            $config = $this->getConfiguration();
            return $config['attachments'];
        }
    
    Peter Rotich's avatar
    Peter Rotich committed
    
        function getWidget($widgetClass=false) {
    
            if ($hint = $this->getLocal('hint'))
    
    Peter Rotich's avatar
    Peter Rotich committed
                $this->set('placeholder', $hint);
            $this->set('hint', null);
            $widget = parent::getWidget($widgetClass);
            return $widget;
        }
    
    }
    
    class PriorityField extends ChoiceField {
    
    
        var $priorities;
        var $_choices;
    
        function getPriorities() {
            if (!isset($this->priorities))
                $this->priorities = Priority::objects();
    
            return $this->priorities;
        }
    
        function getPriority($id) {
    
            if ($this->getPriorities() &&
                    ($p=$this->priorities->findFirst(array('priority_id' =>
                                                           $id))))
                return $p;
    
            return Priority::lookup($id);
        }
    
    
        function getWidget($widgetClass=false) {
            $widget = parent::getWidget($widgetClass);
    
            if ($widget->value instanceof Priority)
                $widget->value = $widget->value->getId();
            return $widget;
        }
    
    
        function hasIdValue() {
            return true;
        }
    
    
        function getChoices($verbose=false) {
    
            if (!isset($this->_choices)) {
                $choices = array('' => '— '.__('Default').' —');
                foreach ($this->getPriorities() as $p)
                    $choices[$p->getId()] = $p->getDesc();
                $this->_choices = $choices;
            }
    
            return $this->_choices;
    
        }
    
        function parse($id) {
            return $this->to_php(null, $id);
        }
    
    
        function to_php($value, $id=false) {
    
            if ($value instanceof Priority)
                return $value;
    
            if (is_array($id)) {
                reset($id);
                $id = key($id);
            }
    
            elseif (is_array($value))
                list($value, $id) = $value;
    
            elseif ($id === false)
                $id = $value;
    
    
            return $this->getPriority($id);
    
        }
    
        function to_database($prio) {
            return ($prio instanceof Priority)
                ? array($prio->getDesc(), $prio->getId())
                : $prio;
        }
    
    
        function display($prio, &$styles=null) {
    
            if (!$prio instanceof Priority)
                return parent::display($prio);
    
            if (is_array($styles))
                $styles += array(
                    'background-color' => $prio->getColor()
                );
            return Format::htmlchars($prio->getDesc());
    
        function toString($value) {
            return ($value instanceof Priority) ? $value->getDesc() : $value;
        }
    
    
        function whatChanged($before, $after) {
            return FormField::whatChanged($before, $after);
        }
    
    
        function searchable($value) {
            // Priority isn't searchable this way
            return null;
        }
    
    
        function getKeys($value) {
            return ($value instanceof Priority) ? array($value->getId()) : null;
        }
    
    
        function asVar($value, $id=false) {
            return $this->to_php($value, $id);
        }
    
    
        function getConfigurationOptions() {
    
            $choices = $this->getChoices();
            $choices[''] = __('System Default');
    
            return array(
                'prompt' => new TextboxField(array(
    
                    'id'=>2, 'label'=>__('Prompt'), 'required'=>false, 'default'=>'',
                    'hint'=>__('Leading text shown before a value is selected'),
    
                    'configuration'=>array('size'=>40, 'length'=>40),
                )),
    
                'default' => new ChoiceField(array(
                    'id'=>3, 'label'=>__('Default'), 'required'=>false, 'default'=>'',
                    'choices' => $choices,
                    'hint'=>__('Default selection for this field'),
                    'configuration'=>array('size'=>20, 'length'=>40),
                )),
    
    
        function getConfiguration() {
            global $cfg;
    
            $config = parent::getConfiguration();
            if (!isset($config['default']))
                $config['default'] = $cfg->getDefaultPriorityId();
            return $config;
        }
    
    
        function applyOrderBy($query, $reverse=false, $name=false) {
            if ($query->model == 'Ticket' && $name == 'cdata__priority') {
                // Order by the priority urgency field
                $col = 'cdata__:priority__priority_urgency';
                $reverse = !$reverse;
            }
            else {
                $col = $name ?: CustomQueue::getOrmPath($this->get('name'), $query);
            }
            if ($reverse)
                $col = "-$col";
            return $query->order_by($col);
        }
    
    FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
    
        return array(
    
    Marco Borla's avatar
    Marco Borla committed
            'priority' => array(__('Priority Level'), 'PriorityField'),
    
    Peter Rotich's avatar
    Peter Rotich committed
    class TimezoneField extends ChoiceField {
        static $widget = 'TimezoneWidget';
    
        function hasIdValue() {
            return false;
        }
    
        function getChoices($verbose=false) {
            global $cfg;
    
            $choices = array();
            foreach (DateTimeZone::listIdentifiers() as $zone)
                $choices[$zone] =  str_replace('/',' / ',$zone);
    
            return $choices;
        }
    
    
    Peter Rotich's avatar
    Peter Rotich committed
        function whatChanged($before, $after) {
            return FormField::whatChanged($before, $after);
        }
    
    
    Peter Rotich's avatar
    Peter Rotich committed
        function searchable($value) {
            return null;
        }
    
        function getConfigurationOptions() {
            return array(
                'autodetect' => new BooleanField(array(
                    'id'=>1, 'label'=>__('Auto Detect'), 'required'=>false, 'default'=>true,
                    'configuration'=>array(
                        'desc'=>__('Add Auto Detect Button'))
                )),
                'prompt' => new TextboxField(array(
                    'id'=>2, 'label'=>__('Prompt'), 'required'=>false, 'default'=>'',
                    'hint'=>__('Leading text shown before a value is selected'),
                    'configuration'=>array('size'=>40, 'length'=>40),
                )),
            );
        }
    }
    
    
    
    class DepartmentField extends ChoiceField {
    
        function getWidget($widgetClass=false) {
            $widget = parent::getWidget($widgetClass);
    
            if ($widget->value instanceof Dept)
                $widget->value = $widget->value->getId();
            return $widget;
        }
    
        function hasIdValue() {
            return true;
        }
    
    
        function getChoices($verbose=false) {
    
            global $cfg;
    
    
            $selected = self::getWidget();
    
            if($selected && $selected->value) {
              if(is_array($selected->value)) {
                foreach ($selected->value as $k => $v) {
    
                  $current_id = $k;
                  $current_name = $v;
                }
              }
              else {
                $current_id = $selected->value;
                $current_name = Dept::getNameById($current_id);
              }
            }
    
    
            $active_depts = Dept::objects()
              ->filter(array('flags__hasbit' => Dept::FLAG_ACTIVE))
    
              ->values('id', 'name')
              ->order_by('name');
    
            $choices = array();
    
            if ($depts = Dept::getDepartments(null, true, Dept::DISPLAY_DISABLED)) {
    
              //create array w/queryset
              $active = array();
              foreach ($active_depts as $dept)
                $active[$dept['id']] = $dept['name'];
    
              //add selected dept to list
    
              if($current_id)
                $active[$current_id] = $current_name;
              else
                return $active;
    
                $choices[$id] = $name;
                if(!array_key_exists($id, $active) && $current_id)
    
    
            return $choices;
        }
    
        function parse($id) {
            return $this->to_php(null, $id);
        }
    
        function to_php($value, $id=false) {
    
    JediKev's avatar
    JediKev committed
            if ($id) {
                if (is_array($id)) {
                    reset($id);
                    $id = key($id);
                }
                return $id;
            } else {
                return $value;
    
            }
        }
    
        function to_database($dept) {
    
    JediKev's avatar
    JediKev committed
            if ($dept instanceof Dept)
                return array($dept->getName(), $dept->getId());
    
            if (!is_array($dept)) {
                $choices = $this->getChoices();
                if (isset($choices[$dept]))
                    $dept = array($choices[$dept], $dept);
            }
            if (!$dept)
                $dept = array();
    
            return $dept;
    
        }
    
        function toString($value) {
    
    JediKev's avatar
    JediKev committed
            if (!is_array($value))
                $value = $this->getChoice($value);
            if (is_array($value))
                return implode(', ', $value);
    
            return (string) $value;
        }
    
    
    JediKev's avatar
    JediKev committed
        function getChoice($value) {
            $choices = $this->getChoices();
            $selection = array();
            if ($value && is_array($value)) {
                $selection = $value;
            } elseif (isset($choices[$value])) {
                $selection[] = $choices[$value];
            }
    
            return $selection;
        }
    
    
        function searchable($value) {
            return null;
        }
    
        function getConfigurationOptions() {
            return array(
                'prompt' => new TextboxField(array(
                    'id'=>2, 'label'=>__('Prompt'), 'required'=>false, 'default'=>'',
                    'hint'=>__('Leading text shown before a value is selected'),
                    'configuration'=>array('size'=>40, 'length'=>40),
                )),
            );
        }
    }
    FormField::addFieldTypes(/*@trans*/ 'Dynamic Fields', function() {
        return array(
    
    Marco Borla's avatar
    Marco Borla committed
            'department' => array(__('Department'), 'DepartmentField'),