diff --git a/include/class.forms.php b/include/class.forms.php index 71a5c717b778005487445aabfb2acb7192fa80a5..516c7db9fd684b8da23eff339af387abc82fd902 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -1014,6 +1014,33 @@ class FormField { return $row[$name ?: $this->get('name')]; } + /** + * If the field can be used in a quick filter. To be used, it should + * also implement getQuickFilterChoices() which should return a list of + * choices to appear in a quick filter drop-down + */ + function supportsQuickFilter() { + return false; + } + + /** + * Fetch a keyed array of quick filter choices. The keys should be + * passed later to ::applyQuickFilter() to apply the quick filter to a + * query. The values should be localized titles for the choices. + */ + function getQuickFilterChoices() { + return array(); + } + + /** + * Apply a quick filter selection of this field to the query. The + * modified query should be returned. Optionally, the orm path / field + * name can be passed. + */ + function applyQuickFilter($query, $choice, $name=false) { + return $query; + } + function getLabel() { return $this->get('label'); } /** @@ -1535,6 +1562,23 @@ class BooleanField extends FormField { return parent::getSearchQ($method, $value, $name); } } + + function supportsQuickFilter() { + return true; + } + + function getQuickFilterChoices() { + return array( + true => __('Checked'), + false => __('Not Checked'), + ); + } + + function applyQuickFilter($query, $qf_value, $name=false) { + return $query->filter(array( + $name ?: $this->get('name') => (int) $qf_value, + )); + } } class ChoiceField extends FormField { @@ -1766,6 +1810,20 @@ class ChoiceField extends FormField { return parent::describeSearchMethod($method); } } + + function supportsQuickFilter() { + return true; + } + + function getQuickFilterChoices() { + return $this->getChoices(); + } + + function applyQuickFilter($query, $qf_value, $name=false) { + return $query->filter(array( + $name ?: $this->get('name') => $qf_value, + )); + } } class DatetimeField extends FormField { diff --git a/include/class.orm.php b/include/class.orm.php index afb6ede9f7bd78adaed577d21bbef00b6eb26f65..f67611ae98dd5af9b41ab53686d84e5534c1098d 100644 --- a/include/class.orm.php +++ b/include/class.orm.php @@ -866,10 +866,15 @@ class SqlExpression extends SqlFunction { case 'bitor': $operator = '|'; break; default: - throw new InvalidArgumentException('Invalid operator specified'); + throw new InvalidArgumentException($operator.': Invalid operator specified'); } return parent::__callStatic($operator, $operands); } + + function __call($operator, $operands) { + array_unshift($operands, $this); + return static::__callStatic($operator, $operands); + } } class SqlInterval extends SqlFunction { @@ -2615,7 +2620,7 @@ class MySqlCompiler extends SqlCompiler { function __range($a, $b) { // XXX: Crash if $b is not array of two items - return sprintf('%s BETWEEN %s AND %s', $a, $b[0], $b[1]); + return sprintf('%s BETWEEN %s AND %s', $a, $this->input($b[0]), $this->input($b[1])); } function compileJoin($tip, $model, $alias, $info, $extra=false) { diff --git a/include/class.queue.php b/include/class.queue.php index 821b30514096018abd440d6f3685a16d0547e1ce..e18749e29b59e80d8e374adc1e757a62afa85ce8 100644 --- a/include/class.queue.php +++ b/include/class.queue.php @@ -6,7 +6,7 @@ Jared Hancock <jared@osticket.com> Peter Rotich <peter@osticket.com> - Copyright (c) 2006-2013 osTicket + Copyright (c) 2006-2015 osTicket http://www.osticket.com Released under the GNU General Public License WITHOUT ANY WARRANTY. @@ -125,7 +125,7 @@ class CustomQueue extends SavedSearch { function getPublicChildren() { return $this->children->findAll(array( - 'flags__hasbit' => self::FLAG_PUBLIC + 'flags__hasbit' => self::FLAG_QUEUE )); } @@ -163,14 +163,36 @@ class CustomQueue extends SavedSearch { * Returns: * <QuerySet> instance */ - function getQuery($form=false) { + function getQuery($form=false, $quick_filter=false) { + // Start with basic criteria $query = $this->getBasicQuery($form); + + // Apply quick filter + if (isset($quick_filter) + && ($qf = $this->getQuickFilterField($quick_filter)) + ) { + $query = $qf->applyQuickFilter($query, $quick_filter, + $this->filter); + } + + // Apply column, annotations and conditions additions foreach ($this->getColumns() as $C) { $query = $C->mangleQuery($query); } return $query; } + function getQuickFilterField($value=null) { + if ($this->filter + && ($fields = SavedSearch::getSearchableFields($this->getRoot())) + && ($f = @$fields[$this->filter]) + && $f->supportsQuickFilter() + ) { + $f->value = $value; + return $f; + } + } + function update($vars, &$errors) { // TODO: Move this to SavedSearch::update() and adjust // AjaxSearch::_saveSearch() @@ -186,6 +208,7 @@ class CustomQueue extends SavedSearch { // Set basic queue information $this->title = $vars['name']; $this->parent_id = $vars['parent_id']; + $this->filter = $vars['filter']; // Update queue columns (but without save) if (isset($vars['columns'])) { diff --git a/include/class.user.php b/include/class.user.php index a3b98f381b61d1e341ae647ce131fa60fcf28528..7a5fe572a0013fe50594150d54f7033fc7040c4e 100644 --- a/include/class.user.php +++ b/include/class.user.php @@ -621,7 +621,7 @@ implements TemplateVariable, Searchable { if (!$id || !$thisstaff) return false; - return ROOT_PATH . sprintf('users.php?id=%s', $id); + return ROOT_PATH . sprintf('scp/users.php?id=%s', $id); } } diff --git a/include/staff/queue.inc.php b/include/staff/queue.inc.php index f01789c5405ffbb781cae3793d344a611d6b00b2..8d4cdd50989e97630719dd181d0d11f5ddce012a 100644 --- a/include/staff/queue.inc.php +++ b/include/staff/queue.inc.php @@ -85,10 +85,15 @@ else { <br/> <div><strong><?php echo __("Quick Filter"); ?></strong></div> <hr/> - <select name="quick-filter"> - <option value=":p:">— <?php echo __('Inherit from parent'); ?> —</option> -<?php foreach (SavedSearch::getSearchableFields('Ticket') as $path=>$f) { ?> - <option value="<?php echo $path; ?>"><?php echo $f->get('label'); ?></option> + <select name="filter"> + <option value="::">— <?php echo __('Inherit from parent'); ?> —</option> +<?php foreach (SavedSearch::getSearchableFields('Ticket') as $path=>$f) { + if (!$f->supportsQuickFilter()) + continue; +?> + <option value="<?php echo $path; ?>" + <?php if ($path == $queue->filter) echo 'selected="selected"'; ?> + ><?php echo $f->get('label'); ?></option> <?php } ?> </select> <br/> diff --git a/include/staff/templates/queue-preview.tmpl.php b/include/staff/templates/queue-preview.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..32d664d906b4fa0d6076b0dd888275ad8de3af8e --- /dev/null +++ b/include/staff/templates/queue-preview.tmpl.php @@ -0,0 +1,40 @@ +<?php +// Calling convention (assumed global scope): +// $tickets - <QuerySet> with all columns and annotations necessary to +// render the full page +// $count - <int> number of records matching the search / filter part of the +// query + +$page = ($_GET['p'] && is_numeric($_GET['p']))?$_GET['p']:1; +$pageNav = new Pagenate($count, $page, PAGE_LIMIT); +$pageNav->setURL('tickets.php', $args); +$tickets = $pageNav->paginate($tickets); + +// Identify columns of output +$columns = $queue->getColumns(); + +?> +<table class="list" border="0" cellspacing="1" cellpadding="2" width="940"> + <thead> + <tr> +<?php +foreach ($columns as $C) { + echo sprintf('<th width="%s">%s</th>', $C->getWidth(), + Format::htmlchars($C->getHeading())); +} ?> + </tr> + </thead> + <tbody> +<?php +foreach ($tickets as $T) { + echo '<tr>'; + foreach ($columns as $C) { + echo "<td>"; + echo $C->render($T); + echo "</td>"; + } + echo '</tr>'; +} +?> + </tbody> +</table> diff --git a/include/staff/templates/queue-quickfilter.tmpl.php b/include/staff/templates/queue-quickfilter.tmpl.php new file mode 100644 index 0000000000000000000000000000000000000000..6b288f49484f3887ef7a2b23e67e76666c5250e3 --- /dev/null +++ b/include/staff/templates/queue-quickfilter.tmpl.php @@ -0,0 +1,47 @@ +<?php +# Calling conventions +# +# $queue - <CustomQueue> queue with quick filter options +# $quick_filter - <string> selected quick filter choice +# $param - <string> URL param to use when selecting an item from the list + +if (!$queue || !$queue->filter) + return; + +$param = $param ?: 'filter'; +$quick_filter = $quick_filter ?: $_REQUEST[$param]; + +if (!($qf_field = $queue->getQuickFilterField($quick_filter))) + return; + +$choices = $qf_field->getQuickFilterChoices(); +?> +<span class="action-button muted" data-dropdown="#quickfilter-dropdown"> + <i class="icon-caret-down pull-right"></i> + <span><i class="icon-filter"></i> <?php + echo $qf_field->get('label'); + if (isset($quick_filter) && isset($choices[$quick_filter])) + echo sprintf(': %s', Format::htmlchars($choices[$quick_filter])); ?></span> +</span> + + +<div id="quickfilter-dropdown" class="action-dropdown anchor-right" +onclick="javascript: +var query = addSearchParam({'<?php echo $param; ?>': $(event.target).data('value')}); +$.pjax({ + url: '?' + query, + timeout: 2000, + container: '#pjax-container'});"> + <ul> + <?php foreach ($choices as $k=>$desc) { + $selected = isset($quick_filter) && $quick_filter == $k; + ?> + <li <?php + if ($selected) echo 'class="active"'; + ?>> + <a href="#" data-value="<?php echo Format::htmlchars($k); ?>"> + <?php echo Format::htmlchars($desc); ?></a> + </li> + <?php } ?> + </ul> +</div> diff --git a/include/staff/templates/queue-tickets.tmpl.php b/include/staff/templates/queue-tickets.tmpl.php index e3f35a79366f547696055d34058844235c2de2fd..282ae7bd2744e6274a049b281b615238fd2ef55f 100644 --- a/include/staff/templates/queue-tickets.tmpl.php +++ b/include/staff/templates/queue-tickets.tmpl.php @@ -35,7 +35,8 @@ $refresh_url = $path . '?' . http_build_query($args); <div class="pull-right" style="height:25px"> <span class="valign-helper"></span> <?php - require STAFFINC_DIR.'templates/queue-sort.tmpl.php'; + require 'queue-quickfilter.tmpl.php'; + require 'queue-sort.tmpl.php'; ?> </div> <form action="tickets.php" method="get" onsubmit="javascript: diff --git a/scp/tickets.php b/scp/tickets.php index 15b96085f13b49ab600e14135638d3af05623e5d..813bec08a41c237704a0c61cac433e47deb0e952 100644 --- a/scp/tickets.php +++ b/scp/tickets.php @@ -457,7 +457,8 @@ if($ticket) { elseif (isset($queue) && $queue) { // XXX: Check staff access? $inc = 'templates/queue-tickets.tmpl.php'; - $tickets = $queue->getQuery(); + $quick_filter = @$_REQUEST['filter']; + $tickets = $queue->getQuery(false, $quick_filter); $count = count($tickets); }