RT# 77021 - fixed advanced report criteria so agent and other fileds with a . in...
[freeside.git] / rt / share / html / Search / Build.html
index 9507a2d..cffcbf4 100644 (file)
@@ -2,7 +2,7 @@
 %#
 %# COPYRIGHT:
 %#
-%# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+%# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
 %#                                          <sales@bestpractical.com>
 %#
 %# (Except where explicitly superseded by other copyright notices)
@@ -53,7 +53,7 @@
 %#   Build/Edit.html (Advanced).)
 %#
 %#   After doing some stuff with default arguments and saved searches, the ParseQuery
-%#   function (which is similar to, but not the same as, _parser in RT/Tickets_Overlay_SQL)
+%#   function (which is similar to, but not the same as, _parser in lib/RT/Tickets.pm)
 %#   converts the Query into a RT::Interface::Web::QueryBuilder::Tree.  This mason file
 %#   then adds stuff to or modifies the tree based on the actions that had been requested
 %#   by clicking buttons.  It then calls GetQueryAndOptionList on the tree to generate
 %#   action does quote it (this breaks SQLite).
 %#
 <& /Elements/Header, Title => $title &>
-<& /Ticket/Elements/Tabs, 
-    current_tab => "Search/Build.html?".$QueryString, 
-    Title => $title,
-    %query,
-    SavedSearchId => $saved_search{'Id'},
-    SavedChartSearchId => $ARGS{SavedChartSearchId},
-&>
-
-<form method="post" action="Build.html" name="BuildQuery">
+<& /Elements/Tabs, %TabArgs &>
+<form method="post" action="Build.html" name="BuildQuery" id="BuildQuery">
 <input type="hidden" class="hidden" name="SavedSearchId" value="<% $saved_search{'Id'} %>" />
 <input type="hidden" class="hidden" name="SavedChartSearchId" value="<% $ARGS{'SavedChartSearchId'} %>" />
 <input type="hidden" class="hidden" name="Query" value="<% $query{'Query'} %>" />
@@ -84,9 +77,9 @@
 
 
 <div id="pick-criteria">
-    <& Elements/PickCriteria, query => $query{'Query'}, cfqueues => $queues &>
-<& /Elements/Submit,  Label => loc('Add these terms'), Name => 'AddClause'&>
-<& /Elements/Submit, Label => loc('Add these terms and Search'), Name => 'DoSearch'&>
+    <& Elements/PickCriteria, query => $query{'Query'}, queues => $queues &>
+<& /Elements/Submit,  Label => loc('Add these terms'), SubmitId => 'AddClause', Name => 'AddClause'&>
+<& /Elements/Submit, Label => loc('Add these terms and Search'), SubmitId => 'DoSearch', Name => 'DoSearch'&>
 </div>
 
 
     AvailableColumns => $AvailableColumns,
     CurrentFormat    => $CurrentFormat,
 &>
-<& /Elements/Submit, Label => loc('Update format and Search'), Name => 'DoSearch', id=>"formatbuttons"&>
 </span>
+<& /Elements/Submit, Label => loc('Update format and Search'), Name => 'DoSearch', id=>"formatbuttons"&>
 </form>
 
 <%INIT>
@@ -146,7 +139,11 @@ if ( $NewQuery ) {
 
     my $current = $session{'CurrentSearchHash'};
     my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {};
-    my $default = { Query => '', Format => '', OrderBy => 'id', Order => 'ASC', RowsPerPage => 50 };
+    my $default = { Query => '',
+                    Format => '',
+                    OrderBy => RT->Config->Get('DefaultSearchResultOrderBy'),
+                    Order => RT->Config->Get('DefaultSearchResultOrder'),
+                    RowsPerPage => 50 };
 
     for( qw(Query Format OrderBy Order RowsPerPage) ) {
         $query{$_} = $current->{$_} unless defined $query{$_};
@@ -179,16 +176,30 @@ my $tree = $ParseQuery->( $query{'Query'}, \@parse_results );
 
 # if parsing went poorly, send them to the edit page to fix it
 if ( @parse_results ) {
-    return $m->comp( "Edit.html", Query => $query{'Query'}, actions => \@actions );
+    push @actions, @parse_results;
+    return $m->comp(
+        "Edit.html",
+        Query => $query{'Query'},
+        Format => $query{'Format'},
+        SavedSearchId => $saved_search{'Id'},
+        SavedChartSearchId => $ARGS{'SavedChartSearchId'},
+        actions => \@actions,
+    );
 }
 
 my @options = $tree->GetDisplayedNodes;
 my @current_values = grep defined, @options[@clauses];
 my @new_values = ();
 
-# {{{ Try to find if we're adding a clause
+my $cf_field_names =
+    join "|",
+     map quotemeta,
+    grep { $RT::Tickets::FIELD_METADATA{$_}->[0] eq 'CUSTOMFIELD' }
+    sort keys %RT::Tickets::FIELD_METADATA;
+
+# Try to find if we're adding a clause
 foreach my $arg ( keys %ARGS ) {
-    next unless $arg =~ m/^ValueOf(\w+|'CF.{.*?}')$/
+    next unless $arg =~ m/^ValueOf([\w\.]+|($cf_field_names).\{.*?\})$/
                 && ( ref $ARGS{$arg} eq "ARRAY"
                      ? grep $_ ne '', @{ $ARGS{$arg} }
                      : $ARGS{$arg} ne '' );
@@ -218,35 +229,36 @@ foreach my $arg ( keys %ARGS ) {
     for ( my $i = 0; $i < @ops; $i++ ) {
         my ( $op, $value ) = ( $ops[$i], $values[$i] );
         next if !defined $value || $value eq '';
+        my $rawvalue = $value;
 
-        if ( $value eq 'NULL' && $op =~ /=/ ) {
+        if ( $value =~ /^NULL$/i && $op =~ /=/ ) {
             if ( $op eq '=' ) {
                 $op = "IS";
             }
             elsif ( $op eq '!=' ) {
                 $op = "IS NOT";
             }
-
-            # This isn't "right", but...
-            # It has to be this way until #5182 is fixed
-            $value = "'NULL'";
         }
-        else {
-            $value =~ s/'/\\'/g;
-            $value = "'$value'" unless $value =~ /^\d+$/;
+        elsif ($value =~ /\D/) {
+            $value =~ s/(['\\])/\\$1/g;
+            $value = "'$value'";
+        }
+
+        if ($keyword =~ s/(['\\])/\\$1/g or $keyword =~ /[^{}\w\.]/) {
+            $keyword = "'$keyword'";
         }
 
         my $clause = {
             Key   => $keyword,
             Op    => $op,
-            Value => $value
+            Value => $value,
+            RawValue => $rawvalue,
         };
 
         push @new_values, RT::Interface::Web::QueryBuilder::Tree->new($clause);
     }
 }
 
-# }}}
 
 push @actions, $m->comp('Elements/EditQuery:Process',
     %ARGS,
@@ -255,7 +267,7 @@ push @actions, $m->comp('Elements/EditQuery:Process',
     New      => \@new_values,
 );
 
-# {{{ Rebuild $Query based on the additions / movements
+# Rebuild $Query based on the additions / movements
 
 my $optionlist_arrayref;
 ($query{'Query'}, $optionlist_arrayref) = $tree->GetQueryAndOptionList(\@current_values);
@@ -264,25 +276,29 @@ my $optionlist = join "\n", map { qq(<option value="$_->{INDEX}" $_->{SELECTED}>
                                   . ("&nbsp;" x (5 * $_->{DEPTH}))
                                   . $m->interp->apply_escapes($_->{TEXT}, 'h') . qq(</option>) } @$optionlist_arrayref;
 
-# }}}
 
 my $queues = $tree->GetReferencedQueues;
 
-# {{{ Deal with format changes
+# Deal with format changes
 my ( $AvailableColumns, $CurrentFormat );
 ( $query{'Format'}, $AvailableColumns, $CurrentFormat ) = $m->comp(
     'Elements/BuildFormatString',
     %ARGS,
-    cfqueues => $queues,
+    queues => $queues,
     Format => $query{'Format'},
 );
 
-# }}}
 
 # if we're asked to save the current search, save it
 push @actions, $m->comp( 'Elements/EditSearches:Save', %ARGS, Query => \%query, SavedSearch => \%saved_search);
 
-# {{{ Push the updates into the session so we don't loose 'em
+# Populate the "query" context with saved search data
+
+if ($ARGS{SavedSearchSave}) {
+    $query{'SavedSearchId'} = $saved_search{'Id'};
+}
+
+# Push the updates into the session so we don't lose 'em
 
 $session{'CurrentSearchHash'} = {
     %query,
@@ -291,30 +307,31 @@ $session{'CurrentSearchHash'} = {
     Description => $saved_search{'Description'},
 };
 
-# }}}
 
-# {{{ Show the results, if we were asked.
+# Show the results, if we were asked.
 
 if ( $ARGS{'DoSearch'} ) {
-    $m->comp( 'Results.html', %query, SavedChartSearchId => $ARGS{'SavedChartSearchId'}, );
-    $m->comp( '/Elements/Footer' );
+    my $redir_query_string = $m->comp(
+        '/Elements/QueryString',
+        %query,
+        SavedChartSearchId => $ARGS{'SavedChartSearchId'},
+        SavedSearchId => $saved_search{'Id'},
+    );
+    RT::Interface::Web::Redirect(RT->Config->Get('WebURL') . 'Search/Results.html?' . $redir_query_string);
     $m->abort;
 }
 
-# }}}
 
-# {{{ Build a querystring for the tabs
+# Build a querystring for the tabs
 
-my $QueryString = '';
+my %TabArgs = ();
 if ($NewQuery) {
-    $QueryString = 'NewQuery=1';
+    $TabArgs{QueryString} = 'NewQuery=1';
 }
 elsif ( $query{'Query'} ) {
-    $QueryString = $m->comp('/Elements/QueryString', %query );
+    $TabArgs{QueryArgs} = \%query;
 }
 
-# }}}
-
 </%INIT>
 
 <%ARGS>