From e70abd21bab68b23488f7ef1ee2e693a3b365691 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 18 May 2010 18:49:59 +0000 Subject: import rt 3.8.8 --- rt/share/html/Admin/CustomFields/Objects.html | 152 ++++++++------- rt/share/html/Admin/CustomFields/index.html | 58 +++--- rt/share/html/Admin/Elements/EditCustomFields | 213 +++++++++------------ rt/share/html/Admin/Elements/EditScrip | 1 + rt/share/html/Admin/Elements/EditScrips | 5 +- rt/share/html/Admin/Elements/EditTemplates | 5 +- rt/share/html/Admin/Groups/index.html | 5 +- rt/share/html/Admin/Queues/Modify.html | 7 + rt/share/html/Admin/Queues/index.html | 6 +- rt/share/html/Admin/Tools/Configuration.html | 180 +++++++++++------ rt/share/html/Admin/Users/Memberships.html | 4 +- rt/share/html/Admin/Users/Modify.html | 52 ++--- rt/share/html/Admin/Users/index.html | 6 +- rt/share/html/Dashboards/Elements/HiddenSearches | 3 + rt/share/html/Dashboards/Render.html | 7 +- rt/share/html/Download/CustomFieldValue/dhandler | 5 +- rt/share/html/Elements/CollectionAsTable/Row | 3 +- rt/share/html/Elements/CollectionList | 26 ++- rt/share/html/Elements/ColumnMap | 24 +++ rt/share/html/Elements/CreateTicket | 7 +- rt/share/html/Elements/EditCustomFieldSelect | 3 +- rt/share/html/Elements/EditLinks | 24 +-- rt/share/html/Elements/EditPassword | 34 ++++ rt/share/html/Elements/HeaderJavascript | 2 +- rt/share/html/Elements/Login | 15 ++ rt/share/html/Elements/Logo | 7 +- rt/share/html/Elements/MessageBox | 2 +- rt/share/html/Elements/MyReminders | 1 + rt/share/html/Elements/RT__CustomField/ColumnMap | 178 +++++++++++++++++ rt/share/html/Elements/RT__Queue/ColumnMap | 54 +++--- rt/share/html/Elements/RT__Scrip/ColumnMap | 4 + rt/share/html/Elements/RT__Template/ColumnMap | 11 ++ rt/share/html/Elements/RT__Ticket/ColumnMap | 22 --- rt/share/html/Elements/SelectQueue | 3 +- rt/share/html/Elements/ShowCustomFields | 11 +- rt/share/html/Elements/ShowLinks | 22 +-- rt/share/html/Elements/ShowRelationLabel | 62 ++++++ rt/share/html/Elements/ShowUser | 24 +-- rt/share/html/Elements/ShowUserConcise | 16 +- rt/share/html/Helpers/CalPopup.html | 12 +- rt/share/html/NoAuth/Logout.html | 12 +- rt/share/html/NoAuth/css/3.4-compat/misc.css | 3 + rt/share/html/NoAuth/css/3.4-compat/titlebox.css | 4 - rt/share/html/NoAuth/css/3.5-default/misc.css | 31 +-- rt/share/html/NoAuth/css/3.5-default/titlebox.css | 4 - rt/share/html/NoAuth/css/autohandler | 3 +- rt/share/html/NoAuth/css/base/misc.css | 49 +++++ rt/share/html/NoAuth/css/print.css | 11 +- rt/share/html/NoAuth/css/web2/base.css | 7 - rt/share/html/NoAuth/css/web2/boxes.css | 8 +- rt/share/html/NoAuth/css/web2/collection.css | 52 +++++ rt/share/html/NoAuth/css/web2/main.css | 1 + rt/share/html/NoAuth/css/web2/misc.css | 27 +-- rt/share/html/NoAuth/css/web2/msie.css | 7 + rt/share/html/NoAuth/css/web2/portlets.css | 6 + rt/share/html/NoAuth/images/autohandler | 3 +- rt/share/html/NoAuth/js/autohandler | 3 +- rt/share/html/NoAuth/rss/dhandler | 48 +++++ rt/share/html/Search/Bulk.html | 4 +- rt/share/html/Search/Chart | 136 +++++++------ rt/share/html/Search/Elements/Chart | 34 ++-- rt/share/html/Search/Elements/ResultsRSSView | 143 ++++++++++++++ rt/share/html/Search/Results.html | 11 +- rt/share/html/Search/Results.rdf | 57 +----- rt/share/html/Search/Results.tsv | 2 +- rt/share/html/SelfService/Error.html | 2 +- rt/share/html/SelfService/Prefs.html | 34 ++-- rt/share/html/Ticket/Attachment/dhandler | 7 +- rt/share/html/Ticket/Create.html | 18 ++ rt/share/html/Ticket/Elements/EditCustomFields | 2 + rt/share/html/Ticket/Elements/EditDates | 1 + .../Ticket/Elements/EditTransactionCustomFields | 2 + rt/share/html/Ticket/Elements/PreviewScrips | 6 +- rt/share/html/Ticket/Elements/ShowAttachments | 17 +- rt/share/html/Ticket/Elements/ShowDates | 1 + rt/share/html/Ticket/Elements/ShowGroupMembers | 4 +- rt/share/html/Ticket/Elements/ShowMessageStanza | 3 +- rt/share/html/Ticket/Elements/ShowPeople | 4 +- rt/share/html/Ticket/Elements/ShowSummary | 111 ++++++----- rt/share/html/Ticket/Elements/ShowTransaction | 2 + .../Ticket/Elements/ShowTransactionAttachments | 7 +- rt/share/html/Ticket/Elements/Tabs | 24 ++- rt/share/html/Ticket/Elements/UpdateCc | 26 ++- rt/share/html/Ticket/ModifyAll.html | 10 +- rt/share/html/Ticket/ModifyDates.html | 1 + rt/share/html/Ticket/Update.html | 28 ++- rt/share/html/Tools/Reports/CreatedByDates.html | 8 +- rt/share/html/Tools/Reports/ResolvedByDates.html | 8 +- rt/share/html/User/Elements/Tabs | 66 +++---- rt/share/html/User/Prefs.html | 43 ++--- rt/share/html/Widgets/Form/Select | 5 +- 91 files changed, 1556 insertions(+), 826 deletions(-) create mode 100644 rt/share/html/Elements/EditPassword create mode 100644 rt/share/html/Elements/RT__CustomField/ColumnMap create mode 100644 rt/share/html/Elements/ShowRelationLabel create mode 100644 rt/share/html/NoAuth/css/base/misc.css create mode 100644 rt/share/html/NoAuth/css/web2/collection.css create mode 100644 rt/share/html/NoAuth/rss/dhandler create mode 100644 rt/share/html/Search/Elements/ResultsRSSView (limited to 'rt/share/html') diff --git a/rt/share/html/Admin/CustomFields/Objects.html b/rt/share/html/Admin/CustomFields/Objects.html index 20d79b294..06e3739b2 100644 --- a/rt/share/html/Admin/CustomFields/Objects.html +++ b/rt/share/html/Admin/CustomFields/Objects.html @@ -56,94 +56,104 @@
- + +% if ( $is_global ) { +

<&|/l&>Applies to all objects

+ +<&|/l&>check this box to remove this Custom Field from all objects and be able to choose specific objects. +% } else { +

<&|/l&>Apply globally

+ + +<&|/l&>check this box to apply this Custom Field to all objects.

<&|/l&>Selected objects

-<& /Admin/Elements/PickObjects, Objects => \@AssignedObjs, id => $id, Checked => 1 &> -

<&|/l&>Unselected objects

-<& /Admin/Elements/PickObjects, Objects => \@UnassignedObjs, id => $id &> +<& /Elements/CollectionList, + OrderBy => 'id', + Order => 'ASC', + %ARGS, + Collection => $applied, + Rows => 0, + Page => 1, + Format => $format, + DisplayFormat => "'__CheckBox.{RemoveCustomField-". $CF->id ."}__',". $format, + AllowSorting => 0, + ShowEmpty => 0, + PassArguments => [ + qw(id Format Rows Page Order OrderBy), + ], +&> -<& /Elements/Submit, CheckAll => 1, ClearAll => 1 &> +

<&|/l&>Unselected objects

+<& /Elements/CollectionList, + OrderBy => 'id', + Order => 'ASC', + %ARGS, + Collection => $not_applied, + Rows => 50, + Format => $format, + DisplayFormat => "'__CheckBox.{AddCustomField-". $CF->id ."}__',". $format, + AllowSorting => 1, + ShowEmpty => 0, + PassArguments => [ + qw(id Format Rows Page Order OrderBy), + ], +&> + +% } + +<& /Elements/Submit, Name => 'UpdateObjs' &>
<%INIT> my $CF = RT::CustomField->new($session{'CurrentUser'}); $CF->Load($id) or Abort(loc("Could not load CustomField [_1]"), $id); -my $LookupType = $CF->LookupType || ''; -$LookupType =~ /^([^-]+)/ || - Abort(loc("Object of type [_1] cannot take custom fields", $LookupType)); - -my $Class = $1; -my $CollectionClass; -if (UNIVERSAL::can($Class.'Collection', 'new') ) { -$CollectionClass = $Class.'Collection'; - -} elsif (UNIVERSAL::can($Class.'es', 'new') ) { - $CollectionClass = $Class.'es'; -} elsif (UNIVERSAL::can($Class.'s', 'new') ) { - $CollectionClass = $Class.'s'; - -} else { - Abort(loc("Can't find a collection class for '[_1]'", $Class)); -} - - -my $title = loc('Modify associated objects for [_1]', $CF->Name); +my $class = $CF->RecordClassFromLookupType; +Abort(loc("Something wrong. Contact system administrator")) + unless $class; -my $Objects = $CollectionClass->new($session{'CurrentUser'}); +my (@results); -# If CF is a Group CF, only display user-defined groups -if ($Class eq 'RT::Group') { - $Objects->LimitToUserDefinedGroups; +if ( $UpdateObjs ) { + if ( defined (my $del = $ARGS{'RemoveCustomField-'.$CF->id}) ) { + foreach my $id ( ref $del? (@$del) : ($del) ) { + my $object = $class->new( $session{'CurrentUser'} ); + if ( $id ) { + $object->Load( $id ); + next unless $object->id; + } + + my ($status, $msg) = $CF->RemoveFromObject( $object ); + push @results, $msg; + } + } + if ( defined (my $add = $ARGS{'AddCustomField-'.$CF->id}) ) { + foreach my $id ( ref $add? (@$add) : ($add) ) { + my $object = $class->new( $session{'CurrentUser'} ); + if ( $id ) { + $object->Load( $id ); + next unless $object->id; + } + + my ($status, $msg) = $CF->AddToObject( $object ); + push @results, $msg; + } + } } -my (@results); -my (@AssignedObjs, @UnassignedObjs); - -$Objects->UnLimit; -$Objects->OrderBy( FIELD => 'Name' ); +my $is_global = $CF->IsApplied(0); +my $applied = $CF->AppliedTo; +my $not_applied = $CF->NotAppliedTo; -my $ObjectCFs; -$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'}); -$ObjectCFs->UnLimit; -$ObjectCFs->LimitToCustomField($id); +my $collection_class = ref($applied); +$collection_class =~ s/^RT:://; -my %seen; -while (my $OCF = $ObjectCFs->Next) { - $seen{$OCF->ObjectId}++; -} +my $format = RT->Config->Get('AdminSearchResultFormat')->{$collection_class} + || '__id__,__Name__'; -while (my $obj = $Objects->Next) { - my $obj_id = $obj->Id; - - if ($UpdateObjs) { - # Go through and delete all the custom field relationships that this object - # no longer has - my $key = "Object-$obj_id-CF-$id"; - if ($ARGS{$key}) { - if (!$seen{$obj_id}) { - my ($val, $msg) = $CF->AddToObject($obj); - push (@results, $msg); - push @UnassignedObjs, $obj if !$val; - } - } - else { - push @UnassignedObjs, $obj; - if ($seen{$obj_id}) { - my ($val, $msg) = $CF->RemoveFromObject($obj); - push (@results, $msg); - pop @UnassignedObjs if !$val; - } - } - } - elsif (!$seen{$obj_id}) { - push @UnassignedObjs, $obj; - } - next if @UnassignedObjs and $UnassignedObjs[-1] == $obj; - push @AssignedObjs, $obj; -} +my $title = loc('Modify associated objects for [_1]', $CF->Name); <%ARGS> diff --git a/rt/share/html/Admin/CustomFields/index.html b/rt/share/html/Admin/CustomFields/index.html index 139b8ebd6..16fb593f6 100644 --- a/rt/share/html/Admin/CustomFields/index.html +++ b/rt/share/html/Admin/CustomFields/index.html @@ -45,40 +45,38 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<& /Admin/Elements/Header, Title => loc('Select a Custom Field') &> +<& /Admin/Elements/Header, Title => $title &> <& /Admin/Elements/CustomFieldTabs, current_tab => 'Admin/CustomFields/', - Title => loc('Select a Custom Field') &> + Title => $title, +&> -% my @types; -% my $prev_lookup = ''; -% while (my $CustomFieldObj = $CustomFields->Next) { -% next unless $CustomFieldObj->CurrentUserHasRight('AdminCustomField'); -% my $lookup = $CustomFieldObj->FriendlyLookupType; -% if ($lookup ne $prev_lookup) { -% if ($prev_lookup) { - -% } -

<% loc("Custom Fields for [_1]", $lookup) %>

- +% my $tmp = RT::CustomField->new( $session{'CurrentUser'} ); +% if ( $Type ) { +

<% loc("Custom Fields for [_1]", $tmp->FriendlyLookupType( $Type )) %>

% } +<& /Elements/CollectionList, + OrderBy => 'LookupType|Name', + Order => 'ASC|ASC', + Rows => 50, + %ARGS, + Collection => $CustomFields, + Format => $Format, + DisplayFormat => ($Type? '' : '__FriendlyLookupType__,'). $Format, + AllowSorting => 1, + PassArguments => [ + qw(Format Rows Page Order OrderBy), + qw(Type ShowDisabled) + ], +&> +
<&|/l&>Only show custom fields for:
@@ -92,8 +90,12 @@ <%args> $Type => '' $ShowDisabled => 0 + +$Format => undef <%INIT> +my $title = loc('Select a Custom Field'); + $Type ||= $ARGS{'type'} || ''; if ( !$Type && $ARGS{'type'} ) { $Type ||= $ARGS{'type'}; @@ -102,7 +104,9 @@ if ( !$Type && $ARGS{'type'} ) { my $CustomFields = RT::CustomFields->new($session{'CurrentUser'}); $CustomFields->UnLimit; -$CustomFields->{'find_disabled_rows'} = 1 if $ShowDisabled; +$CustomFields->FindAllRows if $ShowDisabled; $CustomFields->LimitToLookupType( $Type ) if $Type; -$CustomFields->OrderByCols( { FIELD => 'LookupType' }, { FIELD => 'Name' } ); + +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'CustomFields'}; + diff --git a/rt/share/html/Admin/Elements/EditCustomFields b/rt/share/html/Admin/Elements/EditCustomFields index 89c6d0f65..0767e4ae4 100755 --- a/rt/share/html/Admin/Elements/EditCustomFields +++ b/rt/share/html/Admin/Elements/EditCustomFields @@ -51,155 +51,126 @@ - -% if ($Object->Id) { -

<&|/l&>Global Custom Fields

-<& PickCustomFields, CustomFields => \@GlobalCFs, ReadOnly => 1, id => $id, SubType => $SubType &> -% }

<&|/l&>Selected Custom Fields

-<& PickCustomFields, CustomFields => [$ObjectCFs->CustomFields], id => $id, Checked => 1, SubType => $SubType &> -

<&|/l&>Unselected Custom Fields

-<& PickCustomFields, CustomFields => \@UnassignedCFs, id => $id, SubType => $SubType &> +<& /Elements/CollectionList, + %ARGS, + Collection => $applied_cfs, + Rows => 0, + Page => 1, + Format => $format, + DisplayFormat => + $id + ? ("'__RemoveCheckBox.{$id}__',". $format .", '__MoveCF.{$id}__'") + : ("'__CheckBox.{RemoveCustomField}__',". $format .", '__MoveCF.{$id}__'"), + AllowSorting => 0, + ShowEmpty => 0, + PassArguments => [ + qw(Page Order OrderBy), + qw(id ObjectType SubType), + ], +&> -<& /Elements/Submit, CheckAll => 1, ClearAll => 1 &> +

<&|/l&>Unselected Custom Fields

+<& /Elements/CollectionList, + OrderBy => 'Name', + Order => 'ASC', + %ARGS, + Collection => $not_applied_cfs, + Rows => 50, + Format => $format, + DisplayFormat => "'__CheckBox.{AddCustomField}__',". $format, + AllowSorting => 1, + ShowEmpty => 0, + PassArguments => [ + qw(Page Order OrderBy), + qw(id ObjectType SubType), + ], +&> + +<& /Elements/Submit, Name => 'UpdateCFs' &>
<%INIT> -my $CustomFields = RT::CustomFields->new($session{'CurrentUser'}); -my @results; -my (@GlobalCFs, @UnassignedCFs); - -my $id = $Object->Id; +my $id = $Object->Id || 0; if ($id and !$Object->CurrentUserHasRight('AssignCustomFields')) { $m->out('

', loc('(No custom fields)'), '

'); return; } +my @results; + my $lookup = $ObjectType; $lookup .= "-$SubType" if $SubType; -$CustomFields->LimitToLookupType($lookup); -$CustomFields->OrderBy( FIELD => 'Name' ); - - -my ($GlobalCFs, $ObjectCFs); -$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'}); -$ObjectCFs->UnLimit; -$ObjectCFs->LimitToObjectId($id); -$ObjectCFs->LimitToLookupType($lookup); - -# Check sanity of SortOrders -my %SortOrders; -$SortOrders{ $_->SortOrder }++ - while ($_ = $ObjectCFs->Next); - -# If there are duplicates, run though and squash them -if (grep $_ > 1, values %SortOrders) { - my $i = 1; - while ( my $ObjectCF = $ObjectCFs->Next ) { - $ObjectCF->SetSortOrder( $i++ ); +## deal with moving sortorder of custom fields +if ( $MoveCustomFieldUp ) { { + my $record = RT::ObjectCustomField->new( $session{'CurrentUser'} ); + $record->LoadByCols( ObjectId => $id, CustomField => $MoveCustomFieldUp ); + unless ( $record->id ) { + push @results, loc("Custom field #[_1] is not applied to this object", $MoveCustomFieldUp); + last; } - $ObjectCFs->GotoFirstItem; -} - -# {{{ deal with moving sortorder of custom fields -if ($CustomField and $Move) { - my $SourceObj = RT::ObjectCustomField->new($session{'CurrentUser'}); - $SourceObj->LoadByCols( ObjectId => $id, CustomField => $CustomField ); - - my $TargetObj; - my $target_order = $SourceObj->SortOrder + $Move; - while (my $ObjectCF = $ObjectCFs->Next) { - my $this_order = $ObjectCF->SortOrder; - - # if we have an exact match, finish the loop now - ($TargetObj = $ObjectCF, last) if $this_order == $target_order; - - # otherwise, we need to apropos toward the general direction - # ... first, check the sign is correct - next unless ($this_order - $SourceObj->SortOrder) * $Move > 0; - # ... next, see if we already have a candidate - if ($TargetObj) { - # ... if yes, compare the delta and choose the smaller one - my $orig_delta = abs($TargetObj->SortOrder - $target_order); - my $this_delta = abs($this_order - $target_order); - next if $orig_delta < $this_delta; - } - - $TargetObj = $ObjectCF; + my ($status, $msg) = $record->MoveUp; + push @results, $msg; +} } +if ( $MoveCustomFieldDown ) { { + my $record = RT::ObjectCustomField->new( $session{'CurrentUser'} ); + $record->LoadByCols( ObjectId => $id, CustomField => $MoveCustomFieldDown ); + unless ( $record->id ) { + push @results, loc("Custom field #[_1] is not applied to this object", $MoveCustomFieldDown); + last; } - if ($TargetObj) { - # swap their sort order - my ($s, $t) = ($SourceObj->SortOrder, $TargetObj->SortOrder); - $TargetObj->SetSortOrder($s); - $SourceObj->SetSortOrder($t); - # because order changed, we must redo search for subsequent uses + my ($status, $msg) = $record->MoveDown; + push @results, $msg; +} } + +if ( $UpdateCFs ) { + foreach my $cf_id ( @AddCustomField ) { + my $CF = RT::CustomField->new( $session{'CurrentUser'} ); + $CF->Load( $cf_id ); + unless ( $CF->id ) { + push @results, loc("Couldn't load CustomField #[_1]", $cf_id); + next; + } + my ($status, $msg) = $CF->AddToObject( $Object ); + push @results, $msg; + } + foreach my $cf_id ( @RemoveCustomField ) { + my $CF = RT::CustomField->new( $session{'CurrentUser'} ); + $CF->Load( $cf_id ); + unless ( $CF->id ) { + push @results, loc("Couldn't load CustomField #[_1]", $cf_id); + next; + } + my ($status, $msg) = $CF->RemoveFromObject( $Object ); + push @results, $msg; } - - $ObjectCFs->GotoFirstItem; -} -# }}} - -if ($id) { - $GlobalCFs = RT::ObjectCustomFields->new($session{'CurrentUser'}); - $GlobalCFs->LimitToObjectId(0); - $GlobalCFs->LimitToLookupType($lookup); } -while (my $cf = $CustomFields->Next) { - my $cf_id = $cf->Id; +my $applied_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); +$applied_cfs->LimitToLookupType($lookup); +$applied_cfs->LimitToGlobalOrObjectId($id); +$applied_cfs->ApplySortOrder; - if ($GlobalCFs and $GlobalCFs->HasEntryForCustomField($cf_id)) { - push @GlobalCFs, $cf; - next; - } +my $not_applied_cfs = RT::CustomFields->new( $session{'CurrentUser'} ); +$not_applied_cfs->LimitToLookupType($lookup); +$not_applied_cfs->LimitToNotApplied( $id ? ($id, 0) : (0) ); - if ($UpdateCFs) { - # Go through and delete all the custom field relationships that this object - # no longer has - my $key = "Object-$id-CF-$cf_id"; - if ($ARGS{$key}) { - if (!$ObjectCFs->HasEntryForCustomField($cf_id)) { - my ($val, $msg) = $cf->AddToObject($Object); - push (@results, $msg); - push @UnassignedCFs, $cf if !$val; - } - } - else { - push @UnassignedCFs, $cf; - if ($ObjectCFs->HasEntryForCustomField($cf_id)) { - my ($val, $msg) = $cf->RemoveFromObject($Object); - push (@results, $msg); - pop @UnassignedCFs if !$val; - } - } - } - elsif (!$ObjectCFs->HasEntryForCustomField($cf_id)) { - push @UnassignedCFs, $cf; - } - else { - } -} - -# redo search... -$ObjectCFs = RT::ObjectCustomFields->new($session{'CurrentUser'}); -$ObjectCFs->UnLimit; -$ObjectCFs->LimitToObjectId($id); -$ObjectCFs->LimitToLookupType($lookup); +my $format = RT->Config->Get('AdminSearchResultFormat')->{'CustomFields'}; <%ARGS> -$title => undef -$Move => undef -$Source => undef -$CustomField => undef -$FindDisabledCustomFields => undef -$UpdateCFs => 0 $Object $ObjectType $SubType => '' + +$UpdateCFs => undef +@RemoveCustomField => () +@AddCustomField => () +$MoveCustomFieldUp => undef +$MoveCustomFieldDown => undef diff --git a/rt/share/html/Admin/Elements/EditScrip b/rt/share/html/Admin/Elements/EditScrip index 29ec71cd7..2bcf64d49 100755 --- a/rt/share/html/Admin/Elements/EditScrip +++ b/rt/share/html/Admin/Elements/EditScrip @@ -56,6 +56,7 @@ <&|/l&>Description: Description || '' %>" /> diff --git a/rt/share/html/Admin/Elements/EditScrips b/rt/share/html/Admin/Elements/EditScrips index df349e1b9..dce0390fd 100755 --- a/rt/share/html/Admin/Elements/EditScrips +++ b/rt/share/html/Admin/Elements/EditScrips @@ -109,10 +109,7 @@ foreach my $id ( grep $_, @DeleteScrip, map /^DeleteScrip-(\d+)/, keys %ARGS ) { } # }}} -my $dir_path = $m->request_comp->dir_path; -$Format ||= qq{'__id__/TITLE:#'} - .qq{,'__Description__/TITLE:Description'} - .q{,__Stage__, __Condition__, __Action__, __Template__}; +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Scrips'}; diff --git a/rt/share/html/Admin/Elements/EditTemplates b/rt/share/html/Admin/Elements/EditTemplates index 0bd68c2c0..7d7d930ce 100755 --- a/rt/share/html/Admin/Elements/EditTemplates +++ b/rt/share/html/Admin/Elements/EditTemplates @@ -73,10 +73,7 @@ <%INIT> -my $dir_path = $m->request_comp->dir_path; -$Format ||= qq{'__id__/TITLE:#'} - .qq{,'__Name__/TITLE:Name'} - .qq{,'__Description__'}; +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Templates'}; my $QueueObj = RT::Queue->new( $session{'CurrentUser'} ); $QueueObj->Load( $id ) if $id; diff --git a/rt/share/html/Admin/Groups/index.html b/rt/share/html/Admin/Groups/index.html index 078f51bd9..17b760c26 100755 --- a/rt/share/html/Admin/Groups/index.html +++ b/rt/share/html/Admin/Groups/index.html @@ -113,10 +113,7 @@ else { $caption = loc("User-defined groups"); } - -$Format ||= q{'__id__/TITLE:#'} - .q{,'__Name__/TITLE:Name'} - .q{,'__Description__'}; +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Groups'}; <%ARGS> diff --git a/rt/share/html/Admin/Queues/Modify.html b/rt/share/html/Admin/Queues/Modify.html index df97a68c7..c6ffe179f 100755 --- a/rt/share/html/Admin/Queues/Modify.html +++ b/rt/share/html/Admin/Queues/Modify.html @@ -194,6 +194,13 @@ if ( $QueueObj->Id ) { ); push @results, @linkresults; push @results, ProcessObjectCustomFieldUpdates( ARGSRef => \%ARGS, Object => $QueueObj ); + if ( RT->Config->Get('RTAddressRegexp') ) { + foreach my $address ( $QueueObj->CorrespondAddress, $QueueObj->CommentAddress ) { + next unless defined $address && length $address; + next if RT::EmailParser->IsRTAddress( $address ); + push @results, loc("RTAddressRegexp option in the config doesn't match [_1]", $address ); + } + } } diff --git a/rt/share/html/Admin/Queues/index.html b/rt/share/html/Admin/Queues/index.html index 52e7b3bfd..c0131b14f 100755 --- a/rt/share/html/Admin/Queues/index.html +++ b/rt/share/html/Admin/Queues/index.html @@ -92,7 +92,7 @@ <%INIT> my $queues = new RT::Queues($session{'CurrentUser'}); -$queues->{'find_disabled_rows'} = 1 if $FindDisabledQueues; +$queues->FindAllRows if $FindDisabledQueues; my ($caption); if ( defined $QueueString && length $QueueString ) { @@ -111,9 +111,7 @@ if ( defined $QueueString && length $QueueString ) { : loc("Enabled Queues"); } -$Format ||= q{'__id__/TITLE:#'} - .q{,'__Name__/TITLE:Name'} - .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,__Disabled__}; +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Queues'}; <%ARGS> diff --git a/rt/share/html/Admin/Tools/Configuration.html b/rt/share/html/Admin/Tools/Configuration.html index eb48af19c..22c846aca 100644 --- a/rt/share/html/Admin/Tools/Configuration.html +++ b/rt/share/html/Admin/Tools/Configuration.html @@ -50,9 +50,7 @@ require Module::Versions::Report; my $title = loc('System Configuration'); unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'SuperUser')) { Abort(loc('This feature is only available to system administrators')); -} - - +} <& /Admin/Elements/Header, Title => $title &> <& /Admin/Elements/ToolTabs, @@ -60,18 +58,15 @@ unless ($session{'CurrentUser'}->HasRight( Object=> $RT::System, Right => 'Super current_subtab => 'Admin/Tools/Configuration.html', Title => $title &> - - -

<&|/l&>Loaded perl modules

-% my $report = Module::Versions::Report::report(); -% my @report = grep /v\d/, split("\n",$report); -
-<% join('
', @report) |n %> -
- -

<&|/l&>RT Config

- +<&|/Widgets/TitleBox, title => loc("RT Configuration") &> +
+ + + + + <%PERL> +my $index_conf; foreach my $key ( RT->Config->Options( Overridable => undef, Sorted => 0 ) ) { my $val = RT->Config->Get( $key ); next unless defined $val; @@ -90,9 +85,11 @@ foreach my $key ( RT->Config->Options( Overridable => undef, Sorted => 0 ) ) { else { $description = loc("core config"); } + $index_conf++; - - + + - + + + % }
<&|/l&>Option<&|/l&>Value<&|/l&>Source
<% $key %>\ +
<% $key %> % if ( $key =~ /Password(?!Length)/i ) { Password not printed\ % } elsif ( !ref $val ) { @@ -104,19 +101,38 @@ foreach my $key ( RT->Config->Options( Overridable => undef, Sorted => 0 ) ) { % } else { <% ref $val %>\ % } -
<% $description %>
+% if ( $description =~ /^.*site config$/ ) { +<% $description %> +% } else { +<% $description %> +% } +
- -

<&|/l&>RT Variables

- -% { no strict qw/refs/; -% my %config_opt = map { $_ => 1 } RT->Config->Options( Overridable => undef ); -% foreach my $key ( sort keys %{*RT::} ) { -% next if !${'RT::'.$key} || ref ${'RT::'.$key} || $config_opt{ $key }; - - @@ -364,22 +349,20 @@ if ($UserObj->Id && $id ne 'new') { # }}} } + +my %password_cond = $UserObj->CurrentUserRequireToSetPassword; if ( $UserObj->Id ) { - my $password_not_set; # Deal with Password field - if ( !$Pass1 and !$Pass2 ) { - $password_not_set = 1; - } elsif ( $Pass1 ne $Pass2 ) { - $password_not_set = 1; - push @results, loc("Passwords do not match."); - } elsif ( $Pass1 eq $Pass2 and !$UserObj->IsPassword($Pass1) ) { - my ($code, $msg) = $UserObj->SetPassword($Pass1); - push @results, loc_fuzzy($msg); - $password_not_set = 1 unless $code; + my ($status, $msg) = $UserObj->SafeSetPassword( + Current => $CurrentPass, + New => $Pass1, + Confirmation => $Pass2, + ); + push @results, $msg; + + if ( $id eq 'new' && !$status ) { + push @results, loc("A password was not set, so user won't be able to login."); } - if ($id eq 'new' and $password_not_set) { - push @results, loc("A password was not set, so user won't be able to login."); - } } @@ -431,7 +414,8 @@ $City => undef $State => undef $Zip => undef $Country => undef +$CurrentPass => undef $Pass1 => undef -$Pass2=> undef +$Pass2 => undef $Create=> undef diff --git a/rt/share/html/Admin/Users/index.html b/rt/share/html/Admin/Users/index.html index e9a58183d..88a775fc3 100755 --- a/rt/share/html/Admin/Users/index.html +++ b/rt/share/html/Admin/Users/index.html @@ -93,7 +93,7 @@ <%INIT> my $caption; my $users = RT::Users->new( $session{'CurrentUser'} ); -$users->{'find_disabled_rows'} = 1 if $FindDisabledUsers; +$users->FindAllRows if $FindDisabledUsers; if ( defined($UserString) && length $UserString ) { $caption = loc("Users matching search criteria"); @@ -117,9 +117,7 @@ else { $users->LimitToPrivileged; } -$Format ||= q{'__id__/TITLE:#'} - .q{,'__Name__/TITLE:Name'} - .q{,__RealName__, __EmailAddress__}; +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Users'}; <%ARGS> diff --git a/rt/share/html/Dashboards/Elements/HiddenSearches b/rt/share/html/Dashboards/Elements/HiddenSearches index aa3a67ebb..753d2fe49 100644 --- a/rt/share/html/Dashboards/Elements/HiddenSearches +++ b/rt/share/html/Dashboards/Elements/HiddenSearches @@ -50,6 +50,9 @@ $Dashboard <%init> +# eliminate deleted searches (id=0) because they confuse this logic +@searches = grep { $_->Id } @searches; + return if @searches == 0; my @display; diff --git a/rt/share/html/Dashboards/Render.html b/rt/share/html/Dashboards/Render.html index 1893b533f..ba01a9d2e 100644 --- a/rt/share/html/Dashboards/Render.html +++ b/rt/share/html/Dashboards/Render.html @@ -110,10 +110,11 @@ for my $sub ($session{'CurrentUser'}->UserObj->Attributes->Named('Subscription') last; } -# otherwise honor their search preferences.. otherwise 20 rows -if (!$rows) { +# otherwise honor their search preferences.. otherwise 50 rows +# $rows == 0 means unlimited, which we don't want to ignore from above +unless (defined($rows)) { my $prefs = $session{'CurrentUser'}->UserObj->Preferences("SearchDisplay") || {}; - $rows = defined($prefs->{'RowsPerPage'}) ? $prefs->{'RowsPerPage'} : 20; + $rows = defined($prefs->{'RowsPerPage'}) ? $prefs->{'RowsPerPage'} : 50; } my $title = loc 'Dashboard [_1]', $DashboardObj->Name; diff --git a/rt/share/html/Download/CustomFieldValue/dhandler b/rt/share/html/Download/CustomFieldValue/dhandler index 218de33c8..d8c703904 100644 --- a/rt/share/html/Download/CustomFieldValue/dhandler +++ b/rt/share/html/Download/CustomFieldValue/dhandler @@ -63,7 +63,10 @@ unless ($OCFV->id) { my $content_type = $OCFV->ContentType || 'text/plain'; -unless (RT->Config->Get('TrustHTMLAttachments')) { +if (RT->Config->Get('AlwaysDownloadAttachments')) { + $r->headers_out->{'Content-Disposition'} = "attachment; filename=" . $OCFV->Content; +} +elsif (!RT->Config->Get('TrustHTMLAttachments')) { $content_type = 'text/plain' if ($content_type =~ /^text\/html/i); } diff --git a/rt/share/html/Elements/CollectionAsTable/Row b/rt/share/html/Elements/CollectionAsTable/Row index fa7474b6c..a1af9f383 100644 --- a/rt/share/html/Elements/CollectionAsTable/Row +++ b/rt/share/html/Elements/CollectionAsTable/Row @@ -54,9 +54,10 @@ $Depth => undef $Warning => undef $ColumnMap => {} $Class => 'RT__Ticket' +$Classes => '' <%init> -$m->out( '' . "\n" ); use HTML::Entities; diff --git a/rt/share/html/Elements/CollectionList b/rt/share/html/Elements/CollectionList index 6f21420f5..c7bdfd903 100644 --- a/rt/share/html/Elements/CollectionList +++ b/rt/share/html/Elements/CollectionList @@ -54,7 +54,9 @@ if (!$Collection && $Class eq 'RT::Tickets') { my $TotalFound = $Collection->CountAll(); return '' if !$TotalFound && !$ShowEmpty; -if ( @OrderBy ) { +# XXX: ->{'order_by'} is hacky, but there is no way to check if +# collection is ordered or not +if ( @OrderBy && ($AllowSorting || !$Collection->{'order_by'}) ) { if ( $OrderBy[0] =~ /\|/ ) { @OrderBy = split /\|/, $OrderBy[0]; @Order = split /\|/,$Order[0]; @@ -122,13 +124,27 @@ my ($i, $column_map) = (0, {}); while ( my $record = $Collection->Next ) { # Every ten rows, flush the buffer and put something on the page. $m->flush_buffer unless ++$i % 10; + + my $warning = 0; + my $Classes = ''; + + $m->callback( + CallbackName => 'EachRow', + Record => $record, + Warning => \$warning, + Classes => \$Classes, + Format => \@Format, + ); + $m->comp('/Elements/CollectionAsTable/Row', - i => $i, - Format => \@Format, - record => $record, - maxitems => $maxitems, + i => $i, + Format => \@Format, + record => $record, + maxitems => $maxitems, ColumnMap => $column_map, Class => $Class, + Warning => $warning, + Classes => $Classes, ); } diff --git a/rt/share/html/Elements/ColumnMap b/rt/share/html/Elements/ColumnMap index 71517e063..a1475a99d 100644 --- a/rt/share/html/Elements/ColumnMap +++ b/rt/share/html/Elements/ColumnMap @@ -92,6 +92,26 @@ my $COLUMN_MAP = { value => sub { return $_[0]->LastUpdatedByObj->Name } }, + CustomField => { + attribute => sub { return shift @_ }, + title => sub { return pop @_ }, + value => sub { + # Display custom field contents, separated by newlines. + # For Image custom fields we also show a thumbnail here. + + my $values = $_[0]->CustomFieldValues( $_[-1] ); + my @values = map { + ( + ($_->CustomFieldObj->Type eq 'Image') + ? \($m->scomp( '/Elements/ShowCustomFieldImage', Object => $_ )) + : $_->Content + ), + \'
', + } @{ $values->ItemsArrayRef }; + pop @values; # Remove that last
+ return @values; + }, + }, CheckBox => { title => sub { @@ -136,8 +156,12 @@ my $COLUMN_MAP = { $_ => { value => sub { return \$value } }; } qw(WebPath WebBaseURL WebURL)), + WebRequestPath => { value => sub { substr( $m->request_path, 1 ) } }, + WebRequestPathDir => { value => sub { substr( $m->request_comp->dir_path, 1 ) } }, }; +$COLUMN_MAP->{'CF'} = $COLUMN_MAP->{'CustomField'}; + <%INIT> $m->callback( COLUMN_MAP => $COLUMN_MAP, CallbackName => 'Once', CallbackOnce => 1 ); diff --git a/rt/share/html/Elements/CreateTicket b/rt/share/html/Elements/CreateTicket index 9c8f3aadf..fd2ba9e53 100755 --- a/rt/share/html/Elements/CreateTicket +++ b/rt/share/html/Elements/CreateTicket @@ -45,6 +45,9 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} - -<&|/l, $m->scomp('/Elements/SelectNewTicketQueue', OnChange => 'document.CreateTicketInQueue.submit()')&> [_1] + +<&|/l, $m->scomp('/Elements/SelectNewTicketQueue', OnChange => 'document.CreateTicketInQueue.submit()', SendTo => $SendTo ) &> [_1] +<%ARGS> +$SendTo => '/Ticket/Create.html', + diff --git a/rt/share/html/Elements/EditCustomFieldSelect b/rt/share/html/Elements/EditCustomFieldSelect index 8fe79f9f9..30b06dbd1 100644 --- a/rt/share/html/Elements/EditCustomFieldSelect +++ b/rt/share/html/Elements/EditCustomFieldSelect @@ -52,7 +52,7 @@ % my @category; % my $id = $NamePrefix . $CustomField->Id; % my $out = $m->scomp('SELF:options', %ARGS, SelectedRef => \$selected, CategoryRef => \@category); -% if (@category and not $CustomField->BasedOnObj->id) { +% if (!$HideCategory and @category and not $CustomField->BasedOnObj->id) { %# XXX - Hide this select from w3m?
RT::<% $key %> + + + + + - - - +<&|/Widgets/TitleBox, title => loc("Perl library search order") &> +
    +% foreach my $inc (@INC) { +
  1. <% $inc %>
  2. +% } +
+ + + +
+<&|/Widgets/TitleBox, title=> loc("RT core variables") &> + + + + + +<%PERL> +{ no strict qw/refs/; +my %config_opt = map { $_ => 1 } RT->Config->Options( Overridable => undef ); +my $index_var; +foreach my $key ( sort keys %{*RT::} ) { + next if !${'RT::'.$key} || ref ${'RT::'.$key} || $config_opt{ $key }; + $index_var++; + + + +
<&|/l&>Variable<&|/l&>Value
RT::<% $key %> % if ( $key =~ /Password(?!Length)/i ) { Password not printed % } else { @@ -127,44 +143,100 @@ foreach my $key ( RT->Config->Options( Overridable => undef, Sorted => 0 ) ) { % } % }
+ -

<&|/l&>RT Size

- +<&|/Widgets/TitleBox, title => loc("RT Size") &> +
+ + + + <%PERL> -for my $type (qw/Ticket Queue Transaction Group/) { - my $class = 'RT::' . $type . 's'; +my ($index_size, $user_count, $privileged_count); +for my $type (qw/Tickets Queues Transactions Groups PrivilegedUsers UnprivilegedUsers/) { + my $count; + my $class = 'RT::' . $type; + $class =~ s/Privileged|Unprivileged//; my $collection = $class->new($RT::SystemUser); $collection->UnLimit; - my $count = $collection->CountAll; + if ($type =~ /PrivilegedUsers/) { + $user_count = $collection->CountAll; + $collection->LimitToPrivileged; + $count = $privileged_count = $collection->CountAll; + } elsif ($type =~ /UnprivilegedUsers/) { + $count = $user_count - $privileged_count; + } else { + $count = $collection->CountAll; + } + $index_size++; - - + + + + % } +
<&|/l&>Object<&|/l&>Size
<% $type %>s<% $count %>
<% $type %><% $count %>
+ +
-<%PERL> -my $users = RT::Users->new($RT::SystemUser); -$users->UnLimit; -my $user_count = $users->CountAll; +<&|/Widgets/TitleBox, title => loc("Mason template search order") &> +
    +% foreach my $path ( map { $_->[1] } $m->interp->comp_root_array ) { +
  1. <% $path %>
  2. +% } +
+ -$users->LimitToPrivileged; -my $privileged_count = $users->CountAll; -my $unprivileged_count = $user_count - $privileged_count; - -
Privileged Users<% $privileged_count %>
Unprivileged Users<% $unprivileged_count %>
+ +<&|/Widgets/TitleBox, title => loc("Loaded perl modules")&> + + + + + + + +<%perl> +my $i = 0; +my $report = Module::Versions::Report::report(); +my @report = grep /v\d/, split("\n",$report); +shift @report; # throw away the perl version +my ($ver, $source, $distfile); +foreach my $item (@report) { +if ($item =~ /^\s*(.*?)\s*v(\S+);/) { + $item = $1; + $ver = $2; + $distfile = $item.".pm"; + $distfile =~ s|::|/|g; +} + + + + + + +% }
<&|/l&>Module<&|/l&>Version<&|/l&>Source
<% $item %> + <%$ver%> + + <% $INC{$distfile} %> +
+ -

<&|/l&>Perl configuration

+<&|/Widgets/TitleBox, title => loc("Perl configuration") &> % require Config;
 <% Config::myconfig() %>
 
- -

<&|/l&>Perl Include Paths (@INC)

-
-% foreach my $inc (@INC) {
-<% $inc %>
-% }
-
+ diff --git a/rt/share/html/Admin/Users/Memberships.html b/rt/share/html/Admin/Users/Memberships.html index ea5dd258b..cd8574d58 100644 --- a/rt/share/html/Admin/Users/Memberships.html +++ b/rt/share/html/Admin/Users/Memberships.html @@ -128,9 +128,7 @@ my $is_not_member = RT::Groups->new( $session{'CurrentUser'} ); $is_not_member->LimitToUserDefinedGroups; $is_not_member->WithoutMember( PrincipalId => $UserObj->Id ); -$Format ||= q{'__id__/TITLE:#'} - .q{,'__Name__/TITLE:Name'} - .q{,'__Description__'}; +$Format ||= RT->Config->Get('AdminSearchResultFormat')->{'Groups'}; <%ARGS> $id => undef diff --git a/rt/share/html/Admin/Users/Modify.html b/rt/share/html/Admin/Users/Modify.html index aae38b173..6af7bf378 100755 --- a/rt/share/html/Admin/Users/Modify.html +++ b/rt/share/html/Admin/Users/Modify.html @@ -113,26 +113,11 @@ /> <&|/l&>Let this user be granted rights
- -% unless (RT->Config->Get('WebExternalAuth') and !RT->Config->Get('WebFallbackToInternalAuth')) { - - - - - - - - -
-<&|/l&>New Password: - - -
-<&|/l&>Retype Password: - - -
-% } + +<& /Elements/EditPassword, + User => $UserObj, + Name => [qw(CurrentPass Pass1 Pass2)], +&> % $m->callback( %ARGS, CallbackName => 'LeftColumnBottom', UserObj => $UserObj );
- + - + - + - + - + - + % } - + - + - + - + - + - + % $m->callback( CallbackName => 'NewLink' ); diff --git a/rt/share/html/Elements/EditPassword b/rt/share/html/Elements/EditPassword new file mode 100644 index 000000000..3b0ec0b32 --- /dev/null +++ b/rt/share/html/Elements/EditPassword @@ -0,0 +1,34 @@ +% unless ( $cond{'CanSet'} ) { +<% $cond{'Reason'} %>
+% } else { +
<&|/l&>Depends on:<& ShowRelationLabel, id => $id, Label => loc('Depends on'), Relation => 'DependsOn' &>: % while (my $link = $Object->DependsOn->Next) { @@ -61,7 +61,7 @@
<&|/l&>Depended on by:<& ShowRelationLabel, id => $id, Label => loc('Depended on by'), Relation => 'DependedOnBy' &>: % while (my $link = $Object->DependedOnBy->Next) { @@ -70,7 +70,7 @@
<&|/l&>Parents:<& ShowRelationLabel, id => $id, Label => loc('Parents'), Relation => 'Parents' &>: % while (my $link = $Object->MemberOf->Next) { @@ -79,7 +79,7 @@
<&|/l&>Children:<& ShowRelationLabel, id => $id, Label => loc('Children'), Relation => 'Children' &>: % while (my $link = $Object->Members->Next) { @@ -88,7 +88,7 @@
<&|/l&>Refers to:<& ShowRelationLabel, id => $id, Label => loc('Refers to'), Relation => 'RefersTo' &>: % while (my $link = $Object->RefersTo->Next) { @@ -97,7 +97,7 @@
<&|/l&>Referred to by:<& ShowRelationLabel, id => $id, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>: % while (my $link = $Object->ReferredToBy->Next) { % # Skip reminders @@ -134,27 +134,27 @@
<&|/l&>Depends on:<& ShowRelationLabel, id => $id, Label => loc('Depends on'), Relation => 'DependsOn' &>:
<&|/l&>Depended on by:<& ShowRelationLabel, id => $id, Label => loc('Depended on by'), Relation => 'DependedOnBy' &>:
<&|/l&>Parents:<& ShowRelationLabel, id => $id, Label => loc('Parents'), Relation => 'Parents' &>:
<&|/l&>Children:<& ShowRelationLabel, id => $id, Label => loc('Children'), Relation => 'Children' &>:
<&|/l&>Refers to:<& ShowRelationLabel, id => $id, Label => loc('Refers to'), Relation => 'RefersTo' &>:
<&|/l&>Referred to by:<& ShowRelationLabel, id => $id, Label => loc('Referred to by'), Relation => 'ReferredToBy' &>:
+ +% if ( $cond{'RequireCurrent'} ) { + + + + +% } + + + + + + + + + + + +
<&|/l&>Your current password:
<&|/l&>New password:
<&|/l&>Retype Password:
+% } + +<%ARGS> +$User +@Name => qw(CurrentPass NewPass1 NewPass2) + +<%INIT> + +my %cond = $User->CurrentUserRequireToSetPassword; + + diff --git a/rt/share/html/Elements/HeaderJavascript b/rt/share/html/Elements/HeaderJavascript index 6ee88a13b..c4eb17504 100644 --- a/rt/share/html/Elements/HeaderJavascript +++ b/rt/share/html/Elements/HeaderJavascript @@ -111,7 +111,7 @@ $onload => undef typeField.setAttribute('value', 'text/html'); textArea.parentNode.appendChild(typeField); - var oFCKeditor = new FCKeditor( textArea.name, '100%', <% RT->Config->Get('MessageBoxRichTextHeight') %> ); + var oFCKeditor = new FCKeditor( textArea.name, '100%', <% RT->Config->Get('MessageBoxRichTextHeight', $session{CurrentUser} ) %> ); oFCKeditor.BasePath = "<%RT->Config->Get('WebPath')%>/NoAuth/RichText/"; oFCKeditor.ReplaceTextarea(); } diff --git a/rt/share/html/Elements/Login b/rt/share/html/Elements/Login index 8dfbe51d1..e768b0e7a 100755 --- a/rt/share/html/Elements/Login +++ b/rt/share/html/Elements/Login @@ -64,6 +64,21 @@ my $form_action = defined $goto ? $goto : defined $req_uri ? $req_uri : RT->Config->Get('WebPath') ; + +# sanitize $form_action +my $uri = URI->new($form_action); + +# You get undef scheme with a relative uri like "/Search/Build.html" +unless (!defined($uri->scheme) || $uri->scheme eq 'http' || $uri->scheme eq 'https') { + $form_action = RT->Config->Get('WebPath'); +} + +# Make sure we're logging in to the same domain +# You can get an undef authority with a relative uri like "index.html" +my $uri_base_url = URI->new(RT->Config->Get('WebBaseURL')); +unless (!defined($uri->authority) || $uri->authority eq $uri_base_url->authority) { + $form_action = RT->Config->Get('WebPath'); +} % $m->callback( %ARGS, CallbackName => 'Header' ); diff --git a/rt/share/html/Elements/Logo b/rt/share/html/Elements/Logo index 359738b5e..e6cb1ad4b 100644 --- a/rt/share/html/Elements/Logo +++ b/rt/share/html/Elements/Logo @@ -46,10 +46,11 @@ %# %# END BPS TAGGED BLOCK }}}
<& Elements/ResultViews, + Collection => $session{'tickets'}, QueryString => $QueryString, Query => $Query, Format => $Format, @@ -118,6 +119,7 @@ if ( !defined($Rows) ) { $Rows = 50; } } +$Page = 1 unless $Page && $Page > 0; my ($title, $ticketcount); $session{'i'}++; @@ -134,6 +136,8 @@ if ($OrderBy =~ /\|/) { } else { $session{'tickets'}->OrderBy(FIELD => $OrderBy, ORDER => $Order); } +$session{'tickets'}->RowsPerPage( $Rows ) if $Rows; +$session{'tickets'}->GotoPage( $Page - 1 ); $session{'CurrentSearchHash'} = { Format => $Format, @@ -142,7 +146,7 @@ $session{'CurrentSearchHash'} = { Order => $Order, OrderBy => $OrderBy, RowsPerPage => $Rows - }; +}; if ( $session{'tickets'}->Query()) { @@ -161,7 +165,10 @@ my $QueryString = "?".$m->comp('/Elements/QueryString', Page => $Page); my $ShortQueryString = "?".$m->comp('/Elements/QueryString', Query => $Query); my $RSSQueryString = "?".$m->comp('/Elements/QueryString', Query => $Query, Order => $Order, OrderBy => $OrderBy); -my $RSSFeedURL = RT->Config->Get('WebPath')."/Search/Results.rdf$RSSQueryString"; +my $RSSPath = join '/', map $m->interp->apply_escapes($_, 'u'), + $session{'CurrentUser'}->UserObj->Name, + $session{'CurrentUser'}->UserObj->GenerateAuthString( $Query.$Order.$OrderBy ); +my $RSSFeedURL = RT->Config->Get('WebPath')."/NoAuth/rss/$RSSPath/$RSSQueryString"; if ($ARGS{'TicketsRefreshInterval'}) { $session{'tickets_refresh_interval'} = $ARGS{'TicketsRefreshInterval'}; diff --git a/rt/share/html/Search/Results.rdf b/rt/share/html/Search/Results.rdf index 0a1943059..c402b6f8e 100644 --- a/rt/share/html/Search/Results.rdf +++ b/rt/share/html/Search/Results.rdf @@ -45,59 +45,4 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} -<%INIT> - -my $Tickets = RT::Tickets->new($session{'CurrentUser'}); -$Tickets->FromSQL($ARGS{'Query'}); -if ($OrderBy =~ /\|/) { - # Multiple Sorts - my @OrderBy = split /\|/,$OrderBy; - my @Order = split /\|/,$Order; - $Tickets->OrderByCols( - map { { FIELD => $OrderBy[$_], ORDER => $Order[$_] } } ( 0 - .. $#OrderBy ) );; -} else { - $Tickets->OrderBy(FIELD => $OrderBy, ORDER => $Order); -} -$r->content_type('application/rss+xml'); - - - - # create an RSS 1.0 file (http://purl.org/rss/1.0/) - use XML::RSS; - my $rss = new XML::RSS (version => '1.0'); - $rss->channel( - title => RT->Config->Get('rtname').": Search" . $ARGS{'Query'}, - link => RT->Config->Get('WebURL'), - description => "", - dc => { - }, - generator => "RT v" . $RT::VERSION, - syn => { - updatePeriod => "hourly", - updateFrequency => "1", - updateBase => "1901-01-01T00:00+00:00", - }, - ); - - - while ( my $Ticket = $Tickets->Next()) { - my $creator_str = $m->scomp('/Elements/ShowUser', User => $Ticket->CreatorObj); - $creator_str =~ s/[\r\n]//g; - $rss->add_item( - title => $Ticket->Subject || loc('No Subject'), - link => RT->Config->Get('WebURL')."Ticket/Display.html?id=".$Ticket->id, - description => $Ticket->Transactions->First->Content, - dc => { creator => $creator_str, - date => $Ticket->CreatedObj->RFC2822, - }, - guid => $Ticket->Queue . '_' . $Ticket->id, - ); - } -$m->out($rss->as_string); -$m->abort(); - -<%ARGS> -$OrderBy => 'Created' -$Order => 'ASC' - +<& /Search/Elements/ResultsRSSView, %ARGS &> diff --git a/rt/share/html/Search/Results.tsv b/rt/share/html/Search/Results.tsv index bb3ac4482..946a35d02 100644 --- a/rt/share/html/Search/Results.tsv +++ b/rt/share/html/Search/Results.tsv @@ -107,7 +107,7 @@ $r->content_type('application/vnd.ms-excel'); $_ += @header - 1 foreach values %cf_name_to_pos; - foreach my $name ( sort { $cf_name_to_pos{$a} <=> $cf_name_to_pos{$a} } keys %cf_name_to_pos ) { + foreach my $name ( sort { $cf_name_to_pos{$a} <=> $cf_name_to_pos{$b} } keys %cf_name_to_pos ) { push @header, "CF-". $name; } $m->out(join("\t", @header)); diff --git a/rt/share/html/SelfService/Error.html b/rt/share/html/SelfService/Error.html index 9c81ebbe6..8956c3ea1 100755 --- a/rt/share/html/SelfService/Error.html +++ b/rt/share/html/SelfService/Error.html @@ -66,6 +66,6 @@ $Why => loc("the calling component did not specify why") <%INIT> -$Details ||= "No details"; +$Details ||= loc("No details"); $RT::Logger->error("WebRT: $Why ($Details)"); diff --git a/rt/share/html/SelfService/Prefs.html b/rt/share/html/SelfService/Prefs.html index dabab7937..468a3d508 100755 --- a/rt/share/html/SelfService/Prefs.html +++ b/rt/share/html/SelfService/Prefs.html @@ -50,13 +50,14 @@ <& /Elements/ListActions, actions => \@results &>
-% unless (RT->Config->Get('WebExternalAuth') and !RT->Config->Get('WebFallbackToInternalAuth')) { <&| /Widgets/TitleBox, title => loc('Change password') &> -<&|/l&>New password: -<&|/l&>Confirm: +<& /Elements/EditPassword, + User => $user, + Name => [qw(CurrentPass NewPass1 NewPass2)], +&> +
-% } <& /Elements/Submit, Label => loc('Save Changes') &>
@@ -64,29 +65,32 @@ <%INIT> my @results; -if ($NewPass1) { - if ($NewPass1 ne $NewPass2) { - push (@results, "Passwords did not match."); - } - else { - my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetPassword($NewPass1); - push (@results, "Password: ".$msg); - } +my $user = $session{'CurrentUser'}->UserObj; + +if (defined $NewPass1 && length $NewPass1 ) { + my ($status, $msg) = $user->SafeSetPassword( + Current => $CurrentPass, + New => $NewPass1, + Confirmation => $NewPass2, + ); + push @results, loc("Password: [_1]", $msg); } + if ($Signature) { $Signature =~ s/(\r\n|\r)/\n/g; - if ($Signature ne $session{'CurrentUser'}->UserObj->Signature) { - my ($val, $msg)=$session{'CurrentUser'}->UserObj->SetSignature($Signature); + if ($Signature ne $user->Signature) { + my ($val, $msg) = $user->SetSignature($Signature); push (@results, "Signature: ".$msg); } } -#A hack to make sure that session gets rewritten. +#A hack to make sure that session gets rewritten. $session{'i'}++; <%ARGS> $Signature => undef +$CurrentPass => undef $NewPass1 => undef $NewPass2 => undef diff --git a/rt/share/html/Ticket/Attachment/dhandler b/rt/share/html/Ticket/Attachment/dhandler index d4d556b24..8b41329ba 100755 --- a/rt/share/html/Ticket/Attachment/dhandler +++ b/rt/share/html/Ticket/Attachment/dhandler @@ -68,8 +68,11 @@ } my $content_type = $AttachmentObj->ContentType || 'text/plain'; - - unless (RT->Config->Get('TrustHTMLAttachments')) { + + if (RT->Config->Get('AlwaysDownloadAttachments')) { + $r->headers_out->{'Content-Disposition'} = "attachment; filename=" . $AttachmentObj->Filename; + } + elsif (!RT->Config->Get('TrustHTMLAttachments')) { $content_type = 'text/plain' if ($content_type =~ /^text\/html/i); } diff --git a/rt/share/html/Ticket/Create.html b/rt/share/html/Ticket/Create.html index 28b655691..2c8e35778 100755 --- a/rt/share/html/Ticket/Create.html +++ b/rt/share/html/Ticket/Create.html @@ -112,6 +112,7 @@ +% $m->callback( %ARGS, CallbackName => 'AfterSubject' ); @@ -158,6 +159,7 @@ % } else { <& /Elements/MessageBox, QuoteTransaction => $QuoteTransaction &> %} +% $m->callback( %ARGS, QueueObj => $QueueObj, CallbackName => 'AfterMessageBox' );
@@ -392,6 +394,22 @@ if ( !exists $ARGS{'AddMoreAttach'} && ($ARGS{'id'}||'') eq 'new' ) { $checks_failure = 1 unless $status; } +# check email addresses for RT's +{ + foreach my $field ( qw(Requestors Cc AdminCc) ) { + my $value = $ARGS{ $field }; + next unless defined $value && length $value; + + my @emails = Email::Address->parse( $value ); + foreach my $email ( grep RT::EmailParser->IsRTAddress($_->address), @emails ) { + push @results, loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $email->format, loc($field =~ /^(.*?)s?$/) ); + $checks_failure = 1; + $email = undef; + } + $ARGS{ $field } = join ', ', map $_->format, grep defined, @emails; + } +} + my $skip_create = 0; $m->callback( CallbackName => 'BeforeCreate', ARGSRef => \%ARGS, skip_create => \$skip_create, checks_failure => $checks_failure, results => \@results ); diff --git a/rt/share/html/Ticket/Elements/EditCustomFields b/rt/share/html/Ticket/Elements/EditCustomFields index c3a44ee22..5478c7871 100755 --- a/rt/share/html/Ticket/Elements/EditCustomFields +++ b/rt/share/html/Ticket/Elements/EditCustomFields @@ -45,6 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} +% $m->callback( %ARGS, CallbackName => 'BeforeCustomFields' ); % my $i = 0; % while ( my $CustomField = $CustomFields->Next ) { @@ -85,6 +86,7 @@ % }
+% $m->callback( %ARGS, CallbackName => 'AfterCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj ); <%INIT> my $CustomFields; diff --git a/rt/share/html/Ticket/Elements/EditDates b/rt/share/html/Ticket/Elements/EditDates index fc17cdbd4..e6f724f7b 100755 --- a/rt/share/html/Ticket/Elements/EditDates +++ b/rt/share/html/Ticket/Elements/EditDates @@ -70,6 +70,7 @@ <& /Elements/SelectDate, menu_prefix => 'Due', current => 0 &> (<% $TicketObj->DueObj->AsString %>) +% $m->callback( %ARGS, CallbackName => 'EndOfList', Ticket => $TicketObj ); <%ARGS> $TicketObj => undef diff --git a/rt/share/html/Ticket/Elements/EditTransactionCustomFields b/rt/share/html/Ticket/Elements/EditTransactionCustomFields index 8bf939db6..a58dded9b 100644 --- a/rt/share/html/Ticket/Elements/EditTransactionCustomFields +++ b/rt/share/html/Ticket/Elements/EditTransactionCustomFields @@ -45,6 +45,7 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} +% $m->callback( CallbackName => 'BeforeTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, NamePrefix => $NamePrefix ); % if ($CustomFields->Count) { % while (my $CF = $CustomFields->Next()) { % next unless $CF->CurrentUserHasRight('ModifyCustomField'); @@ -60,6 +61,7 @@ % } % } +% $m->callback( CallbackName => 'AfterTransactionCustomFields', TicketObj => $TicketObj, QueueObj => $QueueObj, NamePrefix => $NamePrefix ); <%INIT> my $CustomFields; diff --git a/rt/share/html/Ticket/Elements/PreviewScrips b/rt/share/html/Ticket/Elements/PreviewScrips index 7480adecf..d376f5d08 100755 --- a/rt/share/html/Ticket/Elements/PreviewScrips +++ b/rt/share/html/Ticket/Elements/PreviewScrips @@ -69,7 +69,11 @@ my @non_recipients = @{ $squelch{'EmailAddresses'} }; %my @addresses = $scrip->ActionObj->Action->$type(); % } diff --git a/rt/share/html/Ticket/Elements/ShowAttachments b/rt/share/html/Ticket/Elements/ShowAttachments index 72298d79f..ab0d92112 100755 --- a/rt/share/html/Ticket/Elements/ShowAttachments +++ b/rt/share/html/Ticket/Elements/ShowAttachments @@ -61,11 +61,22 @@ my $size = $rev->ContentLength; if ($size) { - if ($size > 1024) { - $size = int($size/102.4)/10 . "k"; + my $kb = int($size/102.4) / 10; + my $units = RT->Config->Get('AttachmentUnits'); + + if (!defined($units)) { + if ($size > 1024) { + $size = $kb . "k"; + } + else { + $size = $size . "b"; + } + } + elsif ($units eq 'k') { + $size = $kb . "k"; } else { - $size = $size ."b"; + $size = $size . "b"; } diff --git a/rt/share/html/Ticket/Elements/ShowDates b/rt/share/html/Ticket/Elements/ShowDates index d309907dc..07140c2e4 100755 --- a/rt/share/html/Ticket/Elements/ShowDates +++ b/rt/share/html/Ticket/Elements/ShowDates @@ -84,6 +84,7 @@ <% $UpdatedString | h %> % } +% $m->callback( %ARGS, CallbackName => 'EndOfList', TicketObj => $Ticket ); <%ARGS> $Ticket => undef diff --git a/rt/share/html/Ticket/Elements/ShowGroupMembers b/rt/share/html/Ticket/Elements/ShowGroupMembers index a15f850b4..6597cc543 100644 --- a/rt/share/html/Ticket/Elements/ShowGroupMembers +++ b/rt/share/html/Ticket/Elements/ShowGroupMembers @@ -50,7 +50,9 @@ % my $Users = $Group->UserMembersObj( Recursively => $Recursively ); % while ( my $user = $Users->Next ) { <& /Elements/ShowUser, User => $user, Ticket => $Ticket &> -<& /Elements/ShowUserEmailFrequency, User => $user, Ticket => $Ticket &>
+<& /Elements/ShowUserEmailFrequency, User => $user, Ticket => $Ticket &> +% $m->callback( User => $user, Ticket => $Ticket, %ARGS, CallbackName => 'AboutThisUser' ); +
% } % my $Groups = $Group->GroupMembersObj( Recursively => $Recursively ); % $Groups->LimitToUserDefinedGroups; diff --git a/rt/share/html/Ticket/Elements/ShowMessageStanza b/rt/share/html/Ticket/Elements/ShowMessageStanza index 0d4fe6154..9d2f21120 100755 --- a/rt/share/html/Ticket/Elements/ShowMessageStanza +++ b/rt/share/html/Ticket/Elements/ShowMessageStanza @@ -48,7 +48,8 @@ <%perl> if ( ref $Message ) { $m->out('
') if $plain_text_pre && !$Depth && !$plain_text_mono;
-    $m->out( qq{
} ); + $m->out( qq{
} ); + my @stack; my $para = ''; diff --git a/rt/share/html/Ticket/Elements/ShowPeople b/rt/share/html/Ticket/Elements/ShowPeople index ddd2e3c6f..1f0e5319e 100755 --- a/rt/share/html/Ticket/Elements/ShowPeople +++ b/rt/share/html/Ticket/Elements/ShowPeople @@ -50,7 +50,9 @@ <&|/l&>Owner: % my $owner = $Ticket->OwnerObj; <& /Elements/ShowUser, User => $owner, Ticket => $Ticket &> - <& /Elements/ShowUserEmailFrequency, User => $owner, Ticket => $Ticket &> + <& /Elements/ShowUserEmailFrequency, User => $owner, Ticket => $Ticket &> +% $m->callback( User => $owner, Ticket => $Ticket, %ARGS, CallbackName => 'AboutThisUser' ); + <&|/l&>Requestors: diff --git a/rt/share/html/Ticket/Elements/ShowSummary b/rt/share/html/Ticket/Elements/ShowSummary index 4c2d54e5e..21c53c594 100755 --- a/rt/share/html/Ticket/Elements/ShowSummary +++ b/rt/share/html/Ticket/Elements/ShowSummary @@ -45,73 +45,82 @@ %# those contributions and any derivatives thereof. %# %# END BPS TAGGED BLOCK }}} - - - + +
- <&| /Widgets/TitleBox, title => loc('The Basics'), - title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id, - class => 'ticket-info-basics' &> - <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &> - + + + - + - -
+% $m->callback( %ARGS, CallbackName => 'LeftColumnTop' ); + + <&| /Widgets/TitleBox, title => loc('The Basics'), + title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id, + class => 'ticket-info-basics', + &> + <& /Ticket/Elements/ShowBasics, Ticket => $Ticket &> + % if ($Ticket->CustomFields->First) { - <&| /Widgets/TitleBox, title => loc('Custom Fields'), - title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id, - class => 'ticket-info-cfs' &> - <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &> - + <&| /Widgets/TitleBox, title => loc('Custom Fields'), + title_href => RT->Config->Get('WebPath')."/Ticket/Modify.html?id=".$Ticket->Id, + class => 'ticket-info-cfs', + &> + <& /Ticket/Elements/ShowCustomFields, Ticket => $Ticket &> + % } - <&| /Widgets/TitleBox, title => loc('People'), - title_href => RT->Config->Get('WebPath')."/Ticket/ModifyPeople.html?id=".$Ticket->Id, - class => 'ticket-info-people' &> - <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &> - - <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &> + <&| /Widgets/TitleBox, title => loc('People'), + title_href => RT->Config->Get('WebPath')."/Ticket/ModifyPeople.html?id=".$Ticket->Id, + class => 'ticket-info-people', + &> + <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &> + + + <& /Ticket/Elements/ShowAttachments, Ticket => $Ticket, Attachments => $Attachments &> - <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &> + <& /Ticket/Elements/ShowRequestor, Ticket => $Ticket &> % $m->callback( %ARGS, CallbackName => 'LeftColumn' ); - + + + +% $m->callback( %ARGS, CallbackName => 'RightColumnTop' ); + % if ( RT->Config->Get('EnableReminders') ) { - <&|/Widgets/TitleBox, title => loc("Reminders"), - title_href => RT->Config->Get('WebPath')."/Ticket/Reminders.html?id=".$Ticket->Id, - class => 'ticket-info-reminders' &> - - -
+ <&|/Widgets/TitleBox, title => loc("Reminders"), + title_href => RT->Config->Get('WebPath')."/Ticket/Reminders.html?id=".$Ticket->Id, + class => 'ticket-info-reminders', + &> + - -
- <& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 0 &> -
+ <& /Ticket/Elements/Reminders, Ticket => $Ticket, ShowCompleted => 0 &> +
-
- +
+ % } - <&| /Widgets/TitleBox, title => loc("Dates"), - title_href => RT->Config->Get('WebPath')."/Ticket/ModifyDates.html?id=".$Ticket->Id, - class => 'ticket-info-dates' &> - <& /Ticket/Elements/ShowDates, Ticket => $Ticket &> - + + <&| /Widgets/TitleBox, title => loc("Dates"), + title_href => RT->Config->Get('WebPath')."/Ticket/ModifyDates.html?id=".$Ticket->Id, + class => 'ticket-info-dates', + &> + <& /Ticket/Elements/ShowDates, Ticket => $Ticket &> + + % my (@extra); % push @extra, titleright_raw => ''.loc('Graph').'' unless RT->Config->Get('DisableGraphViz'); - <&| /Widgets/TitleBox, title => loc('Links'), - title_href => RT->Config->Get('WebPath')."/Ticket/ModifyLinks.html?id=".$Ticket->Id, - class => 'ticket-info-links', @extra &> - <& /Elements/ShowLinks, Ticket => $Ticket &> - + <&| /Widgets/TitleBox, title => loc('Links'), + title_href => RT->Config->Get('WebPath')."/Ticket/ModifyLinks.html?id=".$Ticket->Id, + class => 'ticket-info-links', + @extra, + &> + <& /Elements/ShowLinks, Ticket => $Ticket &> + + % $m->callback( %ARGS, CallbackName => 'RightColumn' ); -
+
<%ARGS> $Ticket => undef $Attachments => undef - - - - diff --git a/rt/share/html/Ticket/Elements/ShowTransaction b/rt/share/html/Ticket/Elements/ShowTransaction index a533323a9..6ccbb0c89 100755 --- a/rt/share/html/Ticket/Elements/ShowTransaction +++ b/rt/share/html/Ticket/Elements/ShowTransaction @@ -55,11 +55,13 @@ # <% $LastTransaction ? '' : ''|n %> +% $m->callback( Transaction => $Transaction, %ARGS, CallbackName => 'AfterAnchor' ); <% $transdate|n %> % my $desc = $Transaction->BriefDescription; % $m->callback( text => \$desc, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyDisplay' ); <& /Elements/ShowUser, User => $Transaction->CreatorObj &> - <% $TicketString %> <% $desc %> +% $m->callback( Transaction => $Transaction, %ARGS, CallbackName => 'AfterDescription' ); % $m->callback( TimeTaken => \$TimeTaken, Transaction => $Transaction, %ARGS, CallbackName => 'ModifyTimeTaken' ); <% $TimeTaken %> diff --git a/rt/share/html/Ticket/Elements/ShowTransactionAttachments b/rt/share/html/Ticket/Elements/ShowTransactionAttachments index 9c40b28da..a8cdfc11c 100644 --- a/rt/share/html/Ticket/Elements/ShowTransactionAttachments +++ b/rt/share/html/Ticket/Elements/ShowTransactionAttachments @@ -67,7 +67,10 @@ foreach my $message ( grep $_->__Value('Parent') == $Parent, @$Attachments ) { % if ( $DownloadableHeaders && !$message->Filename && $message->ContentType =~ /text/ ) { / <% loc('with headers') %> % } -
+ +% $m->callback(CallbackName => 'AfterDownloadLinks', ARGSRef => \%ARGS, Ticket => $Ticket, Transaction => $Transaction, Attachment => $message); + +
<% $message->ContentType %> <% $size_to_str->( $size ) %>
% } @@ -76,7 +79,7 @@ foreach my $message ( grep $_->__Value('Parent') == $Parent, @$Attachments ) { % if ( scalar ( grep $_->__Value('Parent') == $message->id, @$Attachments ) ) {
% } else { -
+
% } <%PERL> diff --git a/rt/share/html/Ticket/Elements/Tabs b/rt/share/html/Ticket/Elements/Tabs index 7deb8c18d..a9e697a9f 100755 --- a/rt/share/html/Ticket/Elements/Tabs +++ b/rt/share/html/Ticket/Elements/Tabs @@ -75,11 +75,13 @@ if ($Ticket) { # Don't display prev links if we're on the first ticket if ( $item_map->{ $Ticket->Id }->{prev} ) { - $searchtabs->{'_a'} = { - class => "nav", - path => "Ticket/Display.html?id=" . $item_map->{first}, - title => '<< ' . loc('First') - }; + if ( $item_map->{first} ) { + $searchtabs->{'_a'} = { + class => "nav", + path => "Ticket/Display.html?id=" . $item_map->{first}, + title => '<< ' . loc('First') + }; + } $searchtabs->{"_b"} = { class => "nav", path => "Ticket/Display.html?id=" @@ -96,11 +98,13 @@ if ($Ticket) { . $item_map->{ $Ticket->Id }->{next}, title => loc('Next') . ' >' }; - $searchtabs->{'e'} = { - class => "nav", - path => "Ticket/Display.html?id=" . $item_map->{last}, - title => loc('Last') . ' >>' - }; + if ( $item_map->{last} ) { + $searchtabs->{'e'} = { + class => "nav", + path => "Ticket/Display.html?id=" . $item_map->{last}, + title => loc('Last') . ' >>' + }; + } } } diff --git a/rt/share/html/Ticket/Elements/UpdateCc b/rt/share/html/Ticket/Elements/UpdateCc index 2538c82df..2559e5652 100644 --- a/rt/share/html/Ticket/Elements/UpdateCc +++ b/rt/share/html/Ticket/Elements/UpdateCc @@ -49,24 +49,32 @@
-%foreach my $addr ( keys %txn_addresses) { -% next if ( grep {$addr eq $_} @req_addresses ); +%if (scalar @one_time_Ccs) { +(<&|/l&>check to add) +%} +%foreach my $addr ( @one_time_Ccs ) { format; +% $clean_addr =~ s/'/\\'/g; + onClick="checkboxToInput('UpdateCc', 'UpdateCc-<%$addr%>','<%$clean_addr%>' ); $(UpdateIgnoreAddressCheckboxes).value=1" <% $ARGS{'UpdateCc-'.$addr} ? 'checked="checked"' : ''%> > <& /Elements/ShowUser, Address => $txn_addresses{$addr}&> %} <&|/l&>One-time Bcc:<& /Elements/EmailInput, Name => 'UpdateBcc', Size => '60', Default => $ARGS{UpdateBcc} &>
-%foreach my $addr ( keys %txn_addresses) { -% next if ( grep {$addr eq $_} @req_addresses ); +%if (scalar @one_time_Ccs) { +(<&|/l&>check to add) +%} +%foreach my $addr ( @one_time_Ccs ) { format; +% $clean_addr =~ s/'/\\'/g; + onClick="checkboxToInput('UpdateBcc', 'UpdateBcc-<%$addr%>','<%$clean_addr%>' ); $(UpdateIgnoreAddressCheckboxes).value=1" <% $ARGS{'UpdateBcc-'.$addr} ? 'checked="checked"' : ''%>> <& /Elements/ShowUser, Address => $txn_addresses{$addr}&> %} @@ -77,4 +85,10 @@ $TicketObj <%init> my %txn_addresses = %{$TicketObj->TransactionAddresses}; my @req_addresses = split /,/, $TicketObj->RequestorAddresses; +my @one_time_Ccs; + +foreach my $addr ( keys %txn_addresses) { + next if ( grep {$addr eq $_} @req_addresses ); + push @one_time_Ccs,$addr; +} diff --git a/rt/share/html/Ticket/ModifyAll.html b/rt/share/html/Ticket/ModifyAll.html index 762870099..41eda1b97 100755 --- a/rt/share/html/Ticket/ModifyAll.html +++ b/rt/share/html/Ticket/ModifyAll.html @@ -97,6 +97,7 @@ % } +% $m->callback( %ARGS, CallbackName => 'AfterUpdateType' ); @@ -133,8 +134,13 @@ <&|/l&>Content: - <& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &> - + +% if (exists $ARGS{UpdateContent}) { + <& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, IncludeSignature => 0 &> +% } else { + <& /Elements/MessageBox, Name=>"UpdateContent", QuoteTransaction=>$ARGS{QuoteTransaction} &> +% } + diff --git a/rt/share/html/Ticket/ModifyDates.html b/rt/share/html/Ticket/ModifyDates.html index 69bfde8ef..22bac10cb 100755 --- a/rt/share/html/Ticket/ModifyDates.html +++ b/rt/share/html/Ticket/ModifyDates.html @@ -69,6 +69,7 @@ my $TicketObj = LoadTicket($id); $m->callback( TicketObj => $TicketObj, ARGSRef => \%ARGS ); my @results = ProcessTicketDates( TicketObj => $TicketObj, ARGSRef => \%ARGS); +push @results, ProcessObjectCustomFieldUpdates(Object => $TicketObj, ARGSRef => \%ARGS); $TicketObj->ApplyTransactionBatch; diff --git a/rt/share/html/Ticket/Update.html b/rt/share/html/Ticket/Update.html index d3c2a09c4..f5cdddea8 100755 --- a/rt/share/html/Ticket/Update.html +++ b/rt/share/html/Ticket/Update.html @@ -55,7 +55,7 @@
-% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS, Ticket => $TicketObj ); +% $m->callback( CallbackName => 'FormStart', ARGSRef => \%ARGS, Ticket => $TicketObj, CanRespond => $CanRespond, CanComment => $CanComment, ResponseDefault => $ResponseDefault, CommentDefault => $CommentDefault ); @@ -97,8 +97,11 @@ % } +% $m->callback( %ARGS, CallbackName => 'AfterUpdateType' ); + +<&|/l&>Subject: +% $m->callback( %ARGS, CallbackName => 'AfterSubject' ); -<&|/l&>Subject: <& /Ticket/Elements/UpdateCc, %ARGS, TicketObj => $TicketObj &> @@ -126,6 +129,7 @@ &> % } +% $m->callback( %ARGS, CallbackName => 'AfterGnuPG' ); <&|/l&>Message: % $m->callback( %ARGS, CallbackName => 'BeforeMessageBox' ); @@ -136,7 +140,9 @@ <& /Elements/MessageBox, Name=>"UpdateContent", Default=>$ARGS{UpdateContent}, IncludeSignature => 0, %ARGS&> % $ARGS{'QuoteTransaction'} = $temp; % } else { -<& /Elements/MessageBox, Name=>"UpdateContent", %ARGS &> +% my $IncludeSignature = 1; +% $IncludeSignature = 0 if $Action ne 'Respond' && !RT->Config->Get('MessageBoxIncludeSignatureOnComment'); +<& /Elements/MessageBox, Name=>"UpdateContent", IncludeSignature => $IncludeSignature, %ARGS &> % } @@ -256,6 +262,22 @@ if ( $ARGS{'SubmitTicket'} ) { $checks_failure = 1 unless $status; } +# check email addresses for RT's +{ + foreach my $field ( qw(UpdateCc UpdateBcc) ) { + my $value = $ARGS{ $field }; + next unless defined $value && length $value; + + my @emails = Email::Address->parse( $value ); + foreach my $email ( grep RT::EmailParser->IsRTAddress($_->address), @emails ) { + push @results, loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $email->format, loc(substr($field, 6)) ); + $checks_failure = 1; + $email = undef; + } + $ARGS{ $field } = join ', ', map $_->format, grep defined, @emails; + } +} + if ( !$checks_failure && exists $ARGS{SubmitTicket} ) { $m->callback( Ticket => $TicketObj, ARGSRef => \%ARGS, CallbackName => 'BeforeDisplay' ); return $m->comp('Display.html', TicketObj => $TicketObj, %ARGS); diff --git a/rt/share/html/Tools/Reports/CreatedByDates.html b/rt/share/html/Tools/Reports/CreatedByDates.html index 9ca69557e..ce075970b 100644 --- a/rt/share/html/Tools/Reports/CreatedByDates.html +++ b/rt/share/html/Tools/Reports/CreatedByDates.html @@ -76,8 +76,8 @@ $q->LoadByCols(Name => $Queue); % if ($Queue|| $CreatedBefore ||$CreatedAfter) { % # if we have a queue, do the search % if ($Queue) { $query .= " AND Queue = '$Queue'"} -% if ($CreatedBefore) { $query .= " AND Created < '".$before->ISO."'"; } -% if ($CreatedAfter) { $query .= " AND Created > '".$after->ISO."'"} +% if ($CreatedBefore) { $query .= " AND Created < '".$before->ISO(Timezone => 'user') ."'"; } +% if ($CreatedAfter) { $query .= " AND Created > '".$after->ISO(Timezone => 'user')."'"} % my $groupby = 'Status'; <& /Search/Elements/Chart, Query => $query, PrimaryGroupBy => $groupby &> % } @@ -86,9 +86,9 @@ $q->LoadByCols(Name => $Queue);
<&|/l&>Queue: <& /Elements/SelectQueue, Name => 'Queue', NamedValues => 1, Default => $q->id &>
<&|/l&>Tickets created after: -<& /Elements/SelectDate, Name => 'CreatedAfter', Default => ($CreatedAfter) ? $after->ISO : ''&> +<& /Elements/SelectDate, Name => 'CreatedAfter', Default => ($CreatedAfter) ? $after->ISO(Timezone => 'user') : ''&>
<&|/l&>Tickets created before: -<& /Elements/SelectDate, Name => 'CreatedBefore', Default => ($CreatedBefore) ? $before->ISO : ''&> +<& /Elements/SelectDate, Name => 'CreatedBefore', Default => ($CreatedBefore) ? $before->ISO(Timezone => 'user') : ''&> <& /Elements/Submit&>
diff --git a/rt/share/html/Tools/Reports/ResolvedByDates.html b/rt/share/html/Tools/Reports/ResolvedByDates.html index 455eaedd2..48a952682 100644 --- a/rt/share/html/Tools/Reports/ResolvedByDates.html +++ b/rt/share/html/Tools/Reports/ResolvedByDates.html @@ -77,8 +77,8 @@ $q->LoadByCols(Name => $Queue); % # if we have a queue, do the search % $query = "Status = 'resolved'"; % if ($Queue) { $query .= " AND Queue = '$Queue'"} -% if ($ResolvedBefore) { $query .= " AND Resolved < '".$before->ISO."'"; } -% if ($ResolvedAfter) { $query .= " AND Resolved > '".$after->ISO."'"} +% if ($ResolvedBefore) { $query .= " AND Resolved < '".$before->ISO(Timezone => 'user')."'"; } +% if ($ResolvedAfter) { $query .= " AND Resolved > '".$after->ISO(Timezone => 'user')."'"} % my $groupby = 'Owner'; <& /Search/Elements/Chart, Query => $query, PrimaryGroupBy => $groupby &> % } @@ -87,9 +87,9 @@ $q->LoadByCols(Name => $Queue);
<&|/l&>Queue: <& /Elements/SelectQueue, Name => 'Queue', NamedValues => 1, Default => $q->id &>
<&|/l&>Tickets resolved after: -<& /Elements/SelectDate, Name => 'ResolvedAfter', Default => ($ResolvedAfter) ? $after->ISO : ''&> +<& /Elements/SelectDate, Name => 'ResolvedAfter', Default => ($ResolvedAfter) ? $after->ISO(Timezone => 'user') : ''&>
<&|/l&>Tickets resolved before: -<& /Elements/SelectDate, Name => 'ResolvedBefore', Default => ($ResolvedBefore) ? $before->ISO : ''&> +<& /Elements/SelectDate, Name => 'ResolvedBefore', Default => ($ResolvedBefore) ? $before->ISO(Timezone => 'user') : ''&> <& /Elements/Submit&> diff --git a/rt/share/html/User/Elements/Tabs b/rt/share/html/User/Elements/Tabs index 48cf1808b..7f9aca4dd 100755 --- a/rt/share/html/User/Elements/Tabs +++ b/rt/share/html/User/Elements/Tabs @@ -52,41 +52,43 @@ Title => $Title &> <%INIT> - my $tabs = { - - a => { title => loc('Settings'), - path => 'Prefs/Other.html', - }, - - b => { title => loc('About me'), - path => 'User/Prefs.html', - }, - g => { title => loc('Personal Groups'), - path => 'User/Groups/', - }, - h => { title => loc('Delegation'), - path => 'User/Delegation.html', - }, - f => { title => loc('Search options'), - path => 'Prefs/SearchOptions.html', - }, - r => { title => loc('RT at a glance'), - path => 'Prefs/MyRT.html', - }, - }; +my $tabs = { + a => { + title => loc('Settings'), + path => 'Prefs/Other.html', + }, + b => { + title => loc('About me'), + path => 'User/Prefs.html', + }, + g => { + title => loc('Personal Groups'), + path => 'User/Groups/', + }, + h => { + title => loc('Delegation'), + path => 'User/Delegation.html', + }, + f => { + title => loc('Search options'), + path => 'Prefs/SearchOptions.html', + }, + r => { + title => loc('RT at a glance'), + path => 'Prefs/MyRT.html', + }, +}; - # Now let callbacks add their extra tabs - $m->callback( %ARGS, tabs => $tabs ); - - foreach my $tab (sort keys %{$tabs}) { - if ($tabs->{$tab}->{'path'} eq $current_tab) { - $tabs->{$tab}->{"subtabs"} = $subtabs; - $tabs->{$tab}->{"current_subtab"} = $current_subtab; - } - } - +# Now let callbacks add their extra tabs +$m->callback( %ARGS, tabs => $tabs ); +foreach my $tab (values %$tabs) { + next unless $tab->{'path'} eq $current_tab; + $tab->{"subtabs"} = $subtabs; + $tab->{"current_subtab"} = $current_subtab; +} + <%ARGS> $subtabs => undef $current_tab => undef diff --git a/rt/share/html/User/Prefs.html b/rt/share/html/User/Prefs.html index f52fdcbdf..884cf85e4 100755 --- a/rt/share/html/User/Prefs.html +++ b/rt/share/html/User/Prefs.html @@ -107,27 +107,13 @@ % $m->callback( %ARGS, UserObj => $UserObj, CallbackName => 'FormLeftColumn' ); -% unless (RT->Config->Get('WebExternalAuth') and !RT->Config->Get('WebFallbackToInternalAuth')) { + <&| /Widgets/TitleBox, title => loc('Password'), id => "user-prefs-password" &> - - - - - - - - -
-<&|/l&>New Password: - - -
-<&|/l&>Retype Password: - - -
+<& /Elements/EditPassword, + User => $UserObj, + Name => [qw(CurrentPass Pass1 Pass2)], +&> -% } <&| /Widgets/TitleBox, title => loc('Location'), id => "user-prefs-location" &> @@ -221,6 +207,7 @@ unless ( $UserObj->id ) { if $Name; Abort(loc("Couldn't load user")); } +$id = $UserObj->id; my @results; @@ -259,13 +246,14 @@ if ( $SetPrivileged and $Privileged != $UserObj->Privileged ) { push @results, loc('Privileged status: [_1]', loc_fuzzy($msg)); } -#TODO: make this report errors properly -if ( defined $Pass1 and length $Pass1 and $Pass1 eq $Pass2 and !$UserObj->IsPassword($Pass1) ) { - my ($code, $msg); - ($code, $msg) = $UserObj->SetPassword($Pass1); - push @results, loc('Password: [_1]', loc_fuzzy($msg)); -} elsif ( defined $Pass1 && length $Pass1 && $Pass1 ne $Pass2 ) { - push @results, loc("Passwords do not match. Your password has not been changed"); +my %password_cond = $UserObj->CurrentUserRequireToSetPassword; +if (defined $Pass1 && length $Pass1 ) { + my ($status, $msg) = $UserObj->SafeSetPassword( + Current => $CurrentPass, + New => $Pass1, + Confirmation => $Pass2, + ); + push @results, loc("Password: [_1]", $msg); } if ( $ARGS{'ResetAuthToken'} ) { @@ -308,7 +296,8 @@ $City => undef $State => undef $Zip => undef $Country => undef +$CurrentPass => undef $Pass1 => undef -$Pass2=> undef +$Pass2 => undef $Create=> undef diff --git a/rt/share/html/Widgets/Form/Select b/rt/share/html/Widgets/Form/Select index e77861740..4587f1d58 100644 --- a/rt/share/html/Widgets/Form/Select +++ b/rt/share/html/Widgets/Form/Select @@ -117,7 +117,10 @@ if ( $ValuesCallback ) { } } unless (defined $DefaultLabel ) { - $DefaultLabel = loc('Use system default ([_1])', join ', ', map{ loc($ValuesLabel{$_} || $_) } @DefaultValue); + $DefaultLabel = loc('Use system default ([_1])', + join ', ', map loc($ValuesLabel{$_} || $_), grep defined, + @DefaultValue + ); } -- cgit v1.2.1