%# BEGIN BPS TAGGED BLOCK {{{ %# %# COPYRIGHT: %# %# This software is Copyright (c) 1996-2026 Best Practical Solutions, LLC %# %# %# (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 &>
<&| /Widgets/TitleBox, title => $title, class => 'article-basics', &> <& Elements/EditBasics, ArticleObj => $ArticleObj, EditClass => 1, DefaultClass => $DefaultClass, ClassObj => $ClassObj, %ARGS , id => $id, &> % my $content_title = 'Content' . ( $content_type eq 'Links' ? ' - Links' : '' ); <&| /Widgets/TitleBox, title => $content_title, class => 'article-content', &>
<& Elements/EditCustomFields, ArticleObj => $ArticleObj, CFContent => \%CFContent, ClassObj => $ClassObj, ClassChanged => $ARGS{ClassChanged}, %ARGS, id => $id, ForCreation => ($id eq 'new'), &>
<% loc('Title') %>
<% loc('Link') %>
<% loc('Description') %>
% my $number = 1; % foreach my $link ( @content_links ) {
% foreach my $field ( qw( title link description ) ) {
% }
% $number++; % }
<&| /Widgets/TitleBox, title => 'Links', class => 'article-links', &> <& Elements/EditLinks, ArticleObj => $ArticleObj, %ARGS, id => $id &> <&| /Widgets/TitleBox, title => 'Topics', class => 'article-topics', &> <& Elements/EditTopics, ArticleObj => $ArticleObj, Classes => [$ArticleObj->Id ? $ArticleObj->ClassObj : $ClassObj], OnlyThisClass => 1, %ARGS, id => $id &> <& /Elements/Submit, Label => ($id eq 'new' ? loc('Create') : loc('Save Changes')), color => "#993333", FullWidth => 1 &>
<%INIT> my $MIN_CONTENT_LINK_ROWS = 3; 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 $DefaultClass; if ($Class) { $ClassObj->Load($Class); Abort(loc("'[_1]' isn't a valid class", $Class)) unless $ClassObj->Id; $DefaultClass = $ClassObj->Id; } # If we don't have a class, default to the first class that user can # see and in which user can create articles if (!$DefaultClass) { my $Classes = RT::Classes->new($session{'CurrentUser'}); $Classes->LimitToEnabled(); while (my $class = $Classes->Next) { next unless ($class->Name); $DefaultClass = $class->Id; $ClassObj = $class; last; } } my %create_args; my %CFContent; if ( $ARGS{SetEnabled} ) { $ARGS{Disabled} = $ARGS{Enabled} ? 0 : 1; } my $sortorder_ok = 1; if ($ARGS{SortOrder}) { if ($ARGS{SortOrder} !~ /^-?\d+$/) { push @results, (0, loc('Sort Order must be an integer')); $sortorder_ok = 0; } } # check if this is a Links type article being created/updated my @content_links; if ( $id && $Class && ( ( $ARGS{Type} || '' ) eq 'Links' ) ) { # determine the content cf my $content_cf; my $CustomFields = $ClassObj->ArticleCustomFields(); while ( my $cf = $CustomFields->Next ) { if ( $cf->Name eq 'Content' ) { $content_cf = $cf; last; } } if ( $content_cf ) { # this is a page submit # check if we have content links in ARGS my @links; foreach my $arg ( keys %ARGS ) { if ( $arg =~ /^article-link-(\w+)-(\d+)$/ ) { my $field = $1; my $index = $2 - 1; my $link = $links[$index] || {}; $link->{$field} = $ARGS{$arg}; $links[$index] = $link; } } @links = grep { $_->{title} && $_->{link} } @links; my $content = ''; my $arg = 'Object-RT::Article-' . ( $id eq 'new' ? '' : $id ) . '-CustomField-' . $content_cf->Id . '-Values'; $ARGS{$arg} = $content; } else { push @results, loc(q{Articles of type 'Links' must have a 'Content' custom field}); $ARGS{Type} = 'Content'; RT->Logger->error("No Content custom field for article with type Links for class: $Class"); } } if ( !$id ) { $title = loc('Create a new article'); foreach my $arg ( sort keys %ARGS ) { if ( $arg =~ /^Transaction-(\d+)$/ and $ARGS{$arg} ) { my $trans = RT::Transaction->new( $session{'CurrentUser'} ); $trans->Load($1); my $cf_id = $ARGS{$arg}; my $cf = RT::CustomField->new( $session{'CurrentUser'} ); $cf->LoadById( $cf_id ); if ($CFContent{$cf_id}) { if ($cf->Type eq 'HTML') { $CFContent{$cf_id} .= "

"; } else { $CFContent{$cf_id} .= "\n\n"; } } $CFContent{$cf_id} .= $trans->Content( ($cf->Type eq 'HTML') ? (Type => 'text/html') : () ); } } $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'} ); } my %cfs; if (!$ARGS{ClassChanged}) { if ($sortorder_ok) { %cfs = ProcessObjectCustomFieldUpdatesForCreate( ARGSRef => \%ARGS, ContextObject => $ClassObj, ); my $msg; ( $id, $msg ) = $ArticleObj->Create( Summary => $ARGS{'Summary'}, Name => $ARGS{'Name'}, Type => $ARGS{'Type'}, SortOrder => $ARGS{'SortOrder'}, Class => $ARGS{'Class'}, Topics => $ARGS{'Topics'}, Disabled => $ARGS{'Disabled'}, %create_args, %cfs ); push( @results, $msg ); } else { $id = 0; } } else { $id = 0; } if ($id) { $ArticleObj->Load($id); $title = loc( 'Modify article #[_1]', $ArticleObj->Id ); delete $ARGS{id}; MaybeRedirectForResults( Actions => \@results, Arguments => { id => $ArticleObj->id }, ); } else { $ArticleObj = RT::Article->new( $session{'CurrentUser'} ); $id = 'new'; $title = loc('Create a new article'); } } else { $ArticleObj->Load($id); unless ( $ArticleObj->id ) { $m->comp( "/Elements/Error", Why => loc("Unable to load article") ); } # If it was a real submit, make changes. # If it was just a reload to change the Class, don't make changes. if (!$ARGS{ClassChanged}) { my @attribs = qw(Name Type Summary Class Disabled SortOrder); if ($sortorder_ok) { push @results, UpdateRecordObject( AttributesRef => \@attribs, Object => $ArticleObj, ARGSRef => \%ARGS ); } my @cf_results = ProcessObjectCustomFieldUpdates( Object => $ArticleObj, ARGSRef => \%ARGS ); # change update message for links type update to Content if ( @content_links ) { @cf_results = map { /^Content \