diff options
author | Ivan Kohler <ivan@freeside.biz> | 2015-07-09 22:32:26 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2015-07-09 22:32:26 -0700 |
commit | 026dc7ad72ba972f230b6709e31fa64397d75ad4 (patch) | |
tree | c5af1a7ac9154744afc3660e9a9405892f2bb50b /rt/share/html/Articles | |
parent | 07b4bc84d1078f7390221d766cdb3142513db4b0 (diff) | |
parent | 1c538bfabc2cd31f27067505f0c3d1a46cba6ef0 (diff) |
merge RT 4.2.11 and Header changes to disable RT javascript, RT#34237
Diffstat (limited to 'rt/share/html/Articles')
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" /> <input value="<%loc('Save new')%>" name="Save" type="submit" /> @@ -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%"> |