summaryrefslogtreecommitdiff
path: root/rt/share/html/Articles/Article
diff options
context:
space:
mode:
Diffstat (limited to 'rt/share/html/Articles/Article')
-rw-r--r--rt/share/html/Articles/Article/Delete.html106
-rw-r--r--rt/share/html/Articles/Article/Display.html92
-rw-r--r--rt/share/html/Articles/Article/Edit.html333
-rw-r--r--rt/share/html/Articles/Article/Elements/EditBasics73
-rw-r--r--rt/share/html/Articles/Article/Elements/EditCustomFields83
-rw-r--r--rt/share/html/Articles/Article/Elements/EditLinks113
-rw-r--r--rt/share/html/Articles/Article/Elements/EditTopics147
-rw-r--r--rt/share/html/Articles/Article/Elements/LinkEntryInstructions49
-rw-r--r--rt/share/html/Articles/Article/Elements/Preformatted127
-rw-r--r--rt/share/html/Articles/Article/Elements/SearchByCustomField70
-rw-r--r--rt/share/html/Articles/Article/Elements/SelectSavedSearches76
-rw-r--r--rt/share/html/Articles/Article/Elements/SelectSearchPrivacy62
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowHistory76
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowLinks92
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowSavedSearches85
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowSearchCriteria171
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowTopics58
-rw-r--r--rt/share/html/Articles/Article/ExtractFromTicket.html105
-rw-r--r--rt/share/html/Articles/Article/ExtractIntoClass.html76
-rw-r--r--rt/share/html/Articles/Article/ExtractIntoTopic.html72
-rw-r--r--rt/share/html/Articles/Article/History.html57
-rw-r--r--rt/share/html/Articles/Article/PreCreate.html62
-rw-r--r--rt/share/html/Articles/Article/Search.html269
23 files changed, 2454 insertions, 0 deletions
diff --git a/rt/share/html/Articles/Article/Delete.html b/rt/share/html/Articles/Article/Delete.html
new file mode 100644
index 000000000..7abd824d5
--- /dev/null
+++ b/rt/share/html/Articles/Article/Delete.html
@@ -0,0 +1,106 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => $title &>
+<& /Elements/Tabs &>
+
+% if ($ARGS{'Delete'}) {
+<%$title%>
+<& /Elements/ListActions, actions => \@results &>
+
+% } else {
+<b><&|/l&>Are you sure you want to delete this article?</&></b>
+<table>
+<tr>
+<td align="left">
+<form action="Display.html" method="get">
+<input type="hidden" name="id" value="<%$ArticleObj->Id%>" />
+<input type="submit" value="<&|/l&>No</&>" />
+</form>
+
+</td>
+<td align="right">
+<form action="Delete.html" method="post">
+<input type="hidden" name="id" value="<%$ArticleObj->Id%>" />
+<input type="hidden" name="Delete" value="yes" />
+<input type="submit" value="<&|/l&>Yes</&>" />
+</form>
+</td>
+
+</tr>
+</table>
+% }
+<%INIT>
+
+my @results;
+
+my $title;
+my $ArticleObj = RT::Article->new( $session{'CurrentUser'} );
+
+
+$ArticleObj->Load($id);
+unless ( $ArticleObj->id ) {
+ $m->comp("/Elements/Error", Why => loc("Unable to load article") );
+}
+
+
+unless ( $ArticleObj->CurrentUserHasRight('ModifyArticle') ) {
+ $m->comp("/Elements/Error", Why => loc("No permission to modify article"));
+}
+
+if ($ARGS{'Delete'} eq 'yes') {
+ $ArticleObj->Delete();
+ $title = loc('Article #[_1] deleted', $ArticleObj->Id);
+}
+
+else {
+ $title = loc('Delete article #[_1]', $ArticleObj->Id);
+}
+</%INIT>
+<%ARGS>
+$id => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Display.html b/rt/share/html/Articles/Article/Display.html
new file mode 100644
index 000000000..b80dc1c5e
--- /dev/null
+++ b/rt/share/html/Articles/Article/Display.html
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => $title &>
+<& /Elements/Tabs &>
+<h2><&|/l&>Basics</&></h2>
+<span class="label"><&|/l&>Class</&></span>: <span class="value"><%$article->ClassObj->Name%></span><br />
+<em><span class="value"><%$article->Summary%></span></em>
+<h2><&|/l&>Content</&></h2>
+<& /Elements/ShowCustomFields, Object => $article &>
+
+<h2><&|/l&>Links</&></h2>
+<& Elements/ShowLinks, article => $article &>
+
+<h2><&|/l&>Topics</&></h2>
+<& Elements/ShowTopics, article => $article &>
+<%init>
+
+my $article = RT::Article->new( $session{'CurrentUser'} );
+if ($Name) {
+ $article->LoadByCols( Name => $Name );
+}
+elsif ($id) {
+ $article->Load($id);
+}
+unless ( $article->Id ) {
+ if ( $ARGS{'Name'} ) {
+ $m->comp( 'Edit.html', %ARGS );
+ return ();
+ }
+ else {
+ $m->comp( "/Elements/Error", Why => loc("Article not found") );
+ }
+
+}
+
+unless ( $article->CurrentUserHasRight('ShowArticle') ) {
+ $m->comp( "/Elements/Error", Why => loc("Permission Denied") );
+}
+my $title = loc( "Article #[_1]: [_2]", $article->Id, $article->Name || loc("(no name)"));
+
+$id = $article->id;
+
+</%init>
+<%args>
+$id => undef
+$Name => undef
+</%args>
diff --git a/rt/share/html/Articles/Article/Edit.html b/rt/share/html/Articles/Article/Edit.html
new file mode 100644
index 000000000..756aa2cc9
--- /dev/null
+++ b/rt/share/html/Articles/Article/Edit.html
@@ -0,0 +1,333 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => $title &>
+<& /Elements/Tabs &>
+<& /Elements/ListActions, actions => \@results &>
+
+<form method="post" action="Edit.html" name="EditArticle" id="EditArticle" enctype="multipart/form-data">
+<input type="hidden" name="next" value="<%$ARGS{next}||''%>" />
+<input type="hidden" name="id" value="<%$id%>" />
+<table width="100%">
+<tr>
+<td><h2><&|/l&>Basics</&></h2></td>
+<td></td>
+</tr>
+<& Elements/EditBasics, ArticleObj => $ArticleObj,
+ EditClass =>$EditClass,
+ ClassObj => $ClassObj,
+ %ARGS ,
+ id => $id
+ &>
+
+<tr>
+<td><h2><&|/l&>Content</&></h2></td>
+<td></td>
+</tr>
+<& Elements/EditCustomFields, ArticleObj => $ArticleObj,
+ CFContent => \%CFContent,
+ ClassObj => $ClassObj,
+ %ARGS,
+ id =>$id,
+ &>
+
+<tr>
+<td><h2><&|/l&>Links</&></h2></td>
+<td></td>
+</tr>
+<& Elements/EditLinks, ArticleObj => $ArticleObj,
+ %ARGS,
+ id => $id
+ &>
+<tr>
+<td><h2><&|/l&>Topics</&></h2></td>
+<td></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Topics</&></td>
+<td>
+<& Elements/EditTopics, ArticleObj => $ArticleObj,
+ Classes => [$ArticleObj->Id ? $ArticleObj->ClassObj : $ClassObj],
+ OnlyThisClass => 1,
+ %ARGS,
+ id => $id
+ &>
+</td>
+</tr>
+</table>
+<& /Elements/Submit, Label => ($id eq 'new' ? loc('Create') : loc('Save Changes')), color => "#993333" &>
+</form>
+
+<%INIT>
+
+if ( exists $ARGS{'Topics'} ) {
+ $ARGS{'Topics'} =
+ ref( $ARGS{'Topics'} ) ? $ARGS{'Topics'} : [ $ARGS{'Topics'} ];
+}
+
+my @results;
+my $title;
+
+my $Entries = {};
+my $ArticleObj = RT::Article->new( $session{'CurrentUser'} );
+my $ClassObj = RT::Class->new( $session{'CurrentUser'} );
+my %create_args;
+my %CFContent;
+my $EditClass = 1;
+if ( !$id ) {
+ $title = loc('Create a new article');
+ foreach my $arg ( sort keys %ARGS ) {
+ if ( $arg =~ /^Transaction-(\d+)$/ ) {
+ my $trans = RT::Transaction->new( $session{'CurrentUser'} );
+ $trans->Load($1);
+ $CFContent{ $ARGS{$arg} } .= "\n\n" if $CFContent{ $ARGS{$arg} };
+ $CFContent{ $ARGS{$arg} } .= $trans->Content;
+ }
+ }
+
+ $ClassObj->Load($Class);
+ unless ( $ClassObj->Id ) {
+ $m->comp( "/Elements/Error",
+ Why => loc( "'[_1]' isn't a valid class identifier", $Class ) );
+ }
+ $EditClass = 0;
+ $id = 'new';
+}
+elsif ( $id eq 'new' ) {
+
+ if ( $ARGS{'RefersTo-new'} ) {
+ @{ $create_args{'RefersTo-new'} } =
+ split( /\s+/, $ARGS{'RefersTo-new'} );
+ }
+
+ if ( $ARGS{'new-RefersTo'} ) {
+ @{ $create_args{'new-RefersTo'} } =
+ split( /\s+/, $ARGS{'new-RefersTo'} );
+ }
+
+
+ foreach my $arg (keys %ARGS) {
+ next if $arg =~ /-(?:Magic|Category)$/;
+ # Object-RT::Article--CustomField-3-Values
+ if ( $arg =~ /^Object-RT::Article--CustomField-(\d+)(.*?)$/ ) {
+ my $cfid = $1;
+
+ my $cf = RT::CustomField->new( $session{'CurrentUser'} );
+ $cf->Load( $cfid );
+ unless ( $cf->id ) {
+ $RT::Logger->error( "Couldn't load custom field #". $cfid );
+ next;
+ }
+
+ if ( $arg =~ /-Upload$/ ) {
+ $create_args{"CustomField-$cfid"} = _UploadedFile( $arg );
+ next;
+ }
+
+ my $type = $cf->Type;
+
+ my @values = ();
+ if ( ref $ARGS{ $arg } eq 'ARRAY' ) {
+ @values = @{ $ARGS{ $arg } };
+ } elsif ( $type =~ /text/i ) {
+ @values = ($ARGS{ $arg });
+ } else {
+ @values = split /\r*\n/, $ARGS{ $arg } || '';
+ }
+ @values = grep $_ ne '',
+ map {
+ s/\r+\n/\n/g;
+ s/^\s+//;
+ s/\s+$//;
+ $_;
+ }
+ grep defined, @values;
+
+ $create_args{"CustomField-$cfid"} = \@values;
+ }
+ }
+
+ my $msg;
+ ( $id, $msg ) = $ArticleObj->Create(
+ Summary => $ARGS{'Summary'},
+ Name => $ARGS{'Name'},
+ Class => $ARGS{'Class'},
+ Topics => $ARGS{'Topics'},
+ %create_args
+ );
+ push( @results, $msg );
+ if ($id) {
+
+
+ $ArticleObj->Load($id);
+
+ $title = loc( 'Modify article #[_1]', $ArticleObj->Id );
+ delete $ARGS{id};
+
+ if ( $ARGS{next} ) {
+ $m->redirect($ARGS{next});
+ }
+ else {
+ MaybeRedirectForResults(
+ Actions => \@results,
+ Arguments => { id => $ArticleObj->id },
+ );
+ }
+ }
+ if (!$id) {
+ $ClassObj->Load($Class);
+ unless ( $ClassObj->Id ) {
+ $m->comp( "/Elements/Error",
+ Why => loc( "'[_1]' isn't a valid class identifier", $Class ) );
+ }
+ $ArticleObj = RT::Article->new( $session{'CurrentUser'} );
+ $id = 'new';
+ $EditClass = 0;
+ $title = loc('Create a new article');
+ }
+}
+else {
+
+ $ArticleObj->Load($id);
+ unless ( $ArticleObj->id ) {
+ $m->comp( "/Elements/Error",
+ Why => loc("Unable to load article") );
+ }
+
+ my @attribs = qw(Name Summary Class);
+
+ @results = UpdateRecordObject(
+ AttributesRef => \@attribs,
+ Object => $ArticleObj,
+ ARGSRef => \%ARGS
+ );
+
+ my @cf_results = ProcessObjectCustomFieldUpdates(
+ Object => $ArticleObj,
+ ARGSRef => \%ARGS
+ );
+ @results = ( @results, @cf_results );
+
+ # Delete links that are gone gone gone.
+ foreach my $arg ( keys %ARGS ) {
+ if ( $arg =~ /DeleteLink-(.*?)-(RefersTo|MemberOf|RefersTo)-(.*)$/ ) {
+ my $base = $1;
+ my $type = $2;
+ my $target = $3;
+
+ my ( $val, $msg ) = $ArticleObj->DeleteLink(
+ Base => $base,
+ Type => $type,
+ Target => $target
+ );
+
+ push @results, $msg;
+
+ }
+
+ }
+
+ my @linktypes = qw(DependsOn MemberOf RefersTo );
+
+ foreach my $linktype (@linktypes) {
+
+ for my $luri ( split( / /, ( $ARGS{ $ArticleObj->Id . "-$linktype" } || '' )) ) {
+ $luri =~ s/\s*$//; # Strip trailing whitespace
+ my ( $val, $msg ) =
+ $ArticleObj->AddLink( Target => $luri, Type => $linktype );
+ push @results, $msg;
+ delete $ARGS{ $ArticleObj->Id . "-$linktype" } if $val;
+ }
+
+ for my $luri ( split( / /, ( $ARGS{ "$linktype-" . $ArticleObj->Id } || '' )) ) {
+ my ( $val, $msg ) =
+ $ArticleObj->AddLink( Base => $luri, Type => $linktype );
+ push @results, $msg;
+ delete $ARGS{ "$linktype-" . $ArticleObj->Id } if $val;
+ }
+
+ }
+
+ my %topics;
+ if ( $ARGS{'EditTopics'} ) {
+ $topics{$_}++ for @{ $ARGS{'Topics'} };
+ my $objTopics =
+ RT::ObjectTopics->new( $session{'CurrentUser'} );
+ $objTopics->LimitToObject($ArticleObj);
+ while ( my $t = $objTopics->Next ) {
+ $topics{ $t->Topic }--;
+ }
+ for my $id ( keys %topics ) {
+ if ( $topics{$id} > 0 ) {
+ my ( $val, $msg ) = $ArticleObj->AddTopic( Topic => $id );
+ push @results, $msg;
+ }
+ elsif ( $topics{$id} < 0 ) {
+ my ( $val, $msg ) = $ArticleObj->DeleteTopic( Topic => $id );
+ push @results, $msg;
+ }
+ }
+ }
+
+ $title = loc( 'Modify article #[_1]', $ArticleObj->Id );
+}
+
+# if they're working on an existing article
+if ( $ArticleObj->id ) {
+ unless ( $ArticleObj->CurrentUserHasRight('ShowArticle') ) {
+ $m->comp( "/Elements/Error",
+ Why => loc("No permission to view Article") );
+ }
+}
+
+</%INIT>
+
+
+<%ARGS>
+$id => undef
+$Class => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/EditBasics b/rt/share/html/Articles/Article/Elements/EditBasics
new file mode 100644
index 000000000..256d81610
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/EditBasics
@@ -0,0 +1,73 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<tr>
+<td class="label"><&|/l&>Name</&></td>
+<td><input name="Name" value="<%($ARGS{'id'} eq 'new' ? '' : $ArticleObj->Name) || $ARGS{'Name'} || ''|h%>" size="50" /></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Summary</&></td>
+<td><input name="Summary" value="<%($ARGS{'id'} eq 'new' ? '' : $ArticleObj->Summary) || $ARGS{'Summary'} ||'' |h%>" size="50" /></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Class</&></td>
+<td>
+% if ($EditClass) {
+<& /Articles/Elements/SelectClass, Name => 'Class', Default =>$ArticleObj->ClassObj->Id&>
+% } else {
+<%$ClassObj->Name%>
+<input type="hidden" name="Class" value="<%$ClassObj->Id%>" />
+% }
+</td>
+</tr>
+<%INIT>
+</%INIT>
+<%ARGS>
+$EditClass => 1
+$ClassObj => undef
+$ArticleObj => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/EditCustomFields b/rt/share/html/Articles/Article/Elements/EditCustomFields
new file mode 100644
index 000000000..db719eb2e
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/EditCustomFields
@@ -0,0 +1,83 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+% while (my $CustomField = $CustomFields->Next()) {
+<tr>
+ <td class="labeltop"><b><%$CustomField->Name%></b><br /><i><%$CustomField->FriendlyType%></i></td>
+ <td class="entry"><& /Elements/EditCustomField,
+ Object => $ArticleObj,
+ CustomField => $CustomField,
+ NamePrefix => $NamePrefix,
+ Default =>
+ ($CFContent->{$CustomField->Id} ||
+ $ARGS{$NamePrefix .$CustomField->id .'-Values'} ||
+ $ARGS{$NamePrefix .$CustomField->id .'-Value'})
+ ,
+ Rows => 15,
+ Cols => 70
+ &></td>
+</tr>
+% }
+<%INIT>
+my $CustomFields;
+my $NamePrefix;
+
+if ($ArticleObj->id && $ArticleObj->ClassObj->id) {
+ $CustomFields = $ArticleObj->CustomFields();
+ $NamePrefix = "Object-RT::Article-".$ArticleObj->Id."-CustomField-";
+}
+else {
+ $CustomFields = $ClassObj->ArticleCustomFields();
+ $NamePrefix = "Object-RT::Article--CustomField-";
+}
+</%INIT>
+<%ARGS>
+$ArticleObj => undef
+$ClassObj => undef
+$CFContent => undef
+$id => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/EditLinks b/rt/share/html/Articles/Article/Elements/EditLinks
new file mode 100644
index 000000000..03b99c8d3
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/EditLinks
@@ -0,0 +1,113 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<tr>
+<td class="label"></td>
+<td class="value"><i><&|/l&>Enter articles, tickets, or other URLs related to this article.</&>
+<& LinkEntryInstructions &></i>
+% unless ($id eq 'new') {
+<i><&|/l&>(Check boxes to delete)</&></i><br />
+% }
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Refers to</&>:</td>
+<td><input name="<%$id%>-RefersTo" value="<%$ARGS{$id.'-RefersTo'}||''%>" /><br />
+<ul>
+% if ($id ne 'new') {
+% my $refersto = $ArticleObj->RefersTo;
+% while (my $link = $refersto->Next) {
+% my $member = $link->TargetURI;
+<li>
+<input type="CHECKBOX" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" />
+% if ($link->TargetURI->IsLocal) {
+<a href="<%$member->Resolver->HREF%>"><% loc($member->Object->ObjectTypeStr) %> <%$member->Object->Id%></a>:
+% if (UNIVERSAL::isa($member->Object, "RT::Article") or UNIVERSAL::can($member->Object, 'Name')) {
+<%$member->Object->Name%>
+% } elsif (UNIVERSAL::isa($member->Object, "RT::Ticket") or UNIVERSAL::can($member->Object, 'Subject')) {
+<%$member->Object->Subject%>
+% }
+</a>
+% } else {
+<a href="<%$member->Resolver->HREF%>"><%$link->Target%></a>
+% }
+% }
+% }
+</ul>
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Referred to by</&>:</td>
+<td><input name="RefersTo-<%$id%>" value="<%$ARGS{'RefersTo-'.$id}||''%>" />
+<br />
+<ul>
+% if ($id ne 'new') {
+% my $referredtoby = $ArticleObj->ReferredToBy;
+% while (my $link = $referredtoby->Next) {
+% my $member = $link->BaseURI;
+<li>
+<input type="CHECKBOX" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" />
+% if ($link->BaseURI->IsLocal) {
+<a href="<%$member->Resolver->HREF%>"><% loc($member->Object->ObjectTypeStr) %> <%$member->Object->Id%>:
+% if (UNIVERSAL::isa($member->Object, "RT::Article") or UNIVERSAL::can($member->Object, 'Name')) {
+<%$member->Object->Name%>
+% } elsif (UNIVERSAL::isa($member->Object, "RT::Ticket") or UNIVERSAL::can($member->Object, 'Subject')) {
+<%$member->Object->Subject%>
+% }
+</a>
+% } else {
+<a href="<%$member->Resolver->HREF%>"><%$link->Base%></a>
+% }
+% }
+% }
+</ul>
+</td>
+</tr>
+<%ARGS>
+$ArticleObj => undef
+$id => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/EditTopics b/rt/share/html/Articles/Article/Elements/EditTopics
new file mode 100644
index 000000000..807360bf2
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/EditTopics
@@ -0,0 +1,147 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<input type="hidden" name="EditTopics" value="1" />
+<select multiple size="10" name="Topics">
+<%perl>
+if (@Classes) {
+ $m->print("<optgroup label=\"Current classes (".join (' ',map {$_->Name} @Classes).")\">")
+ unless $OnlyThisClass;
+ $inTree->traverse(sub {
+ my $tree = shift;
+ my $topic = $tree->getNodeValue;
+ $m->print("<option value=\"".$topic->Id."\""
+ .(exists $topics{$topic->Id} ? " selected" : "").">"
+ .("&nbsp;" x ($tree->getDepth*5)).($topic->Name || loc("(no name)"))."</option>\n");
+ });
+}
+unless ($OnlyThisClass) {
+ my $class = $Classes[-1]->Id;
+ $otherTree->traverse(sub {
+ my $tree = shift;
+ my $topic = $tree->getNodeValue;
+ unless ($topic->ObjectId == $class) {
+ $class = $topic->ObjectId;
+ $m->print("</optgroup>\n");
+ my $c = RT::Class->new($session{'CurrentUser'});
+ $c->Load($topic->ObjectId);
+ $m->print("<optgroup label=\"".$c->Name."\">\n");
+ }
+ $m->print("<option value=\"".$topic->Id."\""
+ .(exists $topics{$topic->Id} ? " selected" : "").">"
+ .("&nbsp;" x ($tree->getDepth*5)).($topic->Name || loc("(no name)"))."</option>\n");
+ });
+</%perl>
+</optgroup>
+% }
+</select>
+
+<%INIT>
+use Tree::Simple;
+
+my $inClass = RT::Topics->new($session{'CurrentUser'});
+# global topics should always be available
+push @Classes,$RT::System unless grep { $_ == $RT::System } @Classes;
+$inClass->LimitToObject($_) for @Classes;
+$inClass->OrderByCols({FIELD => 'Name'});
+my $inTree = buildTree($inClass);
+
+my $otherClass = RT::Topics->new($session{'CurrentUser'});
+if (@Classes) {
+ $otherClass->Limit(FIELD => 'ObjectType', VALUE => 'RT::Class');
+ for (@Classes) {
+ $otherClass->Limit(FIELD => 'ObjectId', OPERATOR => '!=', VALUE => $_->Id);
+ }
+} else {
+ $otherClass->UnLimit;
+}
+my $otherTree = buildTree($otherClass);
+
+my $articleTopics = RT::ObjectTopics->new($session{'CurrentUser'});
+$articleTopics->LimitToObject($ArticleObj);
+my %topics;
+while (my $topicObj = $articleTopics->Next) {
+ $topics{$topicObj->Topic} = 1;
+}
+$topics{$_} = 1 for @Topics;
+
+sub buildTree {
+ my $query = shift;
+
+ use Tree::Simple;
+ my $tree = Tree::Simple->new(Tree::Simple->ROOT);
+ my %lookup = (0 => $tree);
+
+ my @todo;
+ while (my $topic = $query->Next) {
+ push @todo, $topic;
+ }
+
+ {
+ my $changed = 0;
+ my @work = @todo;
+ @todo = ();
+ for my $topic (@work) {
+ if (defined $lookup{$topic->Parent}) {
+ $lookup{$topic->Id} = Tree::Simple->new($topic, $lookup{$topic->Parent});
+ $changed = 1;
+ } else {
+ push @todo, $topic;
+ }
+ }
+ redo unless $changed == 0;
+ }
+ return $tree;
+}
+
+</%INIT>
+<%ARGS>
+$ArticleObj => RT::Article->new($session{'CurrentUser'})
+@Classes => ()
+@Topics => ()
+$OnlyThisClass => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/LinkEntryInstructions b/rt/share/html/Articles/Article/Elements/LinkEntryInstructions
new file mode 100644
index 000000000..c2fd1efed
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/LinkEntryInstructions
@@ -0,0 +1,49 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<&|/l&>Type <b>a:</b> before article numbers and <b>t:</b> before ticket numbers.</&>
+<&|/l&>Separate multiple entries with spaces.</&>
diff --git a/rt/share/html/Articles/Article/Elements/Preformatted b/rt/share/html/Articles/Article/Elements/Preformatted
new file mode 100644
index 000000000..2f0e7869e
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/Preformatted
@@ -0,0 +1,127 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+% if ($include{Name}) {
+#<%$Article->Id%>: <%$Article->Name || loc('(no name)')%>
+<%'-' x length("#".$Article->Id.": ".($Article->Name || loc('(no name)'))) %>
+% }
+% if ( $include{Summary} && ($Article->Summary||'') =~ /\S/ ) {
+<% $Article->Summary %>
+% }
+% while (my $cf = $cfs->Next) {
+% next unless $include{"CF-Title-".$cf->Id} or $include{"CF-Value-".$cf->Id};
+% my $values = $Article->CustomFieldValues($cf->Id);
+% if ($values->Count == 1) {
+% my $value = $values->First;
+% if ($include{"CF-Title-".$cf->Id}) {
+<% $cf->Name%>:
+<% '-' x length($cf->Name) %>
+% }
+% if ($value && $include{"CF-Value-".$cf->Id}) {
+<% $get_content->( $value ) %>
+% }
+% } else {
+% my $val = $values->Next;
+% if ($include{"CF-Title-".$cf->Id}) {
+<% $cf->Name%>: \
+% }
+% if ($val && $include{"CF-Value-".$cf->Id}) {
+<% $get_content->( $val ) %>
+% }
+% while ($val = $values->Next) {
+% if ($include{"CF-Title-".$cf->Id}) {
+<% ' ' x length($cf->Name)%> \
+% }
+% if ($include{"CF-Value-".$cf->Id}) {
+<% $get_content->( $val ) %>
+% }
+% }
+% }
+% }
+<%init>
+my $class = $Article->ClassObj;
+my %include = (Name => 1, Summary => 1);
+my $cfs = $class->ArticleCustomFields;
+$include{"CF-Title-".$_->Id} = $include{"CF-Value-".$_->Id} = 1 while $_ = $cfs->Next;
+$include{$_} = not $class->FirstAttribute("Skip-$_") for keys %include;
+
+my $de_htmlify = sub {
+ my $content = shift;
+ require HTML::TreeBuilder;
+ my $tree = HTML::TreeBuilder->new;
+ $tree->parse($content);
+ $tree->eof();
+
+ require HTML::FormatText;
+ my $formatter = HTML::FormatText->new(leftmargin => 0, rightmargin => 50);
+ $content = $formatter->format($tree);
+ return $content;
+};
+
+my $get_content = sub {
+ my $value = shift;
+ return '' unless $value;
+
+ my $content = $value->Content;
+ return '' unless defined $content && length $content;
+
+ $m->callback(
+ %ARGS,
+ CallbackName => 'ProcessContent',
+ content => \$content,
+ );
+
+ if ( $content =~ /<.{1,5}>/ ) {
+ $content = $de_htmlify->( $content );
+ }
+ return $content;
+};
+
+</%init>
+<%args>
+$Article
+</%args>
diff --git a/rt/share/html/Articles/Article/Elements/SearchByCustomField b/rt/share/html/Articles/Article/Elements/SearchByCustomField
new file mode 100644
index 000000000..2a9d14506
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/SearchByCustomField
@@ -0,0 +1,70 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+%# if the custom field is a select, enumerate the options
+% if ($Field->Type =~ /^Select/) {
+% my $CustomFieldValues = $Field->ValuesObj();
+<select name="<%$Name%>" size="5" multiple>
+% while (my $value = $CustomFieldValues->Next) {
+% my $name = $value->Name || '';
+<option value="<% $name %>" <% grep($_ eq $name, @Values)? 'SELECTED' : ''%>><% $name %></option>
+% }
+<option value="" <% $#Values < 0 && 'SELECTED'%>><&|/l&>(no value)</&></option>
+</select>
+% }
+%# otherwise, put in a textedity field
+% else {
+<input name="<%$Name%>" value="<%$Values[0]||''%>" />
+% }
+<%init>
+my @Values =ref( $Values ) ? @{ $Values } : ( $Values );
+</%init>
+<%ARGS>
+$Field => undef
+$Name => 'CustomField'
+$Values => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/SelectSavedSearches b/rt/share/html/Articles/Article/Elements/SelectSavedSearches
new file mode 100644
index 000000000..c42fae1b5
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/SelectSavedSearches
@@ -0,0 +1,76 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<select name="<%$Name%>">
+% foreach my $privacy (reverse sort keys %privacies) {
+% my $searches = RT::SavedSearches->new($session{'CurrentUser'});
+% $searches->LimitToPrivacy($privacy, 'Article');
+% next unless $searches->Count;
+% if ($privacy =~ /^RT::User/) {
+<option value=""><&|/l&>My saved searches</&></option>
+% } else {
+<option value=""><&|/l, $privacies{$privacy}->Name&>[_1]'s saved searches</&></option>
+% }
+% while (my $search = $searches->Next) {
+% my $optionval = "$privacy-SavedSearch-". $search->Id;
+<option value="<%$optionval%>"<% $optionval eq $Default ? 'selected' : '' %>> - <%$search->Name||loc('Unnamed search')%></option>
+% }
+% }
+</select>
+
+<%init>
+use RT::SavedSearches;
+my $groups = $session{'CurrentUser'}->UserObj->OwnGroups;
+my %privacies;
+$privacies{'RT::User-' . $session{'CurrentUser'}->UserObj->Id} = 1;
+map { $privacies{'RT::Group-'.$_->Id} = $_ } @{$groups->ItemsArrayRef};
+</%init>
+
+<%args>
+$Name => undef
+$Default => undef
+</%args>
diff --git a/rt/share/html/Articles/Article/Elements/SelectSearchPrivacy b/rt/share/html/Articles/Article/Elements/SelectSearchPrivacy
new file mode 100644
index 000000000..674a0ffa7
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/SelectSearchPrivacy
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<select name="<%$Name%>">
+<option value="RT::User-<% $user->Id %>" <% $Default eq 'RT::User-'.$user->Id ? 'selected' : '' %>>My searches</option>
+% while (my $group = $groups->Next) {
+<option value="RT::Group-<% $group->Id %>" <% $Default eq 'RT::Group-'.$group->Id ? 'selected' : '' %>><% $group->Name %>'s searches</option>
+% }
+</select>
+<%INIT>
+my $user = $session{'CurrentUser'}->UserObj;
+my $groups = $session{'CurrentUser'}->UserObj->OwnGroups;
+$Default = '' unless defined $Default;
+</%INIT>
+<%ARGS>
+$Name => 'GroupField'
+$Default => ''
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/ShowHistory b/rt/share/html/Articles/Article/Elements/ShowHistory
new file mode 100644
index 000000000..6ca74bf61
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/ShowHistory
@@ -0,0 +1,76 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<table width="100%" cellspacing="0" cellpadding="2">
+% my $i;
+% while (my $transaction = $transactions->Next) {
+<tr class="<% ($i++)%2 ? 'oddline' : 'evenline'%>" >
+<td width="20%"><small><%$transaction->CreatedObj->AsString%></small></td>
+<td><%$transaction->CreatorObj->Name%></td>
+<td><%$transaction->Description%></td>
+</tr>
+% }
+</table>
+<%init>
+
+my $article = RT::Article->new($session{'CurrentUser'});
+
+$article->Load($id);
+unless ($article->Id) {
+ $m->comp("/Elements/Error", Why => loc("Article not found"));
+}
+
+unless ($article->ClassObj->CurrentUserHasRight('ShowArticle')) {
+ $m->comp("/Elements/Error", Why => loc("Permission Denied"));
+}
+
+my $transactions = $article->Transactions();
+
+</%init>
+<%args>
+$id => undef
+</%args>
diff --git a/rt/share/html/Articles/Article/Elements/ShowLinks b/rt/share/html/Articles/Article/Elements/ShowLinks
new file mode 100644
index 000000000..2e48ac949
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/ShowLinks
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<span class="label"><&|/l&>Refers to</&></span>:<br />
+<ul class="value">
+% my $refersto = $article->RefersTo;
+
+% while (my $link = $refersto->Next) {
+% my $member = $link->TargetURI;
+<li>
+% if ($link->TargetURI->IsLocal) {
+<a href="<%$member->Resolver->HREF%>"><% loc($member->Object->ObjectTypeStr) %> <%$member->Object->Id%>:
+% if (UNIVERSAL::isa($member->Object, "RT::Article") or UNIVERSAL::can($member->Object, 'Name')) {
+<%$member->Object->Name%>
+% } elsif (UNIVERSAL::isa($member->Object, "RT::Ticket") or UNIVERSAL::can($member->Object, 'Subject')) {
+<%$member->Object->Subject%>
+% }
+</a>
+% } else {
+<a href="<%$member->Resolver->HREF%>"><%$link->Target%></a>
+% }
+</li>
+% }
+</ul>
+
+<span class="label"><&|/l&>Referred to by</&></span>:<br />
+<ul class="value">
+% my $referredtoby = $article->ReferredToBy;
+% while (my $link = $referredtoby->Next) {
+% my $member = $link->BaseURI;
+<li>
+% if ($member->IsLocal) {
+<a href="<%$member->Resolver->HREF%>"><% loc($member->Object->ObjectTypeStr) %> <%$member->Object->Id%>:
+% if (UNIVERSAL::isa($member->Object, "RT::Article") or UNIVERSAL::can($member->Object, 'Name')) {
+<%$member->Object->Name%>
+% } elsif (UNIVERSAL::isa($member->Object, "RT::Ticket") or UNIVERSAL::can($member->Object, 'Subject')) {
+<%$member->Object->Subject%>
+% }
+</a>
+% } else {
+<a href="<%$member->Resolver->HREF%>"><%$link->Base%></a>
+% }
+</li>
+% }
+</ul>
+<%args>
+$article => undef
+</%args>
diff --git a/rt/share/html/Articles/Article/Elements/ShowSavedSearches b/rt/share/html/Articles/Article/Elements/ShowSavedSearches
new file mode 100644
index 000000000..8ced74b1c
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/ShowSavedSearches
@@ -0,0 +1,85 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/TitleBoxStart, title => loc('Saved searches') &>
+%# Keep track of what our current search ID is.
+<input type="hidden" name="CurrentSearch" value="<% $CurrentSearch ? $CurrentSearch : 'new' %>">
+%# Hide all the save functionality if the user shouldn't see it.
+% if ($session{'CurrentUser'}->HasRight( Right => 'CreateSavedSearch',
+% Object=> $RT::System )) {
+<h2><&|/l&>Save this search</&></h2>
+<&|/l&>Name:</&> <input name="NewSearchName" value="<%$Name||''%>">
+<&|/l&>Privacy:</&> <& SelectSearchPrivacy, Name => 'SearchPrivacy',
+ Default => $Privacy &><br />
+% if ($CurrentSearch && $CurrentSearch ne 'new') {
+<input value="<%loc('Update')%>" name="Update" type="submit" />&nbsp;
+<input value="<%loc('Save new')%>" name="Save" type="submit" />&nbsp;
+<input value="<%loc('Delete')%>" name="Delete" type="submit" />&nbsp;
+% } else {
+<input value="<%loc('Save')%>" name="Save" type="submit" />
+% }
+<hr />
+% } # if HasRight 'CreateSavedSearch'
+
+<h2><&|/l&>Load a saved search</&></h2>
+<& SelectSavedSearches, Name => 'LoadSavedSearch', Default => $CurrentSearch &>
+<input value="<%loc('Load')%>" name="Load" type="submit">
+<& /Elements/TitleBoxEnd &>
+
+<%INIT>
+unless ($session{'CurrentUser'}->HasRight( Right => 'LoadSavedSearch',
+ Object=> $RT::System )) {
+ return;
+}
+
+</%INIT>
+
+<%ARGS>
+$CurrentSearch => undef
+$Name => undef
+$Privacy => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/ShowSearchCriteria b/rt/share/html/Articles/Article/Elements/ShowSearchCriteria
new file mode 100644
index 000000000..377cdb1f0
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/ShowSearchCriteria
@@ -0,0 +1,171 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+% if ($ARGS{'HideOptions'}) {
+<& /Elements/TitleBoxStart, title => loc('Advanced search'), class => "rolled-up", bodyclass => "hidden" &>
+% } else {
+<& /Elements/TitleBoxStart, title => loc('Advanced search') &>
+% }
+<table>
+<tr>
+<td class="label" colspan="2"><h2><&|/l&>Basics</&></h2></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Class</&></td><td class="value">is <& /Articles/Elements/SelectClass, Name => 'Class', Multiple =>1, Size => 5 , ShowNullOption => undef, Default => $ARGS{'Class'} &>
+<&|/l&>and not</&>
+<& /Articles/Elements/SelectClass, Name => 'Class!', Multiple =>1, Size => 5 , ShowNullOption => undef, Default => $ARGS{'Class!'} &></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Name</&></td>
+<td class="value"><&|/l&>matches</&> <input name="Name~" value="<%$ARGS{'Name~'}%>" /> <&|/l&>and not</&> <input name="Name!~" value="<%$ARGS{'Name!~'}%>" /></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Summary</&></td>
+<td class="value"><&|/l&>matches</&> <input name="Summary~" value="<%$ARGS{'Summary~'}%>" /> <&|/l&>and not</&> <input name="Summary!~" value="<%$ARGS{'Summary!~'}%>" /></td>
+</tr>
+<tr>
+<td class="label" colspan="2"><h2><&|/l&>Content</&></h2></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Any field</&></td><td class="value"> <&|/l&>matches</&> <input name="Article~" value="<%$ARGS{'Article~'}%>" /> <&|/l&>and not</&> <input name="Article!~" value="<%$ARGS{'Article!~'}%>" /></td>
+</tr>
+% while (my $field = $customfields->Next ) {
+<tr>
+<td class="label"><% $field->Name %></td>
+<td class="value"><&|/l&>matches</&>
+% my $matches = $field->Name."~";
+% my $nomatches = $field->Name."!~";
+<& /Articles/Article/Elements/SearchByCustomField,
+ Field => $field,
+ Name => $matches,
+ Values => $ARGS{$matches} &>
+ <&|/l&>and not</&>
+<& /Articles/Article/Elements/SearchByCustomField,
+ Field => $field,
+ Name => $nomatches,
+ Values => $ARGS{$nomatches}
+ &>
+</td>
+</tr>
+% }
+<tr>
+<td class="label" colspan="2"><h2><&|/l&>Dates</&></h2></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Created</&></td>
+<td class="value"><&|/l&>after</&>
+<& /Elements/SelectDate, Name=>"Created>", Default => ($dates->{'Created>'} ? $dates->{'Created>'}->ISO : '') &>
+<&|/l&>and before</&>
+<& /Elements/SelectDate, Name=>"Created<", Default => ($dates->{'Created<'} ? $dates->{'Created<'}->ISO:'')&>
+</td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Last updated</&></td>
+<td class="value"><&|/l&>after</&>
+<& /Elements/SelectDate, Name=>"LastUpdated>", Default =>
+($dates->{'LastUpdated>'} ? $dates->{'LastUpdated>'}->AsString:'')&>
+<&|/l&>and before</&>
+<& /Elements/SelectDate, Name=>"LastUpdated<", Default =>
+($dates->{'LastUpdated<'} ? $dates->{'LastUpdated<'}->AsString:'')&>
+</td>
+</tr>
+<tr>
+<td class="label" colspan="2"><h2><&|/l&>Links</&></h2></td>
+</tr>
+<tr>
+<td class="label"></td>
+<td><& LinkEntryInstructions &></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Refer to</&></td>
+<td class="value"><input type=text size=50 name="RefersTo" value="<%$RefersTo%>" /></td>
+</tr>
+<tr>
+<td class="label"><&|/l&>Referred to by</&></td>
+<td class="value"><input type=text size=50 name="ReferredToBy" value="<%$ReferredToBy%>" /></td>
+</tr>
+<tr>
+<td class="label" colspan="2"><h2><&|/l&>Topics</&></h2></td>
+</tr>
+<tr>
+<td class="label"></td>
+<td>
+<& /Articles/Article/Elements/EditTopics, %ARGS, Classes => \@Classes, OnlyThisClass => 1 &>
+<br />
+<input type="checkbox" name="ExpandTopics" <% $ARGS{'ExpandTopics'} ? 'checked="checked"' : "" %> />
+<&|/l&>Include subtopics</&>
+</td>
+</tr>
+</table>
+<& /Elements/Submit, Label => loc('Search') &>
+<&/Elements/TitleBoxEnd&>
+<%init>
+my @Classes =
+ ( ref $ARGS{'Class'} eq 'ARRAY' )
+ ? @{ $ARGS{'Class'} }
+ : ( $ARGS{'Class'} );
+for (@Classes) {
+ my $class = RT::Class->new( $session{'CurrentUser'} );
+ $class->LoadById($_);
+ $_ = $class;
+}
+
+for my $field ( qw/Class Name Summary Article/ ) {
+ $ARGS{"$field~"} = '' unless defined $ARGS{"$field~"};
+ $ARGS{"$field!~"} = '' unless defined $ARGS{"$field!~"};
+}
+$RefersTo = '' unless defined $RefersTo;
+$ReferredToBy = '' unless defined $ReferredToBy;
+
+</%init>
+
+<%ARGS>
+$dates =>undef
+$RefersTo => ''
+$ReferredToBy => ''
+$customfields => undef
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/Elements/ShowTopics b/rt/share/html/Articles/Article/Elements/ShowTopics
new file mode 100644
index 000000000..31aae36eb
--- /dev/null
+++ b/rt/share/html/Articles/Article/Elements/ShowTopics
@@ -0,0 +1,58 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+% my $topics = RT::ObjectTopics->new($session{'CurrentUser'});
+% $topics->LimitToObject($article);
+% my @topics;
+% while (my $t = $topics->Next) {
+<& /Articles/Elements/ShowTopic, topic => $t->TopicObj &><br />
+% }
+<br />
+
+<%args>
+$article => undef
+</%args>
diff --git a/rt/share/html/Articles/Article/ExtractFromTicket.html b/rt/share/html/Articles/Article/ExtractFromTicket.html
new file mode 100644
index 000000000..5d9eba2fc
--- /dev/null
+++ b/rt/share/html/Articles/Article/ExtractFromTicket.html
@@ -0,0 +1,105 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => loc('Extract article from ticket #[_1] into class [_2]',$Ticket, $ClassObj->Name) &>
+<& /Elements/Tabs &>
+<form action="Edit.html" method="post">
+<input type="hidden" name="Class" value="<%$ARGS{'Class'}%>" />
+<input type="hidden" name="Summary" value="<%$ticket->Subject%>" />
+% for (@Topics) {
+<input type="hidden" name="Topics" value="<% $_ %>" />
+% }
+<input type="hidden" name="new-RefersTo" value="t:<% $ticket->id%>" />
+<table width="100%" valign="top" border=0 cellspacing=0>
+<p><&|/l&>Use the dropdown menus to select which ticket updates you want to extract into a new article.</&>
+<&|/l&>You can insert ticket content into any freeform, text or wiki field.</&>
+</p>
+<tr>
+<th><&|/l&>Field</&></th>
+<th><&|/l&>Ticket update</&></th>
+</tr>
+% my $i;
+% while ( my $trans = $transactions->Next ) {
+% next unless $trans->Content;
+<tr class="<% ($i++)%2 ? 'oddline' : 'evenline'%>" >
+<td valign="top">
+<select name="Transaction-<%$trans->Id%>">
+<option value="">-</option>
+% while (my $cf = $CustomFields->Next) {
+<option value="<%$cf->Id%>"><%$cf->Name%></option>
+% }
+</select>
+</td>
+<td><b><%$trans->CreatedObj->AsString%>: <%$trans->Description%></b><br />
+<pre><%$trans->Content%></pre>
+</td>
+</tr>
+% }
+</table>
+<& /Elements/Submit, Label => loc('Create'), color => "#993333" &>
+</form>
+<%INIT>
+
+my $ticket=LoadTicket($Ticket);
+my $transactions = $ticket->Transactions;
+
+my $ClassObj = RT::Class->new($session{'CurrentUser'});
+$ClassObj->Load($Class);
+unless ($ClassObj->Id) {
+ $m->comp("/Elements/Error", Why => loc("'[_1]' isn't a valid class identifier", $Class));
+}
+my $CustomFields = $ClassObj->ArticleCustomFields();
+
+$CustomFields->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => 'Text');
+$CustomFields->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => 'Wikitext');
+$CustomFields->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => 'Freeform');
+</%init>
+<%ARGS>
+$Class => undef
+$Ticket => undef
+@Topics => ()
+</%ARGS>
diff --git a/rt/share/html/Articles/Article/ExtractIntoClass.html b/rt/share/html/Articles/Article/ExtractIntoClass.html
new file mode 100644
index 000000000..adf23fc0f
--- /dev/null
+++ b/rt/share/html/Articles/Article/ExtractIntoClass.html
@@ -0,0 +1,76 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => loc('Extract a new article from ticket #[_1]',$Ticket) &>
+<& /Elements/Tabs &>
+
+
+<h2><&|/l&>Create a new article in</&>:</h2>
+<ul>
+% my $Classes = RT::Classes->new($session{'CurrentUser'});
+% $Classes->LimitToEnabled();
+% while (my $Class = $Classes->Next) {
+<li><a href="ExtractIntoTopic.html?Ticket=<%$Ticket%>&Class=<%$Class->Id%>" onclick="document.getElementById('topics-<% $Class->Id %>').style.display = (document.getElementById('topics-<% $Class->Id %>').style.display == 'block') ? 'none' : 'block'; return false;"><%$Class->Name%></a>:
+<%$Class->Description%>
+<div id="topics-<%$Class->Id%>" style="display: none">
+<form action="ExtractFromTicket.html">
+<input type="hidden" name="Ticket" value="<% $Ticket %>" />
+<input type="hidden" name="Class" value="<% $Class->id %>" />
+<&|/l &>Select topics for this article</&>:<br />
+<& Elements/EditTopics, Classes => [$Class],
+ OnlyThisClass => 1,
+ id => 'new',
+ &><br />
+<input type="submit" value="<%loc('Create')%>" />
+</form>
+<br /></div>
+</li>
+% }
+</ul>
+<%args>
+$Ticket => undef
+</%args>
diff --git a/rt/share/html/Articles/Article/ExtractIntoTopic.html b/rt/share/html/Articles/Article/ExtractIntoTopic.html
new file mode 100644
index 000000000..72fd32464
--- /dev/null
+++ b/rt/share/html/Articles/Article/ExtractIntoTopic.html
@@ -0,0 +1,72 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => loc('Extract a new article from ticket #[_1]',$Ticket) &>
+<& /Elements/Tabs &>
+
+
+<&|/l&>Select topics for this article</&>:<br />
+<form action="ExtractFromTicket.html">
+<input type="hidden" name="Ticket" value="<% $Ticket %>" />
+<input type="hidden" name="Class" value="<% $ClassObj->id %>" />
+<& Elements/EditTopics, Classes => [$ClassObj],
+ OnlyThisClass => 1,
+ id => 'new',
+ &><br />
+<input type="submit" value="<%loc('Create')%>" />
+</form>
+<%args>
+$Ticket => undef
+$Class => undef
+</%args>
+<%init>
+my $ClassObj = RT::Class->new($session{'CurrentUser'});
+$ClassObj->Load($Class);
+unless ($ClassObj->Id) {
+ $m->comp("/Elements/Error", Why => loc("'[_1]' isn't a valid class identifier", $Class));
+}
+</%init>
diff --git a/rt/share/html/Articles/Article/History.html b/rt/share/html/Articles/Article/History.html
new file mode 100644
index 000000000..1c2873f18
--- /dev/null
+++ b/rt/share/html/Articles/Article/History.html
@@ -0,0 +1,57 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => $title &>
+<& /Elements/Tabs &>
+<& Elements/ShowHistory, id => $id &>
+<%init>
+my $title =loc('History for article #[_1]',$id);
+</%init>
+
+<%args>
+$id => undef
+</%args>
diff --git a/rt/share/html/Articles/Article/PreCreate.html b/rt/share/html/Articles/Article/PreCreate.html
new file mode 100644
index 000000000..49507d4a8
--- /dev/null
+++ b/rt/share/html/Articles/Article/PreCreate.html
@@ -0,0 +1,62 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => loc('Create an article in class...') &>
+<& /Elements/Tabs, Title => loc('Create an article in class...') &>
+<ul>
+% my $Classes = RT::Classes->new($session{'CurrentUser'});
+% $Classes->LimitToEnabled();
+% my $have_classes = 0;
+% while (my $Class = $Classes->Next) {
+% $have_classes++;
+% my $qs = $m->comp("/Elements/QueryString", %ARGS, Class=> $Class->Id);
+<li><a href="Edit.html?<% $qs|n %>"><&|/l, $Class->Name &>in class [_1]</&></a></li>
+% }
+</ul>
+% unless ( $have_classes ) {
+<span><&|/l&>Permission Denied</&></span>
+% }
diff --git a/rt/share/html/Articles/Article/Search.html b/rt/share/html/Articles/Article/Search.html
new file mode 100644
index 000000000..f995d41a7
--- /dev/null
+++ b/rt/share/html/Articles/Article/Search.html
@@ -0,0 +1,269 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+%# <sales@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., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# 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 }}}
+<& /Elements/Header, Title => loc("Search for articles") &>
+<& /Elements/Tabs &>
+
+% unless ( keys %ARGS ) {
+% my $Classes = RT::Classes->new($session{'CurrentUser'});
+% $Classes->LimitToEnabled();
+<table width="100%" border="0">
+<tr>
+<td valign="top" width="50%">
+<ul>
+% while (my $class = $Classes->Next) {
+<li><a href="<%RT->Config->Get('WebPath')%>/Articles/Article/Search.html?<% $m->comp('/Elements/QueryString', %filtered, Class => $class->id) %>"><&|/l, $class->Name&>in class [_1]</&></a></li>
+% }
+</ul>
+</td>
+<td valign="top" width="50%">
+<form action="Search.html" method="get">
+<& /Elements/TitleBoxStart, title => loc('Saved searches') &>
+<&|/l&>Load saved search:</&><br />
+<& Elements/SelectSavedSearches, Name => 'LoadSavedSearch', Default => $CurrentSearch &>
+<input value="<%loc('Load')%>" name="Load" type="submit" />
+<& /Elements/TitleBoxEnd &>
+</form>
+</td>
+</tr>
+</table>
+% return;
+% }
+
+<& /Elements/ListActions, actions => \@results &>
+<div style="float: right"><a href="#criteria"><&|/l&>Modify this search...</&></a></div>
+
+% if ($articles->BuildSelectCountQuery =~ /WHERE/i) {
+<h2><&|/l&>Search results</&></h2>
+<& /Elements/CollectionList,
+ Collection => $articles,
+ AllowSorting => 1,
+ OrderBy => \@OrderBy,
+ Order => \@Order,
+ Format => $format,
+ GenericQueryArgs => { %filtered, Format => $format, },
+ &>
+% }
+
+<br />
+<br />
+<br />
+<a name="criteria"></a>
+<form action="Search.html" method="get">
+<& Elements/ShowSearchCriteria, dates => \%dates, RefersTo => $RefersTo, customfields => $customfields, ReferredToBy => $ReferredToBy, %ARGS &>
+<br />
+<br />
+<& Elements/ShowSavedSearches, CurrentSearch => $CurrentSearch,
+ Name => ($search ? $search->Name : undef),
+ Privacy => ($search ? $search->Privacy : undef) &>
+
+</form>
+
+<div align=right>
+<a href="<%RT->Config->Get('WebPath')%>/Articles/Article/Search.html<%$QueryString%>"><&|/l&>Bookmarkable link for this search</&></a><br />
+</div>
+<%init>
+use RT::SavedSearch;
+my @results;
+my $articles = RT::Articles->new( $session{'CurrentUser'} );
+my $format = q{
+ '<a href="__WebPath__/Articles/Article/Display.html?id=__id__">__id__</a>/TITLE:#',
+ '<a href="__WebPath__/Articles/Article/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+ '__ClassName__',
+ '__CreatedRelative__',
+ '__LastUpdatedRelative__',
+ '__Summary__',
+ '__Topics__', };
+
+# {{{ Quicksearch logic
+
+# If it is a number, load the article with that ID. Otherwise, search
+# on name and summary.
+if ($ARGS{'q'} && $ARGS{'q'} =~ /^(\d+)$/) {
+ return $m->comp("/Articles/Article/Display.html", id => $1);
+}
+# }}}
+
+# {{{ Saved search logic
+
+my $search;
+
+# The keys in %ARGS that are not saved and loaded with named searches.
+# These need to be treated specially.
+my @metakeys = qw/NewSearchName CurrentSearch SearchPrivacy Save Load
+ Update Delete/;
+
+if ($CurrentSearch =~ /^(.*-\d+)-SavedSearch-(\d+)$/) {
+ $search = RT::SavedSearch->new($session{'CurrentUser'});
+ $search->Load($1, $2);
+}
+
+# Have we been asked to load a search?
+
+if ($ARGS{'Load'}) {
+ if ($ARGS{'LoadSavedSearch'} =~ /^(.*-\d+)-SavedSearch-(\d+)$/ ) {
+ my $privacy = $1;
+ my $search_id = $2;
+
+ $search = RT::SavedSearch->new($session{'CurrentUser'});
+ my ($ret, $msg) = $search->Load($privacy, $search_id);
+ if ($ret) {
+ my $searchargs = $search->GetParameter('args');
+ # Clean out ARGS and fill it in with the saved args from the
+ # loaded search.
+ foreach my $key (@metakeys) {
+ $searchargs->{$key} = $ARGS{$key};
+ }
+ %ARGS = %{$searchargs};
+ $CurrentSearch = "$privacy-SavedSearch-$search_id";
+ } else {
+ push(@results, loc("Error: could not load saved search [_1]: [_2]",
+ $ARGS{'LoadSavedSearch'}, $msg));
+ }
+ } else {
+ push(@results, loc("Invalid [_1] argument", 'LoadSavedSearch'));
+ }
+}
+
+# ...or have we been asked to save, update, or delete a search?
+
+if ($ARGS{'Save'}) {
+ my %searchargs = %ARGS;
+ foreach my $key (@metakeys) {
+ delete $searchargs{$key};
+ }
+
+ $search = RT::SavedSearch->new($session{'CurrentUser'});
+ unless ($ARGS{'SearchPrivacy'} =~ /^(.*)-(\d+)$/) {
+ # This shouldn't really happen, but hey.
+ push(@results, loc("WARNING: Saving search to user-level privacy"));
+ $ARGS{'SearchPrivacy'} = 'RT::User-'.$session{'CurrentUser'}->Id;
+ }
+ my ($ret, $msg) = $search->Save(Privacy => $ARGS{'SearchPrivacy'},
+ Type => 'Article',
+ Name => $ARGS{'NewSearchName'},
+ SearchParams => {'args' => \%searchargs});
+ if ($ret) {
+ $CurrentSearch = $ARGS{'SearchPrivacy'} . "-SavedSearch-" .
+ $search->Id;
+ push(@results, loc("Created search [_1]", $search->Name));
+ } else {
+ undef $search; # if we bomb out creating a search
+ # we don't want to have the empty object hang around
+ push(@results, loc("Could not create search: [_1]", $msg));
+ }
+} elsif ($ARGS{'Update'}) {
+ if ($ARGS{'SearchPrivacy'} != $search->Privacy) {
+ push(@results,
+ loc("Error: cannot change privacy value of existing search"));
+ } else {
+ my %searchargs = %ARGS;
+ foreach my $key (@metakeys) {
+ delete $searchargs{$key};
+ }
+
+ # We already have a search loaded, because CurrentSearch is set,
+ # or else we would not have gotten here.
+ my ($ret, $msg) = $search->Update(Name => $ARGS{'NewSearchName'},
+ SearchParams => \%searchargs);
+ if ($ret) {
+ push(@results, loc("Search [_1] updated", $search->Name));
+ } else {
+ push(@results, loc("Error: search [_1] not updated: [_2]",
+ $search->Name, $msg));
+ }
+ }
+} elsif ($ARGS{'Delete'}) {
+ # Keep track of this, as we are about to delete the search.
+ my $searchname = $search->Name;
+ my ($ret, $msg) = $search->Delete;
+ if ($ret) {
+ $ARGS{'CurrentSearch'} = undef;
+ push(@results, loc("Deleted search [_1]", $searchname));
+ # Get rid of all the state.
+ foreach my $key (keys %ARGS) {
+ delete $ARGS{$key};
+ }
+ $CurrentSearch = 'new';
+ $search = undef;
+ $RefersTo = undef;
+ $ReferredToBy = undef;
+ } else {
+ push(@results, loc("Could not delete search [_1]: [_2]",
+ $searchname, $msg));
+ }
+}
+
+# }}}
+
+ # Don't want to search for a null class when there is no class specced
+my $customfields = RT::CustomFields->new( $session{'CurrentUser'} );
+my %dates;
+
+$articles->Search( %ARGS, CustomFields => $customfields, Dates => \%dates,
+ OrderBy => \@OrderBy, Order => \@Order, );
+
+$m->callback( %ARGS, _Search => $articles );
+
+my %filtered = %ARGS;
+delete $filtered{$_} for (@metakeys, "EditTopics", "ExpandTopics");
+delete $filtered{$_} for grep {$filtered{$_} !~ /\S/} keys %filtered;
+@filtered{qw(OrderBy Order)} = (\@OrderBy, \@Order);
+my $QueryString = "?".$m->comp('/Elements/QueryString', %filtered);
+</%init>
+
+<%ARGS>
+$CreatedBefore => ''
+$CreatedAfter => ''
+$LastUpdatedBefore => ''
+$LastUpdatedAfter => ''
+$RefersTo => undef
+$ReferredToBy => undef
+$CurrentSearch => 'new'
+@OrderBy => ()
+@Order => ()
+</%ARGS>