summaryrefslogtreecommitdiff
path: root/rt/share/html/Articles
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2015-07-09 22:32:26 -0700
committerIvan Kohler <ivan@freeside.biz>2015-07-09 22:32:26 -0700
commit026dc7ad72ba972f230b6709e31fa64397d75ad4 (patch)
treec5af1a7ac9154744afc3660e9a9405892f2bb50b /rt/share/html/Articles
parent07b4bc84d1078f7390221d766cdb3142513db4b0 (diff)
parent1c538bfabc2cd31f27067505f0c3d1a46cba6ef0 (diff)
merge RT 4.2.11 and Header changes to disable RT javascript, RT#34237
Diffstat (limited to 'rt/share/html/Articles')
-rw-r--r--rt/share/html/Articles/Article/Edit.html67
-rw-r--r--rt/share/html/Articles/Article/Elements/EditCustomFields10
-rw-r--r--rt/share/html/Articles/Article/Elements/EditLinks12
-rw-r--r--rt/share/html/Articles/Article/Elements/Preformatted15
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowLinks8
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowSavedSearches7
-rw-r--r--rt/share/html/Articles/Article/Elements/ShowSearchCriteria10
-rw-r--r--rt/share/html/Articles/Article/History.html20
-rw-r--r--rt/share/html/Articles/Article/PreCreate.html36
-rw-r--r--rt/share/html/Articles/Article/Search.html145
-rw-r--r--rt/share/html/Articles/Elements/CreateArticle4
-rw-r--r--rt/share/html/Articles/Elements/MaybeNeedsSetup (renamed from rt/share/html/Articles/Article/Elements/ShowHistory)33
-rw-r--r--rt/share/html/Articles/Elements/NeedsSetup52
-rw-r--r--rt/share/html/Articles/Elements/NewestArticles4
-rw-r--r--rt/share/html/Articles/Elements/QuickSearch4
-rw-r--r--rt/share/html/Articles/Elements/ShowTopicLink2
-rw-r--r--rt/share/html/Articles/Elements/SubjectOverride92
-rw-r--r--rt/share/html/Articles/Elements/UpdatedArticles4
-rw-r--r--rt/share/html/Articles/index.html1
19 files changed, 316 insertions, 210 deletions
diff --git a/rt/share/html/Articles/Article/Edit.html b/rt/share/html/Articles/Article/Edit.html
index 075b28bc9..a6e5e12fe 100644
--- a/rt/share/html/Articles/Article/Edit.html
+++ b/rt/share/html/Articles/Article/Edit.html
@@ -115,6 +115,12 @@ my $title;
my $Entries = {};
my $ArticleObj = RT::Article->new( $session{'CurrentUser'} );
my $ClassObj = RT::Class->new( $session{'CurrentUser'} );
+
+if ($Class) {
+ $ClassObj->Load($Class);
+ Abort(loc("'[_1]' isn't a valid class", $Class)) unless $ClassObj->Id;
+}
+
my %create_args;
my %CFContent;
my $EditClass = 1;
@@ -129,11 +135,6 @@ if ( !$id ) {
}
}
- $ClassObj->Load($Class);
- unless ( $ClassObj->Id ) {
- $m->comp( "/Elements/Error",
- Why => loc( "'[_1]' isn't a valid class identifier", $Class ) );
- }
$EditClass = 0;
$id = 'new';
}
@@ -149,48 +150,10 @@ elsif ( $id eq 'new' ) {
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->SetContextObject( $ArticleObj );
- $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 %cfs = ProcessObjectCustomFieldUpdatesForCreate(
+ ARGSRef => \%ARGS,
+ ContextObject => $ClassObj,
+ );
my $msg;
( $id, $msg ) = $ArticleObj->Create(
@@ -198,7 +161,8 @@ elsif ( $id eq 'new' ) {
Name => $ARGS{'Name'},
Class => $ARGS{'Class'},
Topics => $ARGS{'Topics'},
- %create_args
+ %create_args,
+ %cfs
);
push( @results, $msg );
if ($id) {
@@ -219,12 +183,7 @@ elsif ( $id eq 'new' ) {
);
}
}
- if (!$id) {
- $ClassObj->Load($Class);
- unless ( $ClassObj->Id ) {
- $m->comp( "/Elements/Error",
- Why => loc( "'[_1]' isn't a valid class identifier", $Class ) );
- }
+ else {
$ArticleObj = RT::Article->new( $session{'CurrentUser'} );
$id = 'new';
$EditClass = 0;
diff --git a/rt/share/html/Articles/Article/Elements/EditCustomFields b/rt/share/html/Articles/Article/Elements/EditCustomFields
index 8af299236..386529597 100644
--- a/rt/share/html/Articles/Article/Elements/EditCustomFields
+++ b/rt/share/html/Articles/Article/Elements/EditCustomFields
@@ -51,12 +51,7 @@
<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'})
- ,
+ Default => $CFContent->{$CustomField->Id},
Rows => 15,
Cols => 70
&></td>
@@ -64,15 +59,12 @@
% }
<%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>
diff --git a/rt/share/html/Articles/Article/Elements/EditLinks b/rt/share/html/Articles/Article/Elements/EditLinks
index 9e8567ef9..325e5809c 100644
--- a/rt/share/html/Articles/Article/Elements/EditLinks
+++ b/rt/share/html/Articles/Article/Elements/EditLinks
@@ -63,9 +63,9 @@
% while (my $link = $refersto->Next) {
% my $member = $link->TargetURI;
<li>
-<input type="CHECKBOX" name="DeleteLink--<%$link->Type%>-<%$link->Target%>" />
+<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>:
+<a href="<%$member->AsHREF%>"><% loc($member->Object->RecordType) %> <%$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')) {
@@ -73,7 +73,7 @@
% }
</a>
% } else {
-<a href="<%$member->Resolver->HREF%>"><%$link->Target%></a>
+<a href="<%$member->AsHREF%>"><%$link->Target%></a>
% }
% }
% }
@@ -90,9 +90,9 @@
% while (my $link = $referredtoby->Next) {
% my $member = $link->BaseURI;
<li>
-<input type="CHECKBOX" name="DeleteLink-<%$link->Base%>-<%$link->Type%>-" />
+<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%>:
+<a href="<%$member->AsHREF%>"><% loc($member->Object->RecordType) %> <%$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')) {
@@ -100,7 +100,7 @@
% }
</a>
% } else {
-<a href="<%$member->Resolver->HREF%>"><%$link->Base%></a>
+<a href="<%$member->AsHREF%>"><%$link->Base%></a>
% }
% }
% }
diff --git a/rt/share/html/Articles/Article/Elements/Preformatted b/rt/share/html/Articles/Article/Elements/Preformatted
index 7e3ab7cbd..acfe6330f 100644
--- a/rt/share/html/Articles/Article/Elements/Preformatted
+++ b/rt/share/html/Articles/Article/Elements/Preformatted
@@ -89,19 +89,6 @@ 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;
@@ -116,7 +103,7 @@ my $get_content = sub {
);
if ( $content =~ /<.{1,5}>/ ) {
- $content = $de_htmlify->( $content );
+ $content = RT::Interface::Email::ConvertHTMLToText( $content );
}
return $content;
};
diff --git a/rt/share/html/Articles/Article/Elements/ShowLinks b/rt/share/html/Articles/Article/Elements/ShowLinks
index 50a971a39..80b00e39f 100644
--- a/rt/share/html/Articles/Article/Elements/ShowLinks
+++ b/rt/share/html/Articles/Article/Elements/ShowLinks
@@ -53,7 +53,7 @@
% my $member = $link->TargetURI;
<li>
% if ($link->TargetURI->IsLocal) {
-<a href="<%$member->Resolver->HREF%>"><% loc($member->Object->ObjectTypeStr) %> <%$member->Object->Id%>:
+<a href="<%$member->AsHREF%>"><% loc($member->Object->RecordType) %> <%$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')) {
@@ -61,7 +61,7 @@
% }
</a>
% } else {
-<a href="<%$member->Resolver->HREF%>"><%$link->Target%></a>
+<a href="<%$member->AsHREF%>"><%$link->Target%></a>
% }
</li>
% }
@@ -74,7 +74,7 @@
% my $member = $link->BaseURI;
<li>
% if ($member->IsLocal) {
-<a href="<%$member->Resolver->HREF%>"><% loc($member->Object->ObjectTypeStr) %> <%$member->Object->Id%>:
+<a href="<%$member->AsHREF%>"><% loc($member->Object->RecordType) %> <%$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')) {
@@ -82,7 +82,7 @@
% }
</a>
% } else {
-<a href="<%$member->Resolver->HREF%>"><%$link->Base%></a>
+<a href="<%$member->AsHREF%>"><%$link->Base%></a>
% }
</li>
% }
diff --git a/rt/share/html/Articles/Article/Elements/ShowSavedSearches b/rt/share/html/Articles/Article/Elements/ShowSavedSearches
index 03396c5e8..e06b79fc5 100644
--- a/rt/share/html/Articles/Article/Elements/ShowSavedSearches
+++ b/rt/share/html/Articles/Article/Elements/ShowSavedSearches
@@ -45,7 +45,7 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc('Saved searches') &>
+<& /Widgets/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.
@@ -53,8 +53,7 @@
% Object=> $RT::System )) {
<h2><&|/l&>Save this search</&></h2>
<&|/l&>Name:</&> <input name="NewSearchName" value="<%$Name||''%>">
-<&|/l&>Privacy:</&> <& SelectSearchPrivacy, Name => 'SearchPrivacy',
- Default => $Privacy &><br />
+<&|/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;
@@ -68,7 +67,7 @@
<h2><&|/l&>Load a saved search</&></h2>
<& SelectSavedSearches, Name => 'LoadSavedSearch', Default => $CurrentSearch &>
<input value="<%loc('Load')%>" name="Load" type="submit">
-<& /Elements/TitleBoxEnd &>
+<& /Widgets/TitleBoxEnd &>
<%INIT>
unless ($session{'CurrentUser'}->HasRight( Right => 'LoadSavedSearch',
diff --git a/rt/share/html/Articles/Article/Elements/ShowSearchCriteria b/rt/share/html/Articles/Article/Elements/ShowSearchCriteria
index ad464f8ca..b4dec87f7 100644
--- a/rt/share/html/Articles/Article/Elements/ShowSearchCriteria
+++ b/rt/share/html/Articles/Article/Elements/ShowSearchCriteria
@@ -46,9 +46,9 @@
%#
%# END BPS TAGGED BLOCK }}}
% if ($ARGS{'HideOptions'}) {
-<& /Elements/TitleBoxStart, title => loc('Advanced search'), class => "rolled-up", bodyclass => "hidden" &>
+<& /Widgets/TitleBoxStart, title => loc('Advanced search'), class => "rolled-up", bodyclass => "hidden" &>
% } else {
-<& /Elements/TitleBoxStart, title => loc('Advanced search') &>
+<& /Widgets/TitleBoxStart, title => loc('Advanced search') &>
% }
<table>
<tr>
@@ -136,13 +136,13 @@
<td>
<& /Articles/Article/Elements/EditTopics, %ARGS, Classes => \@Classes, OnlyThisClass => 1 &>
<br />
-<input type="checkbox" name="ExpandTopics" <% $ARGS{'ExpandTopics'} ? 'checked="checked"' : "" %> />
-<&|/l&>Include subtopics</&>
+<input type="checkbox" id="ExpandTopics" name="ExpandTopics" <% $ARGS{'ExpandTopics'} ? 'checked="checked"' : "" %> />
+<label for="ExpandTopics"><&|/l&>Include subtopics</&></label>
</td>
</tr>
</table>
<& /Elements/Submit, Label => loc('Search') &>
-<&/Elements/TitleBoxEnd&>
+<& /Widgets/TitleBoxEnd &>
<%init>
my @Classes =
( ref $ARGS{'Class'} eq 'ARRAY' )
diff --git a/rt/share/html/Articles/Article/History.html b/rt/share/html/Articles/Article/History.html
index 2ac352023..07437ccbb 100644
--- a/rt/share/html/Articles/Article/History.html
+++ b/rt/share/html/Articles/Article/History.html
@@ -45,13 +45,25 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/Header, Title => $title &>
+<& /Elements/Header, Title => loc('History for article #[_1]', $id) &>
<& /Elements/Tabs &>
-<& Elements/ShowHistory, id => $id &>
+<& /Elements/ShowHistory,
+ Object => $article,
+ ShowHeaders => 0,
+ ShowDisplayModes => 0,
+ ShowActions => 0,
+ DisplayPath => 'History.html',
+ &>
<%init>
-my $title =loc('History for article #[_1]',$id);
-</%init>
+my $article = RT::Article->new($session{'CurrentUser'});
+$article->Load($id);
+
+Abort(loc("Article #[_1] not found", $id))
+ unless $article->Id;
+Abort(loc("Permission Denied"))
+ unless $article->CurrentUserHasRight('ShowArticle');
+</%init>
<%args>
$id => undef
</%args>
diff --git a/rt/share/html/Articles/Article/PreCreate.html b/rt/share/html/Articles/Article/PreCreate.html
index 7a8c05e22..6daa23246 100644
--- a/rt/share/html/Articles/Article/PreCreate.html
+++ b/rt/share/html/Articles/Article/PreCreate.html
@@ -47,17 +47,37 @@
%# END BPS TAGGED BLOCK }}}
<& /Elements/Header, Title => loc('Create an article in class...') &>
<& /Elements/Tabs &>
+
+% if (not $classes_configured) {
+<& /Articles/Elements/NeedsSetup &>
+% } elsif (not @classes) {
+<i><&|/l&>You don't have permission to create Articles in any Class</&></i>
+% } else {
<ul>
-% my $Classes = RT::Classes->new($session{'CurrentUser'});
-% $Classes->LimitToEnabled();
-% my $have_classes = 0;
-% while (my $Class = $Classes->Next) {
-% $have_classes++;
+% for my $Class (@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>
-<p><span><&|/l&>To create an Article, you must first create a Class and have access to that Class.</&></span></p>
% }
+<%init>
+my $Classes = RT::Classes->new($session{'CurrentUser'});
+$Classes->LimitToEnabled();
+
+# This is a COUNT(), which doesn't apply ACLs; as such, we don't display
+# the warning if there are classes, but the user can't see them.
+my $classes_configured = $Classes->Count;
+
+# ->Next applies SeeClass, but we also want to check CreateArticle
+my @classes;
+while (my $class = $Classes->Next) {
+ push @classes, $class if $class->CurrentUserHasRight("CreateArticle");
+}
+
+# If there is only one, redirect to it
+MaybeRedirectForResults(
+ Path => "/Articles/Article/Edit.html",
+ Force => 1,
+ Arguments => { Class => $classes[0]->id },
+) if @classes == 1;
+</%init>
diff --git a/rt/share/html/Articles/Article/Search.html b/rt/share/html/Articles/Article/Search.html
index ad5eba97e..4b8745a57 100644
--- a/rt/share/html/Articles/Article/Search.html
+++ b/rt/share/html/Articles/Article/Search.html
@@ -49,24 +49,28 @@
<& /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%">
+% if (not $classes_configured) {
+<& /Articles/Elements/NeedsSetup &>
+% } elsif (not @classes) {
+<i><&|/l&>You don't have permission to view Articles in any Class</&></i>
+% } else {
<ul>
-% while (my $class = $Classes->Next) {
+% for my $class (@classes) {
<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') &>
+<& /Widgets/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 &>
+<& /Widgets/TitleBoxEnd &>
</form>
</td>
</tr>
@@ -107,6 +111,15 @@
<a href="<%RT->Config->Get('WebPath')%>/Articles/Article/Search.html<%$QueryString%>"><&|/l&>Bookmarkable link for this search</&></a><br />
</div>
<%init>
+my $Classes = RT::Classes->new($session{'CurrentUser'});
+$Classes->LimitToEnabled();
+
+# This is a COUNT(), which doesn't apply ACLs; as such, we don't display
+# the warning if there are classes, but the user can't see them.
+my $classes_configured = $Classes->Count;
+my @classes = @{ $Classes->ItemsArrayRef };
+$ARGS{Class} = $classes[0]->id if @classes == 1;
+
use RT::SavedSearch;
my @results;
my $articles = RT::Articles->new( $session{'CurrentUser'} );
@@ -146,26 +159,26 @@ if ($CurrentSearch =~ /^(.*-\d+)-SavedSearch-(\d+)$/) {
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));
- }
+ 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'));
+ push(@results, loc("Invalid [_1] argument", 'LoadSavedSearch'));
}
}
@@ -174,67 +187,67 @@ if ($ARGS{'Load'}) {
if ($ARGS{'Save'}) {
my %searchargs = %ARGS;
foreach my $key (@metakeys) {
- delete $searchargs{$key};
+ 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;
+ # 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});
+ 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));
+ $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));
+ 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"));
+ 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));
- }
+ 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;
+ $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));
+ push(@results, loc("Could not delete search [_1]: [_2]",
+ $searchname, $msg));
}
}
diff --git a/rt/share/html/Articles/Elements/CreateArticle b/rt/share/html/Articles/Elements/CreateArticle
index 3fb549f7c..7121b0c41 100644
--- a/rt/share/html/Articles/Elements/CreateArticle
+++ b/rt/share/html/Articles/Elements/CreateArticle
@@ -45,13 +45,13 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc('Create an article') &>
+<& /Widgets/TitleBoxStart, title => loc('Create an article') &>
<ul>
% while (my $Class = $Classes->Next) {
<li><a href="Article/Edit.html?Class=<%$Class->Id%>"><%$Class->Name%></a></li>
% }
</ul>
-<& /Elements/TitleBoxEnd &>
+<& /Widgets/TitleBoxEnd &>
<%init>
my $Classes = RT::Classes->new($session{'CurrentUser'});
$Classes->LimitToEnabled;
diff --git a/rt/share/html/Articles/Article/Elements/ShowHistory b/rt/share/html/Articles/Elements/MaybeNeedsSetup
index 136640e4a..40f1d4889 100644
--- a/rt/share/html/Articles/Article/Elements/ShowHistory
+++ b/rt/share/html/Articles/Elements/MaybeNeedsSetup
@@ -45,32 +45,11 @@
%# 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();
-
+my $Classes = RT::Classes->new( $session{'CurrentUser'} );
+$Classes->LimitToEnabled();
+# This is a COUNT(), which doesn't apply ACLs; as such, we don't display
+# the warning if there are classes, but the user can't see them.
+return if $Classes->Count;
</%init>
-<%args>
-$id => undef
-</%args>
+<& NeedsSetup &>
diff --git a/rt/share/html/Articles/Elements/NeedsSetup b/rt/share/html/Articles/Elements/NeedsSetup
new file mode 100644
index 000000000..d2722f35b
--- /dev/null
+++ b/rt/share/html/Articles/Elements/NeedsSetup
@@ -0,0 +1,52 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2015 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 }}}
+%# Stupidly long lines because our extract-message-catalog doesn't handle multiple lines!
+<&|/Widgets/TitleBox, id => "articles-needs-setup", class => "error-titlebox", title => loc("Setup needed") &>
+<p><&|/l_unsafe, qq[<a href="@{[RT->Config->Get("WebPath")]}/Admin/Articles/">], '</a>' &>Before Articles can be used, your RT administrator must [_1]create Classes[_2], apply Article custom fields to them, and grant users rights on the classes and CFs.</&></p>
+<p><&|/l_unsafe, qq[<a href="http://bestpractical.com/rt/docs/$RT::MAJOR_VERSION.$RT::MINOR_VERSION/customizing/articles_introduction.html">], qq[<a href="http://bestpractical.com/rt/docs/$RT::MAJOR_VERSION.$RT::MINOR_VERSION/">], '</a>' &>An [_1]introduction to getting started with articles[_3] is available from [_2]Best Practical's online documentation[_3].</&></p>
+</&>
diff --git a/rt/share/html/Articles/Elements/NewestArticles b/rt/share/html/Articles/Elements/NewestArticles
index 8ceedeca0..02cd389ec 100644
--- a/rt/share/html/Articles/Elements/NewestArticles
+++ b/rt/share/html/Articles/Elements/NewestArticles
@@ -45,7 +45,7 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc("[_1] newest articles", $rows), bodyclass=> '' &>
+<& /Widgets/TitleBoxStart, title => loc("[_1] newest articles", $rows), bodyclass=> '' &>
<table border="0" cellspacing="0" cellpadding="1" width="100%">
<tr>
<th align="right"><&|/l&>#</&></th>
@@ -67,7 +67,7 @@
</tr>
% }
</table>
-<& /Elements/TitleBoxEnd &>
+<& /Widgets/TitleBoxEnd &>
<%INIT>
my $rows = 10;
my $i;
diff --git a/rt/share/html/Articles/Elements/QuickSearch b/rt/share/html/Articles/Elements/QuickSearch
index da5d8247d..858fad34c 100644
--- a/rt/share/html/Articles/Elements/QuickSearch
+++ b/rt/share/html/Articles/Elements/QuickSearch
@@ -45,13 +45,13 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc('Quick search') &>
+<& /Widgets/TitleBoxStart, title => loc('Quick search') &>
<ul>
% while (my $class = $classes->Next) {
<li><a href="<%RT->Config->Get('WebPath')%>/Articles/Article/Search.html?Class=<%$class->Name%>&Parent=0&HideOptions=1"><%$class->Name%></a></li>
% }
</ul>
-<& /Elements/TitleBoxEnd &>
+<& /Widgets/TitleBoxEnd &>
<%init>
my $classes = RT::Classes->new($session{'CurrentUser'});
$classes->LimitToEnabled;
diff --git a/rt/share/html/Articles/Elements/ShowTopicLink b/rt/share/html/Articles/Elements/ShowTopicLink
index 147e5c9c1..cf54a6438 100644
--- a/rt/share/html/Articles/Elements/ShowTopicLink
+++ b/rt/share/html/Articles/Elements/ShowTopicLink
@@ -58,7 +58,7 @@ $Class => 0
% }
% if ( $Articles->Count ) {
- (<&|/l, $Articles->Count &>[quant,_1,article]</&>)
+ (<&|/l, $Articles->Count &>[quant,_1,article,articles]</&>)
% }
% if ($Link) {
diff --git a/rt/share/html/Articles/Elements/SubjectOverride b/rt/share/html/Articles/Elements/SubjectOverride
new file mode 100644
index 000000000..eb10fbb9f
--- /dev/null
+++ b/rt/share/html/Articles/Elements/SubjectOverride
@@ -0,0 +1,92 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2015 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 }}}
+<%INIT>
+foreach my $arg ( keys %$ARGSRef) {
+
+ my $Queue = $QueueObj || RT::Queue->new($session{CurrentUser});
+ if (!$Queue->Id && $Ticket && $Ticket->Id) {
+ $Queue = $Ticket->QueueObj;
+ }
+
+ my $article = RT::Article->new($session{'CurrentUser'});
+ $article->LoadByInclude(
+ Field => $arg,
+ Value => $ARGSRef->{$arg},
+ Queue => $Queue->Id,
+ );
+ next unless $article && $article->id;
+
+ my $class = $article->ClassObj;
+
+ next unless $class->SubjectOverride;
+
+ my $cfs = $class->ArticleCustomFields;
+ $cfs->Limit( FIELD => 'id', VALUE => $class->SubjectOverride );
+
+ my $subjectCF = $cfs->First;
+ next unless $subjectCF;
+
+ my $subject = $article->CustomFieldValuesAsString($subjectCF->Id);
+
+ $m->callback( CallbackName => 'ProcessContent', Ticket => $Ticket, Article => $article, content => \$subject);
+
+ if ( exists $ARGSRef->{UpdateSubject} ) {
+ $ARGSRef->{UpdateSubject} = $subject;
+ } else {
+ $ARGSRef->{Subject} = $subject;
+ }
+}
+return;
+</%INIT>
+<%ARGS>
+$Ticket => undef
+$ARGSRef => undef
+$results => undef
+$QueueObj => undef
+</%ARGS>
+
diff --git a/rt/share/html/Articles/Elements/UpdatedArticles b/rt/share/html/Articles/Elements/UpdatedArticles
index c2e1ff810..1a1ec5264 100644
--- a/rt/share/html/Articles/Elements/UpdatedArticles
+++ b/rt/share/html/Articles/Elements/UpdatedArticles
@@ -45,7 +45,7 @@
%# those contributions and any derivatives thereof.
%#
%# END BPS TAGGED BLOCK }}}
-<& /Elements/TitleBoxStart, title => loc("[_1] most recently updated articles", $rows), bodyclass=> '' &>
+<& /Widgets/TitleBoxStart, title => loc("[_1] most recently updated articles", $rows), bodyclass=> '' &>
<table border="0" cellspacing="0" cellpadding="1" width="100%">
<tr>
<th align="right"><&|/l&>#</&></th>
@@ -68,7 +68,7 @@
</tr>
% }
</table>
-<& /Elements/TitleBoxEnd &>
+<& /Widgets/TitleBoxEnd &>
<%INIT>
my $rows = 10;
my $i;
diff --git a/rt/share/html/Articles/index.html b/rt/share/html/Articles/index.html
index bfe4a1f07..4143f1d36 100644
--- a/rt/share/html/Articles/index.html
+++ b/rt/share/html/Articles/index.html
@@ -47,6 +47,7 @@
%# END BPS TAGGED BLOCK }}}
<& /Elements/Header, Title => loc('Articles') &>
<& /Elements/Tabs &>
+<& /Articles/Elements/MaybeNeedsSetup &>
<table width="100%">
<tr>
<td valign="top" width="70%">