[Rt-commit] r3045 - in rt/branches/3.4-RELEASE: . html/Search
lib/RT/Interface/Web lib/RT/Interface/Web/QueryBuilder
glasser at bestpractical.com
glasser at bestpractical.com
Wed Jun 1 18:35:35 EDT 2005
Author: glasser
Date: Wed Jun 1 18:35:33 2005
New Revision: 3045
Added:
rt/branches/3.4-RELEASE/lib/RT/Interface/Web/QueryBuilder/
rt/branches/3.4-RELEASE/lib/RT/Interface/Web/QueryBuilder.pm (contents, props changed)
rt/branches/3.4-RELEASE/lib/RT/Interface/Web/QueryBuilder/Tree.pm (contents, props changed)
Modified:
rt/branches/3.4-RELEASE/ (props changed)
rt/branches/3.4-RELEASE/html/Search/Build.html
Log:
r33106 at tin-foil: glasser | 2005-05-26 01:21:29 -0400
Move stuff out from html/Search/Build.html into a module; refactor some of the code there.
Modified: rt/branches/3.4-RELEASE/html/Search/Build.html
==============================================================================
--- rt/branches/3.4-RELEASE/html/Search/Build.html (original)
+++ rt/branches/3.4-RELEASE/html/Search/Build.html Wed Jun 1 18:35:33 2005
@@ -61,7 +61,7 @@
<table width=100% border="0" cellpadding="5">
<tr valign="top">
<td class="boxcontainer" rowspan="2" width="65%">
-<& Elements/PickCriteria, query => $Query, cfqueues => \%queues &>
+<& Elements/PickCriteria, query => $Query, cfqueues => $queues &>
<& /Elements/Submit, Caption => loc('Add additional criteria'), Label => loc('Add'), Name => 'AddClause'&>
</td>
@@ -96,7 +96,8 @@
</FORM>
<%INIT>
-use Tree::Simple;
+use RT::Interface::Web::QueryBuilder;
+use RT::Interface::Web::QueryBuilder::Tree;
my $search_hash = {};
my $search;
@@ -146,7 +147,6 @@
# }}}
my @actions = ();
-my %queues;
# Clean unwanted junk from the format
$Format = $m->comp( '/Elements/ScrubHTML', Content => $Format ) if ($Format);
@@ -246,7 +246,6 @@
}
$Query = "";
-%queues = ();
my @options = get_displayed_nodes($tree);
@@ -315,7 +314,7 @@
Value => $value
};
- my $newnode = Tree::Simple->new($clause);
+ my $newnode = RT::Interface::Web::QueryBuilder::Tree->new($clause);
if (@current_values) {
foreach my $value (@current_values) {
my $newindex = $value->getIndex() + 1;
@@ -405,7 +404,7 @@
my $sibling = $parent->getChild( $index - 1 );
if ( ref( $sibling->getNodeValue ) ) {
$parent->removeChild($value);
- my $newtree = Tree::Simple->new( 'AND', $parent );
+ my $newtree = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent );
$newtree->addChild($value);
}
else {
@@ -415,7 +414,7 @@
}
else {
$parent->removeChild($value);
- $newparent = Tree::Simple->new( 'AND', $parent );
+ $newparent = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $parent );
$newparent->addChild($value);
}
}
@@ -451,16 +450,23 @@
}
}
elsif ( $ARGS{"Clear"} ) {
- $tree = Tree::Simple->new( Tree::Simple->ROOT );
+ $tree = RT::Interface::Web::QueryBuilder::Tree->new;
}
# }}}
# {{{ Rebuild $Query based on the additions / movements
$Query = "";
-%queues = ();
-my $optionlist =
- build_array( \$Query, \@current_values, $tree, \%queues );
+my($optionlist_arrayref, $queues);
+
+($optionlist_arrayref, $Query, $queues) =
+ RT::Interface::Web::QueryBuilder::TreeToQueryAndOptionListAndQueues( $tree, \@current_values );
+
+my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>)
+ . (" " x (5 * $_->{DEPTH}))
+ . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref;
+
+
# This function returns an array ref of the nodes of the tree in depth-first
# order which correspond to options in the "clauses" multi-select box.
@@ -478,112 +484,6 @@
return @keys;
}
-sub build_array {
- my $Query = shift;
- my $values_ref = shift;
- my $tree = shift;
- my $queues = shift;
-
- my $i = 0;
- my @optionlist;
- my $depth = 0;
- my %parens;
-
- $tree->traverse(
- sub {
- my ($_tree) = @_;
-
- return if $_tree->getParent->isRoot();
-
- my $clause = $_tree->getNodeValue();
- my $str;
- my $ea = $_tree->getParent()->getNodeValue();
- if ( ref($clause) ) {
- $str .= $ea . " " if $_tree->getIndex() > 0;
- $str .=
- $clause->{Key} . " " . $clause->{Op} . " " . $clause->{Value};
-
- if ( $clause->{Key} eq "Queue" ) {
- $queues->{ $clause->{Value} } = 1;
- }
- }
- else {
- $str = $ea if $_tree->getIndex() > 0;
- }
-
- my $selected;
- if ( grep { $_ == $_tree } @$values_ref ) {
- $selected = "SELECTED";
- }
- else {
- $selected = "";
- }
-
- # These two variables are for display in the optionlists only.
- my $before_parens = '';
- my $after_parens = '';
-
- foreach my $p ( keys %parens ) {
- if ( $p > $_tree->getDepth ) {
- $$Query .= ')' x $parens{$p};
- # The fact that I am writing this line implies
- # that the whole function should be rewritten, because
- # it ought to be possible to have figured out this
- # information earlier:
- $optionlist[-1]{TEXT} .= ')' x $parens{$p};
- $parens{$p}--;
- }
- }
-
- my $parent = $_tree->getParent();
- if ( !( $parent->isRoot || $parent->getParent()->isRoot )
- && !ref( $parent->getNodeValue() ) )
- {
- if ( $_tree->getIndex() == 0 ) {
- $$Query .= '(';
- $before_parens .= '(';
- $parens{ $_tree->getDepth }++;
- }
- }
- $$Query .= " " . $str . " ";
-
- if ( $_tree->getDepth < $depth ) {
- $$Query .= ')';
- $after_parens .= ')';
- $parens{$depth}--;
- }
-
- push @optionlist, {
- TEXT => $before_parens . $str . $after_parens,
- INDEX => $i,
- SELECTED => $selected,
- DEPTH => $_tree->getDepth() - 1,
- };
-
- $i++;
- }
- );
-
- foreach my $p ( keys %parens ) {
- $$Query .= ") " x $parens{$p};
- $optionlist[-1]{TEXT} .= ") " x $parens{$p};
- }
-
- my $should_be_query = join ' ', map { $_->{TEXT} } @optionlist;
-
-# So, $should_be_query *ought* to be the same as $$Query but calculated in a much
-# simpler way, but this has not been tested enough to make sure, so I won't commit it.
-# my $sbq_tmp = $should_be_query;
-# my $q_tmp = $$Query;
-# $sbq_tmp =~ tr/ //d; $q_tmp =~ tr/ //d;
-# $RT::Logger->crit("query check: " . ($q_tmp eq $sbq_tmp ? 'yay' : 'nay') );
-
- return join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>)
- . (" " x (5 * $_->{DEPTH}))
- . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @optionlist;
-
-}
-
use Regexp::Common qw /delimited/;
# States
@@ -603,8 +503,8 @@
my $depth = 1;
# make a tree root
- $$tree = Tree::Simple->new( Tree::Simple->ROOT );
- my $root = Tree::Simple->new( 'AND', $$tree );
+ $$tree = RT::Interface::Web::QueryBuilder::Tree->new;
+ my $root = RT::Interface::Web::QueryBuilder::Tree->new( 'AND', $$tree );
my $lastnode = $root;
my $parentnode = $root;
@@ -677,7 +577,7 @@
$depth++;
# make a new node that the clauses can be children of
- $parentnode = Tree::Simple->new( $ea, $parentnode );
+ $parentnode = RT::Interface::Web::QueryBuilder::Tree->new( $ea, $parentnode );
}
else {
$depth--;
@@ -745,7 +645,7 @@
};
# explicity add a child to it
- $lastnode = Tree::Simple->new( $clause, $parentnode );
+ $lastnode = RT::Interface::Web::QueryBuilder::Tree->new( $clause, $parentnode );
$lastnode->getParent()->setNodeValue($ea);
( $ea, $key, $op, $value ) = ( "", "", "", "" );
@@ -788,7 +688,7 @@
my ( $AvailableColumns, $CurrentFormat );
( $Format, $AvailableColumns, $CurrentFormat ) = $m->comp(
'Elements/BuildFormatString',
- cfqueues => \%queues,
+ cfqueues => $queues,
%ARGS, Format => $Format
);
Added: rt/branches/3.4-RELEASE/lib/RT/Interface/Web/QueryBuilder.pm
==============================================================================
--- (empty file)
+++ rt/branches/3.4-RELEASE/lib/RT/Interface/Web/QueryBuilder.pm Wed Jun 1 18:35:33 2005
@@ -0,0 +1,135 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+# <jesse at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+package RT::Interface::Web::QueryBuilder;
+
+use strict;
+use warnings;
+
+sub TreeToQueryAndOptionListAndQueues {
+ my $tree = shift;
+ my $selected_nodes = shift;
+
+ my $Query = '';
+ my $queues = {};
+ my $optionlist = [];
+
+ my $i = 0;
+
+ $tree->traverse_pre_post(
+ sub { # This is called before recursing to the node's children.
+ my $node = shift;
+
+ return if $node->isRoot or $node->getParent->isRoot;
+
+ my $clause = $node->getNodeValue();
+ my $str = ' ';
+ my $aggregator_context = $node->getParent()->getNodeValue();
+ $str = $aggregator_context . " " if $node->getIndex() > 0;
+
+ if ( ref($clause) ) { # ie, it's a leaf
+ $str .=
+ $clause->{Key} . " " . $clause->{Op} . " " . $clause->{Value};
+
+ if ( $clause->{Key} eq "Queue" ) {
+ $queues->{ $clause->{Value} } = 1;
+ }
+ }
+
+ my $selected = '';
+ if ( grep { $_ == $node } @$selected_nodes ) {
+ $selected = "SELECTED";
+ }
+
+ unless ($node->getParent->getParent->isRoot) {
+ # used to check !ref( $parent->getNodeValue() ) )
+ if ( $node->getIndex() == 0 ) {
+ $str = '( ' . $str;
+ }
+ }
+
+ $Query .= " " . $str . " ";
+
+ push @$optionlist, {
+ TEXT => $str,
+ INDEX => $i,
+ SELECTED => $selected,
+ DEPTH => $node->getDepth() - 1,
+ };
+
+ $i++;
+ }, sub {
+ # This is called after recursing to the node's children.
+ my $node = shift;
+
+ return if $node->isRoot or $node->getParent->isRoot or $node->getParent->getParent->isRoot;
+
+ # Only do this for the rightmost child.
+ return unless $node->getIndex == $node->getParent->getChildCount - 1;
+
+ $Query .= ' )';
+ $optionlist->[-1]{TEXT} .= ' )';
+ }
+ );
+
+ my $should_be_query = join ' ', map { $_->{TEXT} } @$optionlist;
+
+# So, $should_be_query *ought* to be the same as $Query but calculated in a much
+# simpler way, but this has not been tested enough to make sure, so I won't commit it.
+# my $sbq_tmp = $should_be_query;
+# my $q_tmp = $Query;
+# $sbq_tmp =~ tr/ //d; $q_tmp =~ tr/ //d;
+# $RT::Logger->crit("query check: " . ($q_tmp eq $sbq_tmp ? 'yay' : 'nay') );
+
+ return $optionlist, $Query, $queues;
+}
+
+
+eval "require RT::Interface::Web::QueryBuilder_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Vendor.pm});
+eval "require RT::Interface::Web::QueryBuilder_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Local.pm});
+
+1;
Added: rt/branches/3.4-RELEASE/lib/RT/Interface/Web/QueryBuilder/Tree.pm
==============================================================================
--- (empty file)
+++ rt/branches/3.4-RELEASE/lib/RT/Interface/Web/QueryBuilder/Tree.pm Wed Jun 1 18:35:33 2005
@@ -0,0 +1,79 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+# <jesse at bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+package RT::Interface::Web::QueryBuilder::Tree;
+
+use strict;
+use warnings;
+
+use base qw/Tree::Simple/;
+
+=head2 traverse_pre_post PREFUNC POSTFUNC
+
+Traverses the tree depth-first. Before processing the node's children,
+calls PREFUNC with the node as its argument; after processing all of the
+children, calls POSTFUNC with the node as its argument.
+
+=cut
+
+sub traverse_pre_post {
+ my ($self, $prefunc, $postfunc) = @_;
+
+ $prefunc->($self);
+
+ foreach my $child ($self->getAllChildren()) {
+ $child->traverse_pre_post($prefunc, $postfunc);
+ }
+
+ $postfunc->($self);
+}
+
+
+eval "require RT::Interface::Web::QueryBuilder::Tree_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Vendor.pm});
+eval "require RT::Interface::Web::QueryBuilder::Tree_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Local.pm});
+
+1;
More information about the Rt-commit
mailing list