X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;ds=sidebyside;f=rt%2Fshare%2Fhtml%2FREST%2F1.0%2FForms%2Fticket%2Fdefault;h=ab97059cb09b6fe338bbdbab247a66b882a940a2;hb=44dd00a3ff974a17999e86e64488e996edc71e3c;hp=b82cb5ed620dd524f2d2ebede873ecd49eed4b4a;hpb=b4b0c7e72d7eaee2fbfc7022022c9698323203dd;p=freeside.git diff --git a/rt/share/html/REST/1.0/Forms/ticket/default b/rt/share/html/REST/1.0/Forms/ticket/default index b82cb5ed6..ab97059cb 100755 --- a/rt/share/html/REST/1.0/Forms/ticket/default +++ b/rt/share/html/REST/1.0/Forms/ticket/default @@ -1,40 +1,40 @@ %# BEGIN BPS TAGGED BLOCK {{{ -%# +%# %# COPYRIGHT: -%# -%# This software is Copyright (c) 1996-2009 Best Practical Solutions, LLC -%# -%# +%# +%# This software is Copyright (c) 1996-2019 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 @@ -43,7 +43,7 @@ %# 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 }}} %# REST/1.0/Forms/ticket/default %# @@ -62,12 +62,12 @@ my $cf_spec = RT::Interface::REST->custom_field_spec(1); my @comments; my ($c, $o, $k, $e) = ("", [], {}, 0); my %data = %$changes; -my $ticket = new RT::Ticket $session{CurrentUser}; +my $ticket = RT::Ticket->new($session{CurrentUser}); my @dates = qw(Created Starts Started Due Resolved Told LastUpdated); my @people = qw(Requestors Cc AdminCc); my @create = qw(Queue Requestor Subject Cc AdminCc Owner Status Priority InitialPriority FinalPriority TimeEstimated TimeWorked - TimeLeft Starts Started Due Resolved); + TimeLeft Starts Started Due Resolved Content-Type); my @simple = qw(Subject Status Priority Disabled TimeEstimated TimeWorked TimeLeft InitialPriority FinalPriority); my %dates = map {lc $_ => $_} @dates; @@ -81,29 +81,40 @@ if ($id ne 'new') { if (!$ticket->Id) { return [ "# Ticket $id does not exist.", [], {}, 1 ]; } - elsif (!$ticket->CurrentUserHasRight('ShowTicket') || - (%data && !$ticket->CurrentUserHasRight('ModifyTicket'))) - { - my $act = %data ? "modify" : "display"; - return [ "# You are not allowed to $act ticket $id.", [], {}, 1 ]; + elsif ( %data ) { + if ( $data{status} && lc $data{status} eq 'deleted' && ! grep { $_ ne 'id' && $_ ne 'status' } keys %data ) { + if ( !$ticket->CurrentUserHasRight('DeleteTicket') ) { + return [ "# You are not allowed to delete ticket $id.", [], {}, 1 ]; + } + } + elsif ( !$ticket->CurrentUserHasRight('ModifyTicket') ) { + return [ "# You are not allowed to modify ticket $id.", [], {}, 1 ]; + } + } + elsif (!$ticket->CurrentUserHasRight('ShowTicket')) { + return [ "# You are not allowed to display ticket $id.", [], {}, 1 ]; } } else { if (!keys(%data)) { # GET ticket/new: Return a suitable default form. # We get defaults from queue/1 (XXX: What if it isn't there?). - my $due = new RT::Date $session{CurrentUser}; - my $queue = new RT::Queue $session{CurrentUser}; - my $starts = new RT::Date $session{CurrentUser}; + my $queue = RT::Queue->new($session{CurrentUser}); $queue->Load(1); - $due->SetToNow; - $due->AddDays($queue->DefaultDueIn) if $queue->DefaultDueIn; + + my $due; + if ($queue->DefaultDueIn) { + $due = RT::Date->new($session{CurrentUser}); + $due->SetToNow; + $due->AddDays($queue->DefaultDueIn); + } + my $starts = RT::Date->new($session{CurrentUser}); $starts->SetToNow; return [ "# Required: id, Queue", [ qw(id Queue Requestor Subject Cc AdminCc Owner Status Priority - InitialPriority FinalPriority TimeEstimated Starts Due Text) ], + InitialPriority FinalPriority TimeEstimated Starts Due Attachment Text) ], { id => "ticket/new", Queue => $queue->Name, @@ -117,8 +128,9 @@ else { InitialPriority => $queue->InitialPriority, FinalPriority => $queue->FinalPriority, TimeEstimated => 0, - Starts => $starts->ISO, - Due => $due->ISO, + Starts => $starts->ISO(Timezone => 'user'), + Due => $due ? $due->ISO(Timezone => 'user') : undef, + Attachment => '', Text => "", }, 0 @@ -127,12 +139,12 @@ else { else { # We'll create a new ticket, and fall through to set fields that # can't be set in the call to Create(). - my (%v, $text); + my (%v, $text, @atts); foreach my $k (keys %data) { # flexibly parse any dates if ($dates{lc $k}) { - my $time = new RT::Date $session{CurrentUser}; + my $time = RT::Date->new($session{CurrentUser}); $time->Set(Format => 'unknown', Value => $data{$k}); $data{$k} = $time->ISO; } @@ -142,30 +154,66 @@ else { } # Set custom field elsif ($k =~ /^$cf_spec/) { - my $cf = RT::CustomField->new( $RT::SystemUser ); - my $cfk = $1 || $2; - unless($cf->LoadByName( Name => $cfk )) { - push @comments, "# Invalid custom field name ($cfk)"; + my $key = $1 || $2; + + my $cf = RT::CustomField->new( $session{CurrentUser} ); + $cf->LoadByName( + Name => $key, + LookupType => RT::Ticket->CustomFieldLookupType, + ObjectId => $data{Queue} || $v{Queue}, + IncludeGlobal => 1, + ); + + if (not $cf->id) { + push @comments, "# Invalid custom field name ($key)"; delete $data{$k}; next; } - $v{"CustomField-".$cf->Id()} = delete $data{$k}; + my $val = delete $data{$k}; + next unless defined $val && length $val; + $v{"CustomField-".$cf->Id()} = $cf->SingleValue ? $val : vsplit($val,1); } elsif (lc $k eq 'text') { $text = delete $data{$k}; } + elsif (lc $k eq 'attachment') { + push @atts, @{ vsplit(delete $data{$k}) }; + } + elsif ( $k !~ /^(?:id|requestors)$/i ) { + $e = 1; + push @$o, $k; + push(@comments, "# $k: Unknown field"); + } + } + + if ( $e ) { + unshift @comments, "# Could not create ticket."; + $k = \%data; + goto DONE; } # people fields allow multiple values $v{$_} = vsplit($v{$_}) foreach ( grep $create{lc $_}, @people ); - if ($text) { + if ($text || @atts) { $v{MIMEObj} = MIME::Entity->build( - From => $session{CurrentUser}->EmailAddress, - Subject => $v{Subject}, - Data => $text + Type => "multipart/mixed", + From => Encode::encode( "UTF-8", $session{CurrentUser}->EmailAddress ), + Subject => Encode::encode( "UTF-8", $v{Subject}), + 'X-RT-Interface' => 'REST', ); + $v{MIMEObj}->attach( + Type => $v{'Content-Type'} || 'text/plain', + Charset => "UTF-8", + Data => Encode::encode( "UTF-8", $text ), + ) if $text; + my ($status, $msg) = process_attachments($v{'MIMEObj'}, @atts); + unless ($status) { + push(@comments, "# $msg"); + goto DONE; + } + $v{MIMEObj}->make_singlepart; } my($tid,$trid,$terr) = $ticket->Create(%v); @@ -188,15 +236,15 @@ if (!keys(%data)) { my ($time, $key, $val, @data); push @data, [ id => "ticket/".$ticket->Id ]; - push @data, [ Queue => $ticket->QueueObj->Name ] - if (!%$fields || exists $fields->{lc 'Queue'}); + push @data, [ Queue => $ticket->QueueObj->Name ] + if (!%$fields || exists $fields->{lc 'Queue'}); push @data, [ Owner => $ticket->OwnerObj->Name ] - if (!%$fields || exists $fields->{lc 'Owner'}); + if (!%$fields || exists $fields->{lc 'Owner'}); push @data, [ Creator => $ticket->CreatorObj->Name ] - if (!%$fields || exists $fields->{lc 'Creator'}); + if (!%$fields || exists $fields->{lc 'Creator'}); foreach (qw(Subject Status Priority InitialPriority FinalPriority)) { - next unless (!%$fields || (exists $fields->{lc $_})); + next unless (!%$fields || (exists $fields->{lc $_})); push @data, [$_ => $ticket->$_ ]; } @@ -205,16 +253,16 @@ if (!keys(%data)) { push @data, [ $key => [ $ticket->$key->MemberEmailAddresses ] ]; } - $time = new RT::Date ($session{CurrentUser}); + $time = RT::Date->new ($session{CurrentUser}); foreach $key (@dates) { - next unless (!%$fields || (exists $fields->{lc $key})); + next unless (!%$fields || (exists $fields->{lc $key})); $time->Set(Format => 'sql', Value => $ticket->$key); push @data, [ $key => $time->AsString ]; } - $time = new RT::Date ($session{CurrentUser}); + $time = RT::Date->new ($session{CurrentUser}); foreach $key (qw(TimeEstimated TimeWorked TimeLeft)) { - next unless (!%$fields || (exists $fields->{lc $key})); + next unless (!%$fields || (exists $fields->{lc $key})); $val = $ticket->$key || 0; $val = "$val minutes" if $val; push @data, [ $key => $val ]; @@ -236,8 +284,8 @@ if (!keys(%data)) { else { while (my $v = $vals->Next()) { my $content = $v->Content; - $content =~ s/'/\\'/g; if ( $v->Content =~ /,/ ) { + $content =~ s/([\\'])/\\$1/g; push @out, q{'} . $content . q{'}; } else { @@ -254,6 +302,7 @@ if (!keys(%data)) { } else { my ($get, $set, $key, $val, $n, $s); + my $updated; foreach $key (keys %data) { $val = $data{$key}; @@ -279,8 +328,10 @@ else { elsif (exists $simple{$key}) { $key = $simple{$key}; $set = "Set$key"; + my $current = $ticket->$key; + $current = '' unless defined $current; - next if (($val eq $ticket->$key)|| ($ticket->$key =~ /^\d+$/ && $val == $ticket->$key)); + next if ($val eq $current) or ($current =~ /^\d+$/ && $val =~ /^\d+$/ && $val == $current); ($n, $s) = $ticket->$set("$val"); } elsif (exists $dates{$key}) { @@ -295,7 +346,7 @@ else { $set = "Set$key"; - my $time = new RT::Date $session{CurrentUser}; + my $time = RT::Date->new($session{CurrentUser}); $time->Set(Format => 'sql', Value => $ticket->$key); next if ($val =~ /^not set$/i || $val eq $time->AsString); @@ -318,13 +369,6 @@ else { } } foreach $p (keys %new) { - # XXX: This is a stupid test. - unless ($p =~ /^[\w.+-]+\@([\w.-]+\.)*\w+.?$/) { - $s = 0; - $n = "$p is not a valid email address."; - push @msgs, [ $s, $n ]; - next; - } unless ($ticket->IsWatcher(Type => $type, Email => $p)) { ($s, $n) = $ticket->AddWatcher(Type => $type, Email => $p); @@ -341,63 +385,39 @@ else { } # Set custom field elsif ($key =~ /^$cf_spec/) { - my $cf = RT::CustomField->new( $RT::SystemUser ); $key = $1 || $2; - if (not $cf->LoadByName( Name => $key )) { + + my $cf = RT::CustomField->new( $session{CurrentUser} ); + $cf->ContextObject( $ticket ); + $cf->LoadByName( + Name => $key, + LookupType => RT::Ticket->CustomFieldLookupType, + ObjectId => $ticket->Queue, + IncludeGlobal => 1, + ); + + if (not $cf->id) { $n = 0; $s = "Unknown custom field."; } else { my $vals = $ticket->CustomFieldValues($cf->id); - if ( $cf->SingleValue ) { - my $old = $vals->Next; - if ( $old ) { - if ( $val ne $old->Content ) { - $old->Delete; - ($n, $s) = $ticket->AddCustomFieldValue( - Field => $cf, Value => $val ); - $s =~ s/^# // if defined $s; - } - } - else { - ($n, $s) = $ticket->AddCustomFieldValue( - Field => $cf, Value => $val ); + if ( !defined $val || !length $val ) { + while ( my $val = $vals->Next ) { + ($n, $s) = $ticket->DeleteCustomFieldValue( + Field => $cf, ValueId => $val->id, + ); $s =~ s/^# // if defined $s; } } + elsif ( $cf->SingleValue ) { + ($n, $s) = $ticket->AddCustomFieldValue( + Field => $cf, Value => $val ); + $s =~ s/^# // if defined $s; + } else { - my @new; - my ( $a, $b ) = split /,/, $val, 2; - while ($a) { - no warnings 'uninitialized'; - if ( $a =~ /^'/ ) { - my $s = $a; - while ( $a !~ /'$/ || ( $a !~ /(\\\\)+'$/ - && $a =~ /(\\)+'$/ ) ) { - ( $a, $b ) = split /,/, $b, 2; - $s .= ',' . $a; - } - $s =~ s/^'//; - $s =~ s/'$//; - $s =~ s/\\'/'/g; - push @new, $s; - } - elsif ( $a =~ /^q{/ ) { - my $s = $a; - while ( $a !~ /}$/ ) { - ( $a, $b ) = split /,/, $b, 2; - $s .= ',' . $a; - } - $s =~ s/^q{//; - $s =~ s/}//; - push @new, $s; - } - else { - push @new, $a; - } - ( $a, $b ) = split /,/, $b, 2; - } + my @new = @{vsplit($val, 1)}; my %new; $new{$_}++ for @new; @@ -408,7 +428,7 @@ else { $new{$c}--; } else { - $v->Delete(); + $ticket->DeleteCustomFieldValue( Field => $cf, ValueId => $v->id ); } } for ( @new ) { @@ -421,7 +441,7 @@ else { } } } - elsif ($key ne 'id' && $key ne 'type' && $key ne 'creator') { + elsif ($key ne 'id' && $key ne 'type' && $key ne 'creator' && $key ne 'content-type' ) { $n = 0; $s = "Unknown field."; } @@ -436,8 +456,11 @@ else { $k = $changes; } } + else { + $updated ||= 1; + } } - push(@comments, "# Ticket ".$ticket->id." updated.") unless $n == 0; + push(@comments, "# Ticket ".$ticket->id." updated.") if $updated; } DONE: