Master to 4.2.8
[usit-rt.git] / share / html / Search / Elements / EditSearches
CommitLineData
84fb5b46
MKG
1%# BEGIN BPS TAGGED BLOCK {{{
2%#
3%# COPYRIGHT:
4%#
320f0092 5%# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
84fb5b46
MKG
6%# <sales@bestpractical.com>
7%#
8%# (Except where explicitly superseded by other copyright notices)
9%#
10%#
11%# LICENSE:
12%#
13%# This work is made available to you under the terms of Version 2 of
14%# the GNU General Public License. A copy of that license should have
15%# been provided with this software, but in any event can be snarfed
16%# from www.gnu.org.
17%#
18%# This work is distributed in the hope that it will be useful, but
19%# WITHOUT ANY WARRANTY; without even the implied warranty of
20%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21%# General Public License for more details.
22%#
23%# You should have received a copy of the GNU General Public License
24%# along with this program; if not, write to the Free Software
25%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26%# 02110-1301 or visit their web page on the internet at
27%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
28%#
29%#
30%# CONTRIBUTION SUBMISSION POLICY:
31%#
32%# (The following paragraph is not intended to limit the rights granted
33%# to you to modify and distribute this software under the terms of
34%# the GNU General Public License and is only of importance to you if
35%# you choose to contribute your changes and enhancements to the
36%# community by submitting them to Best Practical Solutions, LLC.)
37%#
38%# By intentionally submitting any modifications, corrections or
39%# derivatives to this work, or any other work intended for use with
40%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
41%# you are the copyright holder for those contributions and you grant
42%# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
43%# royalty-free, perpetual, license to use, copy, create derivative
44%# works based on those contributions, and sublicense and distribute
45%# those contributions and any derivatives thereof.
46%#
47%# END BPS TAGGED BLOCK }}}
48<div class="edit-saved-searches">
49<&| /Widgets/TitleBox, title => loc($Title)&>
50
51%# Hide all the save functionality if the user shouldn't see it.
52% if ( $can_modify ) {
53<span class="label"><&|/l&>Privacy</&>:</span>
54<& SelectSearchObject, Name => 'SavedSearchOwner', Objects => \@Objects, Object => ( $Object && $Object->id ) ? $Object->Object : '' &>
55<br />
56<span class="label"><&|/l&>Description</&>:</span>
57<input size="25" name="SavedSearchDescription" value="<% $Description || '' %>" />
58
59% if ($Id ne 'new') {
60<nobr>
61% if ( $Dirty ) {
62<input type="submit" class="button" name="SavedSearchRevert" value="<%loc('Revert')%>" />
63% }
64<input type="submit" class="button" name="SavedSearchDelete" value="<%loc('Delete')%>" />
65% if ( $AllowCopy ) {
66<input type="submit" class="button" name="SavedSearchCopy" value="<%loc('Save as New')%>" />
67% }
68</nobr>
69% }
70% if ( $Object && $Object->Id ) {
71<input type="submit" class="button" id="SavedSearchSave" name="SavedSearchSave" value="<%loc('Update')%>" />
72% } else {
73<input type="submit" class="button" id="SavedSearchSave" name="SavedSearchSave" value="<%loc('Save')%>" />
74%}
75% }
76<br />
77<hr />
78<span class="label"><&|/l&>Load saved search</&>:</span>
79<& SelectSearchesForObjects, Name => 'SavedSearchLoad', Objects => \@Objects, SearchType => $Type &>
80<input type="submit" value="<% loc('Load') %>" id="SavedSearchLoadSubmit" name="SavedSearchLoadSubmit" class="button" />
81
82</&>
83</div>
84<%INIT>
85return unless $session{'CurrentUser'}->HasRight(
86 Right => 'LoadSavedSearch',
87 Object => $RT::System,
88);
89
90my $can_modify = $session{'CurrentUser'}->HasRight(
91 Right => 'CreateSavedSearch',
92 Object => $RT::System,
93);
94
95use RT::SavedSearch;
96my @Objects = RT::SavedSearch->new($session{CurrentUser})->_PrivacyObjects;
97push @Objects, RT::System->new( $session{'CurrentUser'} )
98 if $session{'CurrentUser'}->HasRight( Object=> $RT::System,
99 Right => 'SuperUser' );
100
101my $is_dirty = sub {
102 my %arg = (
103 Query => {},
104 SavedSearch => {},
105 SearchFields => [qw(Query Format OrderBy Order RowsPerPage)],
106 @_
107 );
108
109 my $obj = $arg{'SavedSearch'}->{'Object'};
110 return 0 unless $obj && $obj->id;
111
112 foreach( @{ $arg{'SearchFields'} } ) {
113 return 1 if $obj->SubValue( $_ ) ne $arg{'Query'}->{$_};
114 }
115
116 return 0;
117};
118
119# If we're modifying an old query, check if it's been changed
120my $Dirty = $is_dirty->(
121 Query => $CurrentSearch,
122 SavedSearch => { Id => $Id, Object => $Object, Description => $Description },
123 SearchFields => \@SearchFields,
124);
125
126</%INIT>
127
128<%ARGS>
129$Id => 'new'
130$Object => undef
131$Type => 'Ticket'
132$Description => ''
133$CurrentSearch => {}
134@SearchFields => ()
135$AllowCopy => 1
136$Title => loc('Saved searches')
137</%ARGS>
138
139<%METHOD Init>
140<%ARGS>
141$Query => {}
142$SavedSearch => {}
143@SearchFields => qw(Query Format OrderBy Order RowsPerPage)
144</%ARGS>
145<%INIT>
146
147$SavedSearch->{'Id'} = ( $ARGS{Type} && $ARGS{Type} eq 'Chart' ?
148$ARGS{'SavedChartSearchId'} : $ARGS{'SavedSearchId'} ) || 'new';
c33a4027 149$SavedSearch->{'Description'} = $ARGS{'SavedSearchDescription'} || '';
84fb5b46
MKG
150$SavedSearch->{'Privacy'} = $ARGS{'SavedSearchOwner'} || undef;
151
152my @results;
153
154if ( $ARGS{'SavedSearchRevert'} ) {
155 $ARGS{'SavedSearchLoad'} = $SavedSearch->{'Id'};
156}
157
158if ( $ARGS{'SavedSearchLoad'} ) {
159 my ($container, $id ) = _parse_saved_search ($ARGS{'SavedSearchLoad'});
160 if ( $container ) {
af59614d
MKG
161 my $search = RT::Attribute->new( $session{'CurrentUser'} );
162 $search->Load( $id );
84fb5b46
MKG
163 $SavedSearch->{'Id'} = $ARGS{'SavedSearchLoad'};
164 $SavedSearch->{'Object'} = $search;
165 $SavedSearch->{'Description'} = $search->Description;
166 $Query->{$_} = $search->SubValue($_) foreach @SearchFields;
167
168 if ( $ARGS{'SavedSearchRevert'} ) {
169 push @results, loc('Loaded original "[_1]" saved search', $SavedSearch->{'Description'} );
170 } else {
171 push @results, loc('Loaded saved search "[_1]"', $SavedSearch->{'Description'} );
172 }
173 }
174 else {
175 push @results, loc( 'Can not load saved search "[_1]"',
176 $ARGS{'SavedSearchLoad'} );
177 return @results;
178 }
179}
180elsif ( $ARGS{'SavedSearchDelete'} ) {
181 # We set $SearchId to 'new' above already, so peek into the %ARGS
182 my ($container, $id) = _parse_saved_search( $SavedSearch->{'Id'} );
183 if ( $container && $container->id ) {
184 # We have the object the entry is an attribute on; delete the entry...
185 my ($val, $msg) = $container->Attributes->DeleteEntry( Name => 'SavedSearch', id => $id );
186 unless ( $val ) {
187 push @results, $msg;
188 return @results;
189 }
190 }
191 $SavedSearch->{'Id'} = 'new';
192 $SavedSearch->{'Object'} = undef;
193 $SavedSearch->{'Description'} = undef;
194 push @results, loc("Deleted saved search");
195}
196elsif ( $ARGS{'SavedSearchCopy'} ) {
197 my ($container, $id ) = _parse_saved_search( $ARGS{'SavedSearchId'} );
af59614d
MKG
198 $SavedSearch->{'Object'} = RT::Attribute->new( $session{'CurrentUser'} );
199 $SavedSearch->{'Object'}->Load( $id );
84fb5b46
MKG
200 if ( $ARGS{'SavedSearchDescription'} && $ARGS{'SavedSearchDescription'} ne $SavedSearch->{'Object'}->Description ) {
201 $SavedSearch->{'Description'} = $ARGS{'SavedSearchDescription'};
202 } else {
203 $SavedSearch->{'Description'} = loc( "[_1] copy", $SavedSearch->{'Object'}->Description );
204 }
205 $SavedSearch->{'Id'} = 'new';
206 $SavedSearch->{'Object'} = undef;
207}
208
209if ( $SavedSearch->{'Id'} && $SavedSearch->{'Id'} ne 'new'
210 && !$SavedSearch->{'Object'} )
211{
212 my ($container, $id ) = _parse_saved_search( $ARGS{'SavedSearchId'} );
af59614d
MKG
213 $SavedSearch->{'Object'} = RT::Attribute->new( $session{'CurrentUser'} );
214 $SavedSearch->{'Object'}->Load( $id );
84fb5b46
MKG
215 $SavedSearch->{'Description'} ||= $SavedSearch->{'Object'}->Description;
216}
217
218return @results;
219
220</%INIT>
221</%METHOD>
222
223<%METHOD Save>
224<%ARGS>
225$Query => {}
226$SavedSearch => {}
227@SearchFields => qw(Query Format OrderBy Order RowsPerPage)
228</%ARGS>
229<%INIT>
230
231return unless $ARGS{'SavedSearchSave'} || $ARGS{'SavedSearchCopy'};
232
233my @results;
234my $obj = $SavedSearch->{'Object'};
235my $id = $SavedSearch->{'Id'};
236my $desc = $SavedSearch->{'Description'};
237my $privacy = $SavedSearch->{'Privacy'};
238
239my %params = map { $_ => $Query->{$_} } @SearchFields;
240my ($new_obj_type, $new_obj_id) = split(/\-/, ($privacy || ''));
241
242if ( $obj && $obj->id ) {
243 # permission check
244 if ($obj->Object->isa('RT::System')) {
245 unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser')) {
246 push @results, loc("No permission to save system-wide searches");
247 return @results;
248 }
249 }
250
251 $obj->SetSubValues( %params );
252 $obj->SetDescription( $desc );
253
254 my $obj_type = ref($obj->Object);
255 # We need to get current obj_id now, because when we change obj_type to
256 # RT::System, $obj->Object->Id returns 1, not the old one :(
257 my $obj_id = $obj->Object->Id;
258
259 if ( $new_obj_type && $new_obj_id ) {
260 my ($val, $msg);
261
262 # we need to check right before we change any of ObjectType and ObjectId,
263 # or it will fail the 2nd change if we use SetObjectType and
264 # SetObjectId sequentially
265
266 if ( $obj->CurrentUserHasRight('update') ) {
267 if ( $new_obj_type ne $obj_type ) {
268 ( $val, $msg ) = $obj->__Set(
269 Field => 'ObjectType',
270 Value => $new_obj_type,
271 );
272 push @results, loc( 'Unable to set privacy object: [_1]', $msg )
273 unless ($val);
274 }
275 if ( $new_obj_id != $obj_id ) {
276 ( $val, $msg ) = $obj->__Set(
277 Field => 'ObjectId',
278 Value => $new_obj_id,
279 );
280 push @results, loc( 'Unable to set privacy id: [_1]', $msg )
281 unless ($val);
282 }
283 }
284 else {
285 # two loc are just for convenience so we don't need to
286 # write an extra i18n translation item
287 push @results,
288 loc( 'Unable to set privacy object or id: [_1]',
289 loc('Permission Denied') )
290 }
291 } else {
292 push @results, loc('Unable to determine object type or id');
293 }
294 push @results, loc('Updated saved search "[_1]"', $desc);
295}
c33a4027 296elsif ( $id eq 'new' and defined $desc and length $desc ) {
84fb5b46
MKG
297 my $saved_search = RT::SavedSearch->new( $session{'CurrentUser'} );
298 my ($status, $msg) = $saved_search->Save(
299 Privacy => $privacy,
300 Name => $desc,
301 Type => $SavedSearch->{'Type'},
302 SearchParams => \%params,
303 );
304
305 if ( $status ) {
af59614d
MKG
306 $SavedSearch->{'Object'} = RT::Attribute->new( $session{'CurrentUser'} );
307 $SavedSearch->{'Object'}->Load( $saved_search->Id );
84fb5b46
MKG
308 # Build new SearchId
309 $SavedSearch->{'Id'} =
310 ref( $session{'CurrentUser'}->UserObj ) . '-'
311 . $session{'CurrentUser'}->UserObj->Id
312 . '-SavedSearch-'
313 . $SavedSearch->{'Object'}->Id;
314 }
315 else {
316 push @results, loc("Can't find a saved search to work with").': '.loc($msg);
317 }
318}
c33a4027
MKG
319elsif ( $id eq 'new' ) {
320 push @results, loc("Can't save a search without a name");
321}
84fb5b46
MKG
322else {
323 push @results, loc("Can't save this search");
324}
325
326return @results;
327
328</%INIT>
329</%METHOD>