[Rt-commit] rt branch, 4.4-trunk, updated. rt-4.4.1-201-gcb9c3d6
Shawn Moore
shawn at bestpractical.com
Tue Dec 27 13:32:46 EST 2016
The branch, 4.4-trunk has been updated
via cb9c3d6210d338353d6ae30a541564b739c727ec (commit)
via 2171a89ff9a083838e2eec6bc25dba655e5c39ec (commit)
via 398ec1b9a1b86ad5d66c209dec07825ab95648dd (commit)
via 988f7133a9a6de15956ae006648512b4f4be5dc1 (commit)
via a3e11d047dc6cfa5c5c9e5b9dd48f68e11a4b91a (commit)
via d9feec6fa4685efc9b229e3e5e7f314d41e45df9 (commit)
via f1c247a2b029d15cc9b6fc738d5a2b645b6aff86 (commit)
via a24f4358480d8665b985f9ccddbec2d1cb724388 (commit)
via a0f38800f21edbaed3e6a5e29a6a0ecaa6978c37 (commit)
via 43aa03582cddc23aee38a52a4aeacf042766176e (commit)
via c9774928c6da3757b266e305a2794f0b4122ac47 (commit)
via 99c08c1141c9a38cb727073d70d95d92243df1ef (commit)
via 18cc75db4638cb9b7e6117217f5ee9d4a945fdf9 (commit)
via cbd5ed469f41db880ad041c56e547f5a8fb4a95d (commit)
via 05ddb1844560bc8153e9ccf52e7956c506fc33c7 (commit)
via d6cdacb638315ae2772ba97d0c5894e9daa22e6d (commit)
via fd91b5b5c37af455414b96b05241a6183ff79d48 (commit)
via b00a27fdb942e033bc6eaa83cac228298da425c0 (commit)
via 3da2bf2868ff72f5e13b19eba4f02eb8f5a85f70 (commit)
via fb4bdf2d6fe2742fe1c510af7446e1dd6b888e92 (commit)
via 40d289bbc0b41ceadecc50e4b2a50d5c7be96432 (commit)
via bdd6bd96ece4faebb5a067bdd787b8e2e4fec755 (commit)
via 8cd8411090e783a460d84a4725e7f33a81145d2f (commit)
via 9b4705611e637604a3c00b7c3f036196928c581f (commit)
via 69474c481897f655239467077976fbdc11b6879d (commit)
via b34993b69bbb8480f2759950a926995b0fae7aed (commit)
via 1e3010c6bffdbf4923edf0cdc439fba39655acc0 (commit)
via f815e22ff4861eadeb77a0eca9faccb761ee465f (commit)
via 14c420dc448fadbf97d925928f70ab3f006edca3 (commit)
via 434613b4a64a43edce7fd825720b063633f769c1 (commit)
via 542ffc5412bf8293c67420a7801a66e7868d77d9 (commit)
via 51f6226fa546f6e67f190977bd7d6981763f62c7 (commit)
via 4ed0f4e647d4d1243c7aa3d1da649ae57d36b98c (commit)
via 7bdd183b11be1b24d137115454d6de55818de42e (commit)
via a3988c716512dbc11da5dc48cb5affcfc8b10ca6 (commit)
via e56326444ffaa560926610c52c8391cbc21196ea (commit)
via d82a3f9b49d9349ce569a1f5da5f385d2ba3f536 (commit)
via f94b7adcf95cb89cdec16351530b42e35290bbde (commit)
via 9f5b8613d97b73bf5e0b3a0980cac3addd36b4a7 (commit)
via 2472f6f8627c7c708c4afdff324eb2f1aa580f64 (commit)
via b4f82e954efd0057863fbaba6bef0322579ad2bb (commit)
via b41a13e8555e98283e5e5ad6721931c819ca09d1 (commit)
via 877b88b07f34e39ac0d0c82a938a31faff4edc7a (commit)
via deb8019a0d83b37499c9094a860538dcfadc3685 (commit)
via 84ec669470f5b550fc5bfc8175393e644e7c2870 (commit)
via 05db56f2b375b6219859a627731f344f34c95489 (commit)
from a670d25b4b565601020102e27cd63728c3e763f4 (commit)
Summary of changes:
etc/RT_Config.pm.in | 26 ++++++++++++
lib/RT.pm | 1 +
lib/RT/Crypt/SMIME.pm | 8 ++++
lib/RT/I18N.pm | 9 ++--
lib/RT/Interface/Email.pm | 60 ++++++++++++++++++---------
lib/RT/Plugin.pm | 11 +++++
share/html/Admin/Scrips/index.html | 30 ++++++++++++--
share/html/Admin/Tools/Configuration.html | 17 ++++++++
share/html/Admin/Users/Modify.html | 5 +++
share/html/Articles/Elements/BeforeMessageBox | 2 +-
share/html/Elements/ColumnMap | 2 +-
share/html/Elements/Tabs | 7 ++--
share/html/Search/Chart | 10 ++++-
share/html/Ticket/Elements/UpdateCc | 4 ++
share/static/css/base/ticket-form.css | 4 ++
t/lifecycles/basics.t | 2 +-
t/lifecycles/dates.t | 2 +-
t/lifecycles/moving.t | 2 +-
t/lifecycles/types.t | 2 +-
t/lifecycles/unresolved-deps.t | 2 +-
t/mail/mime_decoding.t | 10 +++++
t/mail/outgoing-mail-from.t | 56 +++++++++++++++++++++++++
t/mail/precedence-outgoing.t | 59 ++++++++++++++++++++++++++
t/web/cf_groupings.t | 2 +-
t/web/installer.t | 5 ++-
25 files changed, 295 insertions(+), 43 deletions(-)
create mode 100644 t/mail/outgoing-mail-from.t
create mode 100644 t/mail/precedence-outgoing.t
- Log -----------------------------------------------------------------
commit cb9c3d6210d338353d6ae30a541564b739c727ec
Merge: a670d25 2171a89
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Tue Dec 27 13:32:35 2016 -0500
Merge branch '4.2-trunk' into 4.4-trunk
diff --cc etc/RT_Config.pm.in
index c34c04e,fd5a866..9366a23
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@@ -1763,125 -1687,18 +1780,134 @@@ you will have no access to Articles
Set($HideArticleSearchOnReplyCreate, 0);
+ =item C<$LinkArticlesOnInclude>
+
+ Set this to 0 to suppress the default behavior of automatically linking
+ to Articles when they are included in a message.
+
+ =cut
+
+ Set($LinkArticlesOnInclude, 1);
+
=back
+=head1 Assets
+
+=over 4
+
+=item C<@AssetQueues>
+
+This should be a list of names of queues whose tickets should always
+display the "Assets" box. This is useful for queues which deal
+primarily with assets, as it provides a ready box to link an asset to
+the ticket, even when the ticket has no related assets yet.
+
+=cut
+
+# Set(@AssetQueues, ());
+
+=item C<$DefaultCatalog>
+
+This provides the default catalog after a user initially logs in.
+However, the default catalog is "sticky," and so will remember the
+last-selected catalog thereafter.
+
+=cut
+
+# Set($DefaultCatalog, 'General assets');
+
+=item C<$AssetSearchFields>
+
+Specifies which fields of L<RT::Asset> to match against and how to match
+each field when performing a quick search on assets. Valid match
+methods are LIKE, STARTSWITH, ENDSWITH, =, and !=. Valid search fields
+are id, Name, Description, or custom fields, which are specified as
+"CF.1234" or "CF.Name"
+
+=cut
+
+Set($AssetSearchFields, {
+ id => '=',
+ Name => 'LIKE',
+ Description => 'LIKE',
+});
+
+=item C<$AssetSearchFormat>
+
+The format that results of the asset search are displayed with. This is
+either a string, which will be used for all catalogs, or a hash
+reference, keyed by catalog's name/id. If a hashref and neither name or
+id is found therein, falls back to the key ''.
+
+If you wish to use the multiple catalog format, your configuration would look
+something like:
+
+ Set($AssetSearchFormat, {
+ 'General assets' => q[Format String for the General Assets Catalog],
+ 8 => q[Format String for Catalog 8],
+ '' => q[Format String for any catalogs not listed explicitly],
+ });
+
+=cut
+
+# loc('Related tickets')
+Set($AssetSearchFormat, q[
+ '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+ Description,
+ '__Status__ (__Catalog__)/TITLE:Status',
+ Owner,
+ HeldBy,
+ Contacts,
+ '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
+]);
+
+=item C<$AssetSummaryFormat>
+
+The information that is displayed on ticket display pages about assets
+related to the ticket. This is displayed in a table beneath the asset
+name.
+
+=cut
+
+Set($AssetSummaryFormat, q[
+ '<a href="__WebHomePath__/Asset/Display.html?id=__id__">__Name__</a>/TITLE:Name',
+ Description,
+ '__Status__ (__Catalog__)/TITLE:Status',
+ Owner,
+ HeldBy,
+ Contacts,
+ '__ActiveTickets__ __InactiveTickets__/TITLE:Related tickets',
+]);
+
+=item C<$AssetSummaryRelatedTicketsFormat>
+
+The information that is displayed on ticket display pages about tickets
+related to assets related to the ticket. This is displayed as a list of
+tickets underneath the asset properties.
+
+=cut
+Set($AssetSummaryRelatedTicketsFormat, q[
+ '<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>',
+ '(__OwnerName__)',
+ '<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>',
+ QueueName,
+ Status,
+]);
+
+=item C<$AssetBasicCustomFieldsOnCreate>
+
+Specify a list of Asset custom fields to show in "Basics" widget on create.
+
+e.g.
+
+Set( $AssetBasicCustomFieldsOnCreate, [ 'foo', 'bar' ] );
+
+=cut
+
+# Set($AssetBasicCustomFieldsOnCreate, undef );
+
+=back
=head2 Message box properties
diff --cc lib/RT/Interface/Email.pm
index 23543fc,1d5f3bb..281c5c2
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@@ -462,322 -323,61 +462,348 @@@ C<Return-path>, C<Errors-To>, C<Reply-T
=cut
-sub WillSignEncrypt {
- my %args = @_;
- my $attachment = delete $args{Attachment};
- my $ticket = delete $args{Ticket};
-
- if ( not RT->Config->Get('Crypt')->{'Enable'} ) {
- $args{Sign} = $args{Encrypt} = 0;
- return wantarray ? %args : 0;
- }
+sub ParseErrorsToAddressFromHead {
+ my $head = shift;
- for my $argument ( qw(Sign Encrypt) ) {
- next if defined $args{ $argument };
+ foreach my $header ( 'Errors-To', 'Reply-To', 'From', 'Sender' ) {
+ my $value = Encode::decode( "UTF-8", $head->get($header) );
+ next unless $value;
- if ( $attachment and defined $attachment->GetHeader("X-RT-$argument") ) {
- $args{$argument} = $attachment->GetHeader("X-RT-$argument");
- } elsif ( $ticket and $argument eq "Encrypt" ) {
- $args{Encrypt} = $ticket->QueueObj->Encrypt();
- } elsif ( $ticket and $argument eq "Sign" ) {
- # Note that $queue->Sign is UI-only, and that all
- # UI-generated messages explicitly set the X-RT-Crypt header
- # to 0 or 1; thus this path is only taken for messages
- # generated _not_ via the web UI.
- $args{Sign} = $ticket->QueueObj->SignAuto();
- }
+ my ( $email ) = RT::EmailParser->ParseEmailAddress($value);
+ return $email->address if $email;
}
-
- return wantarray ? %args : ($args{Sign} || $args{Encrypt});
}
-sub _OutgoingMailFrom {
- my $TicketObj = shift;
+=head3 IsMachineGeneratedMail Message => C<message>
- my $MailFrom = RT->Config->Get('SetOutgoingMailFrom');
- my $OutgoingMailAddress = $MailFrom =~ /\@/ ? $MailFrom : undef;
- my $Overrides = RT->Config->Get('OverrideOutgoingMailFrom') || {};
+Checks if the mail is machine-generated (via a bounce, mail headers,
- if ($TicketObj) {
- my $Queue = $TicketObj->QueueObj;
- my $QueueAddressOverride = $Overrides->{$Queue->id}
- || $Overrides->{$Queue->Name};
+=cut
+
+sub IsMachineGeneratedMail {
+ my %args = (
+ Message => undef,
+ Subject => undef,
+ @_
+ );
+ my $head = $args{'Message'}->head;
+
+ my $IsAutoGenerated = CheckForAutoGenerated($head);
+ my $IsALoop = CheckForLoops($head);
+
+ my $owner_mail = RT->Config->Get('OwnerEmail');
+
+ # Don't let the user stuff the RT-Squelch-Replies-To header.
+ $head->delete('RT-Squelch-Replies-To');
+
+ # If the message is autogenerated, we need to know, so we can not
+ # send mail to the sender
+ return unless $IsAutoGenerated || $IsALoop;
+
+ # Warn someone if it's a loop, before we drop it on the ground
+ if ($IsALoop) {
+ my $MessageId = Encode::decode( "UTF-8", $head->get('Message-ID') );
+ $RT::Logger->crit("RT Received mail ($MessageId) from itself.");
+
+ #Should we mail it to RTOwner?
+ if ( RT->Config->Get('LoopsToRTOwner') ) {
+ MailError(
+ To => $owner_mail,
+ Subject => "RT Bounce: ".$args{'Subject'},
+ Explanation => "RT thinks this message may be a bounce",
+ );
+ }
+
+ #Do we actually want to store it?
+ FAILURE( "Message is a bounce" ) unless RT->Config->Get('StoreLoops');
+ }
+
+ # Squelch replies to the sender, and also leave a clue to
+ # allow us to squelch ALL outbound messages. This way we
+ # can punt the logic of "what to do when we get a bounce"
+ # to the scrip. We might want to notify nobody. Or just
+ # the RT Owner. Or maybe all Privileged watchers.
+ my ( $Sender ) = ParseSenderAddressFromHead($head);
+ $head->replace( 'RT-Squelch-Replies-To', Encode::encode("UTF-8", $Sender ) );
+ $head->replace( 'RT-DetectedAutoGenerated', 'true' );
+
+ return 1;
+}
+
+=head3 CheckForLoops HEAD
+
+Takes a L<MIME::Head> object and returns true if the message was sent by
+this RT instance, by checking the C<X-RT-Loop-Prevention> header.
+
+=cut
+
+sub CheckForLoops {
+ my $head = shift;
+
+ # If this instance of RT sent it our, we don't want to take it in
+ my $RTLoop = Encode::decode( "UTF-8", $head->get("X-RT-Loop-Prevention") || "" );
+ chomp ($RTLoop); # remove that newline
+ if ( $RTLoop eq RT->Config->Get('rtname') ) {
+ return 1;
+ }
+
+ # TODO: We might not trap the case where RT instance A sends a mail
+ # to RT instance B which sends a mail to ...
+ return undef;
+}
+
+=head3 CheckForAutoGenerated HEAD
+
+Takes a HEAD object of L<MIME::Head> class and returns true if message is
+autogenerated. Checks C<Precedence>, RFC3834 C<Auto-Submitted>, and
+C<X-FC-Machinegenerated> fields of the head in tests.
+
+=cut
+
+sub CheckForAutoGenerated {
+ my $head = shift;
+
+ # Bounces, via return-path
+ my $ReturnPath = $head->get("Return-path") || "";
+ return 1 if $ReturnPath =~ /<>/;
+
+ # Bounces, via mailer-daemon or postmaster
+ my ( $From ) = ParseSenderAddressFromHead($head);
+ return 1 if defined $From and $From =~ /^mailer-daemon\@/i;
+ return 1 if defined $From and $From =~ /^postmaster\@/i;
+ return 1 if defined $From and $From eq "";
+
+ # Bulk or junk messages are auto-generated
+ return 1 if grep {/^(bulk|junk)/i} $head->get_all("Precedence");
+
+ # Per RFC3834, any Auto-Submitted header which is not "no" means
+ # it is auto-generated.
+ my $AutoSubmitted = $head->get("Auto-Submitted") || "";
+ return 1 if length $AutoSubmitted and $AutoSubmitted ne "no";
+
+ # First Class mailer uses this as a clue.
+ my $FCJunk = $head->get("X-FC-Machinegenerated") || "";
+ return 1 if $FCJunk =~ /^true/i;
+
+ return 0;
+}
+
+=head3 ExtractTicketId
+
+Passed a L<MIME::Entity> object, and returns a either ticket id or undef
+to signal 'new ticket'.
+
+This is a great entry point if you need to customize how ticket ids are
+handled for your site. L<RT::Extension::RepliesToResolved> demonstrates
+one possible use for this extension.
+
+If the Subject of the L<MIME::Entity> is modified, the updated subject
+will be used during ticket creation.
+
+=cut
+
+sub ExtractTicketId {
+ my $entity = shift;
+
+ my $subject = Encode::decode( "UTF-8", $entity->head->get('Subject') || '' );
+ chomp $subject;
+ return ParseTicketId( $subject );
+}
+
+=head3 ParseTicketId
+
+Takes a string and searches for [subjecttag #id]
+
+Returns the id if a match is found. Otherwise returns undef.
+
+=cut
+
+sub ParseTicketId {
+ my $Subject = shift;
+
+ my $rtname = RT->Config->Get('rtname');
+ my $test_name = RT->Config->Get('EmailSubjectTagRegex') || qr/\Q$rtname\E/i;
+
+ # We use @captures and pull out the last capture value to guard against
+ # someone using (...) instead of (?:...) in $EmailSubjectTagRegex.
+ my $id;
+ if ( my @captures = $Subject =~ /\[$test_name\s+\#(\d+)\s*\]/i ) {
+ $id = $captures[-1];
+ } else {
+ foreach my $tag ( RT->System->SubjectTag ) {
+ next unless my @captures = $Subject =~ /\[\Q$tag\E\s+\#(\d+)\s*\]/i;
+ $id = $captures[-1];
+ last;
+ }
+ }
+ return undef unless $id;
+
+ $RT::Logger->debug("Found a ticket ID. It's $id");
+ return $id;
+}
+
+=head3 MailError PARAM HASH
+
+Sends an error message. Takes a param hash:
+
+=over 4
+
+=item From
+
+Sender's address, defaults to L<RT_Config/$CorrespondAddress>;
+
+=item To
+
+Recipient, defaults to L<RT_Config/$OwnerEmail>;
+
+=item Subject
+
+Subject of the message, defaults to C<There has been an error>;
+
+=item Explanation
+
+Main content of the error, default value is C<Unexplained error>;
+
+=item MIMEObj
+
+Optional L<MIME::Entity> that is attached to the error mail.
+Additionally, the C<In-Reply-To> header will point to this message.
+
+=item Attach
+
+Optional text that attached to the error as a C<message/rfc822> part.
+
+=item LogLevel
+
+Log level the subject and explanation is written to the log; defaults to
+C<critical>.
+
+=back
+
+=cut
+
+sub MailError {
+ my %args = (
+ To => RT->Config->Get('OwnerEmail'),
+ From => RT->Config->Get('CorrespondAddress'),
+ Subject => 'There has been an error',
+ Explanation => 'Unexplained error',
+ MIMEObj => undef,
+ Attach => undef,
+ LogLevel => 'crit',
+ FAILURE => 0,
+ @_
+ );
+
+ $RT::Logger->log(
+ level => $args{'LogLevel'},
+ message => "$args{Subject}: $args{'Explanation'}",
+ ) if $args{'LogLevel'};
+
+ # the colons are necessary to make ->build include non-standard headers
+ my %entity_args = (
+ Type => "multipart/mixed",
+ From => Encode::encode( "UTF-8", $args{'From'} ),
+ To => Encode::encode( "UTF-8", $args{'To'} ),
+ Subject => EncodeToMIME( String => $args{'Subject'} ),
+ 'X-RT-Loop-Prevention:' => Encode::encode( "UTF-8", RT->Config->Get('rtname') ),
+ );
+
+ # only set precedence if the sysadmin wants us to
+ if (defined(RT->Config->Get('DefaultErrorMailPrecedence'))) {
+ $entity_args{'Precedence:'} =
+ Encode::encode( "UTF-8", RT->Config->Get('DefaultErrorMailPrecedence') );
+ }
+
+ my $entity = MIME::Entity->build(%entity_args);
+ SetInReplyTo( Message => $entity, InReplyTo => $args{'MIMEObj'} );
+
+ $entity->attach(
+ Type => "text/plain",
+ Charset => "UTF-8",
+ Data => Encode::encode( "UTF-8", $args{'Explanation'} . "\n" ),
+ );
+
+ if ( $args{'MIMEObj'} ) {
+ $args{'MIMEObj'}->sync_headers;
+ $entity->add_part( $args{'MIMEObj'} );
+ }
+
+ if ( $args{'Attach'} ) {
+ $entity->attach( Data => Encode::encode( "UTF-8", $args{'Attach'} ), Type => 'message/rfc822' );
+
+ }
+
+ SendEmail( Entity => $entity, Bounce => 1 );
+
+ FAILURE( "$args{Subject}: $args{Explanation}" ) if $args{FAILURE};
+}
+
++sub _OutgoingMailFrom {
++ my $TicketObj = shift;
++
++ my $MailFrom = RT->Config->Get('SetOutgoingMailFrom');
++ my $OutgoingMailAddress = $MailFrom =~ /\@/ ? $MailFrom : undef;
++ my $Overrides = RT->Config->Get('OverrideOutgoingMailFrom') || {};
++
++ if ($TicketObj) {
++ my $Queue = $TicketObj->QueueObj;
++ my $QueueAddressOverride = $Overrides->{$Queue->id}
++ || $Overrides->{$Queue->Name};
+
+ if ($QueueAddressOverride) {
+ $OutgoingMailAddress = $QueueAddressOverride;
+ } else {
+ $OutgoingMailAddress ||= $Queue->CorrespondAddress
+ || RT->Config->Get('CorrespondAddress');
+ }
+ }
+ elsif ($Overrides->{'Default'}) {
+ $OutgoingMailAddress = $Overrides->{'Default'};
+ }
+
+ return $OutgoingMailAddress;
+ }
+
+=head2 SENDING EMAIL
+
+=head3 SendEmail Entity => undef, [ Bounce => 0, Ticket => undef, Transaction => undef ]
+
+Sends an email (passed as a L<MIME::Entity> object C<ENTITY>) using
+RT's outgoing mail configuration. If C<BOUNCE> is passed, and is a
+true value, the message will be marked as an autogenerated error, if
+possible. Sets Date field of the head to now if it's not set.
+
+If the C<X-RT-Squelch> header is set to any true value, the mail will
+not be sent. One use is to let extensions easily cancel outgoing mail.
+
+Ticket and Transaction arguments are optional. If Transaction is
+specified and Ticket is not then ticket of the transaction is
+used, but only if the transaction belongs to a ticket.
+
+Returns 1 on success, 0 on error or -1 if message has no recipients
+and hasn't been sent.
+
+=head3 Signing and Encrypting
+
+This function as well signs and/or encrypts the message according to
+headers of a transaction's attachment or properties of a ticket's queue.
+To get full access to the configuration Ticket and/or Transaction
+arguments must be provided, but you can force behaviour using Sign
+and/or Encrypt arguments.
+
+The following precedence of arguments are used to figure out if
+the message should be encrypted and/or signed:
+
+* if Sign or Encrypt argument is defined then its value is used
+
+* else if Transaction's first attachment has X-RT-Sign or X-RT-Encrypt
+header field then it's value is used
+
+* else properties of a queue of the Ticket are used.
+
+=cut
+
sub SendEmail {
my (%args) = (
Entity => undef,
diff --cc share/html/Admin/Users/Modify.html
index 0b30780,984a29b..63144db
--- a/share/html/Admin/Users/Modify.html
+++ b/share/html/Admin/Users/Modify.html
@@@ -242,8 -246,10 +246,9 @@@ $ARGS{Disabled} = $ARGS{Enabled} ? 0 :
delete $ARGS{Disabled} unless $ARGS{SetEnabled};
my @fields = qw(Name Comments Signature EmailAddress FreeformContactInfo
- Organization RealName NickName Lang EmailEncoding WebEncoding
- ExternalContactInfoId ContactInfoSystem Gecos ExternalAuthId
- AuthSystem HomePhone WorkPhone MobilePhone PagerPhone Address1
- Address2 City State Zip Country Timezone
+ Organization RealName NickName Lang Gecos HomePhone WorkPhone
+ MobilePhone PagerPhone Address1 Address2 City State Zip Country
++ Timezone
);
if ($Create) {
diff --cc share/html/Elements/Tabs
index 083d89d,0a00512..8579f67
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@@ -1124,7 -937,7 +1125,7 @@@ my $build_main_nav = sub
PageMenu()->child( edit => title => loc('Edit'), path => '/Prefs/MyRT.html' );
}
- $m->callback( CallbackName => 'Privileged', Path => $request_path, ARGSRef => \%ARGS );
- $m->callback( CallbackName => 'Privileged', Path => $request_path, Search_Args => $args, Has_Query => $has_query );
++ $m->callback( CallbackName => 'Privileged', Path => $request_path, Search_Args => $args, Has_Query => $has_query, ARGSRef => \%ARGS );
};
my $build_selfservice_nav = sub {
diff --cc share/html/Ticket/Elements/UpdateCc
index 641fa33,bb65553..4b65367
--- a/share/html/Ticket/Elements/UpdateCc
+++ b/share/html/Ticket/Elements/UpdateCc
@@@ -70,10 -65,8 +71,11 @@@
onClick="checkboxToInput('UpdateCc', <% "UpdateCc-$addr" |n,j%>, <%$clean_addr|n,j%> );"
<% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> >
<label for="UpdateCc-<%$addr%>"><& /Elements/ShowUser, Address => $txn_addresses{$addr}&></label>
+ </span>
%}
+%if (@one_time_Ccs && $hide_cc_suggestions) {
+</div>
+%}
</td></tr>
<tr><td class="label"><&|/l&>One-time Bcc</&>:</td><td><& /Elements/EmailInput, Name => 'UpdateBcc', Size => undef, Default => $ARGS{UpdateBcc}, AutocompleteMultiple => 1 &><br />
%if (scalar @one_time_Ccs) {
@@@ -95,22 -83,8 +98,23 @@@
onClick="checkboxToInput('UpdateBcc', <% "UpdateBcc-$addr" |n,j%>, <%$clean_addr|n,j%> );"
<% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%> >
<label for="UpdateBcc-<%$addr%>"><& /Elements/ShowUser, Address => $txn_addresses{$addr}&></label>
+ </span>
%}
+%if (@one_time_Ccs && $hide_cc_suggestions) {
+</div>
+<script type="text/javascript">
+jQuery(function() {
+ jQuery('a.ToggleSuggestions').click(function(e) {
+ e.preventDefault();
+ var toggleSuggestions = jQuery(this);
+ var oneTimeCcs = toggleSuggestions.closest('td').find('.OneTimeCcs');
+ oneTimeCcs.toggleClass('hidden');
+ var hideOrShow = oneTimeCcs.hasClass('hidden') ? toggleSuggestions.data('showLabel') : toggleSuggestions.data('hideLabel');
+ toggleSuggestions.find('i').html('(' + hideOrShow + ')');
+ });
+});
+</script>
+%}
</td></tr>
<%args>
$TicketObj
-----------------------------------------------------------------------
More information about the rt-commit
mailing list