[Rt-commit] rt branch, timezones_in_charts, created. rt-3.8.7-307-ge5e4b61

Ruslan Zakirov ruz at bestpractical.com
Tue Mar 30 13:30:41 EDT 2010


The branch, timezones_in_charts has been created
        at  e5e4b610bb4428980c36aa7bf0ea94458c4beac5 (commit)

- Log -----------------------------------------------------------------
commit a2ff1fe108a829a16ec8803097663606849667af
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Mar 26 16:22:45 2010 +0800

    make x_labes vertical if no enough space

diff --git a/share/html/Search/Chart b/share/html/Search/Chart
index 793c7ad..19bd310 100644
--- a/share/html/Search/Chart
+++ b/share/html/Search/Chart
@@ -81,6 +81,7 @@ my $class = $class{ $PrimaryGroupBy };
 
 my %data;
 my $max_value = 0;
+my $max_key_length = 0;
 while ( my $entry = $tix->Next ) {
     my $key;
     if ( $class ) {
@@ -101,6 +102,7 @@ while ( my $entry = $tix->Next ) {
     }
     $data{ $key } = $value;
     $max_value = $value if $max_value < $value;
+    $max_key_length = length $key if $max_key_length < length $key;
 }
 
 # XXX: Convert 1970-01-01 date to the 'Not Set'
@@ -167,6 +169,8 @@ if ($chart_class eq "GD::Graph::bars") {
         values_space => -1,
 # the following line to make sure there's enough space for values to show
         y_max_value => 5*(int($max_value/5) + 1),
+# if there're too many bars or at least one key is too long, use vertical
+        x_labels_vertical => ( keys(%data) * $max_key_length > 60 ) ? 1 : 0,
     );
 }
 

commit 9bc63f712a807009775298fb0374ebd94e2632c5
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Feb 16 21:01:33 2010 +0300

    use IsRTAddress on Create/Update

diff --git a/share/html/Ticket/Create.html b/share/html/Ticket/Create.html
index eeff899..2c8e357 100755
--- a/share/html/Ticket/Create.html
+++ b/share/html/Ticket/Create.html
@@ -396,15 +396,12 @@ if ( !exists $ARGS{'AddMoreAttach'} && ($ARGS{'id'}||'') eq 'new' ) {
 
 # check email addresses for RT's
 {
-    my $address_re = RT->Config->Get('RTAddressRegexp');
     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 ( @emails ) {
-            next unless $email->address =~ $address_re;
-
+        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;
diff --git a/share/html/Ticket/Update.html b/share/html/Ticket/Update.html
index 9bce7de..18f8d60 100755
--- a/share/html/Ticket/Update.html
+++ b/share/html/Ticket/Update.html
@@ -264,15 +264,12 @@ if ( $ARGS{'SubmitTicket'} ) {
 
 # check email addresses for RT's
 {
-    my $address_re = RT->Config->Get('RTAddressRegexp');
     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 ( @emails ) {
-            next unless $email->address =~ $address_re;
-
+        foreach my $email ( grep RT::EmailAddress->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;

commit d27eef5a57b2d6abba96da6f93d6cbddd4e8d24b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Feb 16 21:04:29 2010 +0300

    don't generate lame regexp for RTAddressRegexp

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index 2604a24..cc4b1c1 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -333,6 +333,21 @@ our %META = (
         },
     },
 
+    RTAddressRegexp => {
+        Type    => 'SCALAR',
+        PostLoadCheck => sub {
+            my $self = shift;
+            my $value = $self->Get('RTAddressRegexp');
+            return if $value;
+
+            $RT::Logger->error(
+                'RTAddressRegexp option is not set in the config.'
+                .' Not setting this option result in additional SQL queries to check'
+                .' every address if it belongs to RT or not. These checks are'
+                .' required to avoid mail loops and other consequences.'
+            );
+        },
+    },
     # User overridable mail options
     EmailFrequency => {
         Section         => 'Mail',                                     #loc
@@ -829,9 +844,9 @@ sub SetFromConfig {
 
             # get entry for type we are looking for
             # XXX skip references to scalars or other references.
-            # Otherwise 5.10 goes boom. maybe we should skip any
+            # Otherwie 5.10 goes boom. may be we should skip any
             # reference
-            next if ref($entry) eq 'SCALAR' || ref($entry) eq 'REF';
+            return if ref($entry) eq 'SCALAR' || ref($entry) eq 'REF';
             my $entry_ref = *{$entry}{ ref($ref) };
             next unless $entry_ref;
 

commit dde3b3afc146f056693d81dcc6b426c9a6038a75
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Feb 16 21:06:29 2010 +0300

    if RT address regexp is not set then load queues for check

diff --git a/lib/RT/EmailParser.pm b/lib/RT/EmailParser.pm
index 7890f49..88041fe 100755
--- a/lib/RT/EmailParser.pm
+++ b/lib/RT/EmailParser.pm
@@ -333,12 +333,18 @@ sub IsRTAddress {
     my $self = shift;
     my $address = shift;
 
-    # Example: the following rule would tell RT not to Cc 
-    #   "tickets at noc.example.com"
-    my $address_re = RT->Config->Get('RTAddressRegexp');
-    if ( defined $address_re && $address =~ /$address_re/i ) {
-        return 1;
+    if ( my $address_re = RT->Config->Get('RTAddressRegexp') ) {
+        return $address =~ /$address_re/i ? 1 : undef;
     }
+
+    # we don't warn here, but do in config check
+    my $queue = RT::Queue->new( $RT::SystemUser );
+    $queue->LoadByCols( CorrespondAddress => $address );
+    return 1 if $queue->id;
+
+    $queue->LoadByCols( CommentAddress => $address );
+    return 1 if $queue->id;
+
     return undef;
 }
 

commit c70db9a9288d90ca73c7c78b0e30d558c17eea8f
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Feb 16 21:11:10 2010 +0300

    match against global Comment/Correspond addresses

diff --git a/lib/RT/EmailParser.pm b/lib/RT/EmailParser.pm
index 88041fe..5445080 100755
--- a/lib/RT/EmailParser.pm
+++ b/lib/RT/EmailParser.pm
@@ -338,6 +338,13 @@ sub IsRTAddress {
     }
 
     # we don't warn here, but do in config check
+    if ( my $global_address = RT->Config->Get('CorrespondAddress') ) {
+        return 1 if lc $global_address eq lc $address;
+    }
+    if ( my $global_address = RT->Config->Get('CommentAddress') ) {
+        return 1 if lc $global_address eq lc $address;
+    }
+
     my $queue = RT::Queue->new( $RT::SystemUser );
     $queue->LoadByCols( CorrespondAddress => $address );
     return 1 if $queue->id;
@@ -349,8 +356,6 @@ sub IsRTAddress {
 }
 
 
-
-
 =head2 CullRTAddresses ARRAY
 
 Takes a single argument, an array of email addresses.

commit f58ed809f160baddae260ae5f7d89f6e9a5013a6
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Feb 16 21:13:30 2010 +0300

    change every usage of the IsRTAddress function

diff --git a/lib/RT/Attachment_Overlay.pm b/lib/RT/Attachment_Overlay.pm
index e709814..e2707a7 100644
--- a/lib/RT/Attachment_Overlay.pm
+++ b/lib/RT/Attachment_Overlay.pm
@@ -447,24 +447,20 @@ sub Addresses {
 
     my %data = ();
     my $current_user_address = lc $self->CurrentUser->EmailAddress;
-    my $correspond = lc $self->TransactionObj->TicketObj->QueueObj->CorrespondAddress;
-    my $comment = lc $self->TransactionObj->TicketObj->QueueObj->CommentAddress;
     foreach my $hdr (qw(From To Cc Bcc RT-Send-Cc RT-Send-Bcc)) {
         my @Addresses;
-        my $line      = $self->GetHeader($hdr);
+        my $line = $self->GetHeader($hdr);
         
         foreach my $AddrObj ( Email::Address->parse( $line )) {
             my $address = $AddrObj->address;
             $address = lc RT::User->CanonicalizeEmailAddress($address);
-            next if ( $current_user_address eq $address );
-            next if ( $comment              eq $address );
-            next if ( $correspond           eq $address );
-            next if ( RT::EmailParser->IsRTAddress($address) );
+            next if $current_user_address eq $address;
+            next if RT::EmailParser->IsRTAddress($address);
             push @Addresses, $AddrObj ;
         }
-		$data{$hdr} = \@Addresses;
+        $data{$hdr} = \@Addresses;
     }
-	return \%data;
+    return \%data;
 }
 
 =head2 NiceHeaders
diff --git a/lib/RT/EmailParser.pm b/lib/RT/EmailParser.pm
index 5445080..036743f 100755
--- a/lib/RT/EmailParser.pm
+++ b/lib/RT/EmailParser.pm
@@ -289,9 +289,7 @@ email address and anything that the RT->Config->Get('RTAddressRegexp') matches.
 =cut
 
 sub ParseCcAddressesFromHead {
-
     my $self = shift;
-
     my %args = (
         QueueObj    => undef,
         CurrentUser => undef,
@@ -307,10 +305,8 @@ sub ParseCcAddressesFromHead {
         my $Address = $AddrObj->address;
         my $user = RT::User->new($RT::SystemUser);
         $Address = $user->CanonicalizeEmailAddress($Address);
-        next if ( lc $args{'CurrentUser'}->EmailAddress   eq lc $Address );
-        next if ( lc $args{'QueueObj'}->CorrespondAddress eq lc $Address );
-        next if ( lc $args{'QueueObj'}->CommentAddress    eq lc $Address );
-        next if ( $self->IsRTAddress($Address) );
+        next if lc $args{'CurrentUser'}->EmailAddress eq lc $Address;
+        next if $self->IsRTAddress($Address) );
 
         push ( @Addresses, $Address );
     }
@@ -318,8 +314,6 @@ sub ParseCcAddressesFromHead {
 }
 
 
-
-
 =head2 IsRTaddress ADDRESS
 
 Takes a single parameter, an email address. 
diff --git a/lib/RT/Interface/Email.pm b/lib/RT/Interface/Email.pm
index 6df907c..e0815fb 100755
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@ -978,22 +978,14 @@ sub ParseCcAddressesFromHead {
         @_
     );
 
-    my @recipients =
-        map lc $_->address,
+    my $current_address = lc $args{'CurrentUser'}->EmailAddress;
+    my $user = $args{'CurrentUser'}->UserObj;
+
+    return
+        grep $_ ne $current_address && !RT::EmailParser->IsRTAddress( $_ ),
+        map lc $user->CanonicalizeEmailAddress( $_->address ),
         map Email::Address->parse( $args{'Head'}->get( $_ ) ),
         qw(To Cc);
-
-    my @res;
-    foreach my $address ( @recipients ) {
-        $address = $args{'CurrentUser'}->UserObj->CanonicalizeEmailAddress( $address );
-        next if lc $args{'CurrentUser'}->EmailAddress   eq $address;
-        next if lc $args{'QueueObj'}->CorrespondAddress eq $address;
-        next if lc $args{'QueueObj'}->CommentAddress    eq $address;
-        next if RT::EmailParser->IsRTAddress( $address );
-
-        push @res, $address;
-    }
-    return @res;
 }
 
 

commit 2f11e5d2a96d5a099ae6ee2495c7f1e1f36b0857
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Tue Feb 16 22:26:58 2010 +0300

    adjust warning wording

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index cc4b1c1..f552b0c 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -343,8 +343,9 @@ our %META = (
             $RT::Logger->error(
                 'RTAddressRegexp option is not set in the config.'
                 .' Not setting this option result in additional SQL queries to check'
-                .' every address if it belongs to RT or not. These checks are'
-                .' required to avoid mail loops and other consequences.'
+                .' every address if it belongs to RT or not.'
+                .' Especially important to set this option if RT recieves'
+                .' emails on addresses that are not in DB or config.'
             );
         },
     },

commit e3ebff1df81860b0c8ed69730e03c9aa27ba886a
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Wed Feb 17 01:22:38 2010 +0300

    fix some mistakes

diff --git a/lib/RT/EmailParser.pm b/lib/RT/EmailParser.pm
index 036743f..63c7698 100755
--- a/lib/RT/EmailParser.pm
+++ b/lib/RT/EmailParser.pm
@@ -306,7 +306,7 @@ sub ParseCcAddressesFromHead {
         my $user = RT::User->new($RT::SystemUser);
         $Address = $user->CanonicalizeEmailAddress($Address);
         next if lc $args{'CurrentUser'}->EmailAddress eq lc $Address;
-        next if $self->IsRTAddress($Address) );
+        next if $self->IsRTAddress($Address);
 
         push ( @Addresses, $Address );
     }
@@ -332,11 +332,11 @@ sub IsRTAddress {
     }
 
     # we don't warn here, but do in config check
-    if ( my $global_address = RT->Config->Get('CorrespondAddress') ) {
-        return 1 if lc $global_address eq lc $address;
+    if ( my $correspond_address = RT->Config->Get('CorrespondAddress') ) {
+        return 1 if lc $correspond_address eq lc $address;
     }
-    if ( my $global_address = RT->Config->Get('CommentAddress') ) {
-        return 1 if lc $global_address eq lc $address;
+    if ( my $comment_address = RT->Config->Get('CommentAddress') ) {
+        return 1 if lc $comment_address eq lc $address;
     }
 
     my $queue = RT::Queue->new( $RT::SystemUser );

commit d175e86048879f70dbb2a5dbb43d38a5664819ab
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 18 22:24:49 2010 +0300

    don't allow to add RT addresses as watchers in API
    
    this covers Ticket/People page as well

diff --git a/lib/RT/Queue_Overlay.pm b/lib/RT/Queue_Overlay.pm
index 00d684c..98bdec5 100755
--- a/lib/RT/Queue_Overlay.pm
+++ b/lib/RT/Queue_Overlay.pm
@@ -789,8 +789,15 @@ sub _AddWatcher {
     my $principal = RT::Principal->new( $self->CurrentUser );
     if ( $args{'PrincipalId'} ) {
         $principal->Load( $args{'PrincipalId'} );
+        if ( $principal->id and $principal->IsUser and my $email = $principal->Object->EmailAddress ) {
+            return (0, $self->loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $email, $self->loc($args{'Type'})))
+                if RT::EmailParser->IsRTAddress( $email );
+        }
     }
     elsif ( $args{'Email'} ) {
+        if ( RT::EmailParser->IsRTAddress( $args{'Email'} ) ) {
+            return (0, $self->loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $args{'Email'}, $self->loc($args{'Type'})));
+        }
         my $user = RT::User->new($self->CurrentUser);
         $user->LoadByEmail( $args{'Email'} );
         $user->Load( $args{'Email'} )
diff --git a/lib/RT/Ticket_Overlay.pm b/lib/RT/Ticket_Overlay.pm
index c722590..186853e 100755
--- a/lib/RT/Ticket_Overlay.pm
+++ b/lib/RT/Ticket_Overlay.pm
@@ -1103,12 +1103,20 @@ sub _AddWatcher {
 
     my $principal = RT::Principal->new($self->CurrentUser);
     if ($args{'Email'}) {
+        if ( RT::EmailParser->IsRTAddress( $args{'Email'} ) ) {
+            return (0, $self->loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $args{'Email'}, $self->loc($args{'Type'})));
+        }
         my $user = RT::User->new($RT::SystemUser);
         my ($pid, $msg) = $user->LoadOrCreateByEmail( $args{'Email'} );
         $args{'PrincipalId'} = $pid if $pid; 
     }
     if ($args{'PrincipalId'}) {
         $principal->Load($args{'PrincipalId'});
+        if ( $principal->id and $principal->IsUser and my $email = $principal->Object->EmailAddress ) {
+            return (0, $self->loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $email, $self->loc($args{'Type'})))
+                if RT::EmailParser->IsRTAddress( $email );
+
+        }
     } 
 
  

commit a379f9daa08d45f76610b6a1c4bd3ce8130ae59b
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 18 22:39:53 2010 +0300

    warn admin if RTAddressRegexp is set, but queue's address doesn't match

diff --git a/share/html/Admin/Queues/Modify.html b/share/html/Admin/Queues/Modify.html
index df97a68..c6ffe17 100755
--- a/share/html/Admin/Queues/Modify.html
+++ b/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 );
+        }
+    }
 }
 </%INIT>
 

commit 30f45d6a8cc3836fe1bf45b4c01eaea97877ebe3
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 25 23:57:35 2010 +0300

    fix typo in class name

diff --git a/share/html/Ticket/Update.html b/share/html/Ticket/Update.html
index 18f8d60..f5cddde 100755
--- a/share/html/Ticket/Update.html
+++ b/share/html/Ticket/Update.html
@@ -269,7 +269,7 @@ if ( $ARGS{'SubmitTicket'} ) {
         next unless defined $value && length $value;
 
         my @emails = Email::Address->parse( $value );
-        foreach my $email ( grep RT::EmailAddress->IsRTAddress($_->address), @emails ) {
+        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;

commit 30bb2bb98f1fee182d2c7bf7261dbd5f2f3cd9c0
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Mar 25 17:35:39 2010 +0300

    test that merge only possible when user has Modify right on both tickets

diff --git a/t/ticket/merge.t b/t/ticket/merge.t
index a714cb6..7c72fe0 100644
--- a/t/ticket/merge.t
+++ b/t/ticket/merge.t
@@ -5,7 +5,7 @@ use warnings;
 
 
 use RT;
-use RT::Test tests => '17';
+use RT::Test tests => '29';
 
 
 # validate that when merging two tickets, the comments from both tickets
@@ -16,7 +16,10 @@ use RT::Test tests => '17';
     ok ($id,$msg);
 
     my $t1 = RT::Ticket->new($RT::SystemUser);
-    my ($tid,$transid, $t1msg) =$t1->Create ( Queue => $queue->Name, Subject => 'Merge test. orig');
+    my ($tid,$transid, $t1msg) =$t1->Create(
+        Queue => $queue->Name,
+        Subject => 'Merge test. orig',
+    );
     ok ($tid, $t1msg);
     ($id, $msg) = $t1->Comment(Content => 'This is a Comment on the original');
     ok($id,$msg);
@@ -90,3 +93,45 @@ use RT::Test tests => '17';
     ($id,$val) = $t->MergeInto($t2->id);
     ok($id,$val);
 }
+
+my $user = RT::Test->load_or_create_user(
+    Name => 'a user', Password => 'password',
+);
+ok $user && $user->id, 'loaded or created user';
+
+# check rights
+{
+    RT::Test->set_rights(
+        { Principal => 'Everyone', Right => [qw(SeeQueue ShowTicket CreateTicket OwnTicket TakeTicket)] },
+        { Principal => 'Owner',    Right => [qw(ModifyTicket)] },
+    );
+
+    my $t = RT::Ticket->new(RT::CurrentUser->new($user));
+    $t->Create(Subject => 'Main', Queue => 'general');
+    ok ($t->id, "Created ticket");
+
+    my $t2 = RT::Ticket->new(RT::CurrentUser->new($user));
+    $t2->Create(Subject => 'Second', Queue => 'general');
+    ok ($t2->id, "Created ticket");
+
+    foreach my $ticket ( $t, $t2 ) {
+        ok( !$ticket->CurrentUserHasRight('ModifyTicket'), "can not modify" );
+    }
+
+    my ($status,$msg) = $t->MergeInto($t2->id);
+    ok(!$status, "Can not merge: $msg");
+    
+    ($status, $msg) = $t->SetOwner( $user->id );
+    ok( $status, "User took ticket");
+    ok( $t->CurrentUserHasRight('ModifyTicket'), "can modify after take" );
+
+    ($status,$msg) = $t->MergeInto($t2->id);
+    ok(!$status, "Can not merge: $msg");
+
+    ($status, $msg) = $t2->SetOwner( $user->id );
+    ok( $status, "User took ticket");
+    ok( $t2->CurrentUserHasRight('ModifyTicket'), "can modify after take" );
+
+    ($status,$msg) = $t->MergeInto($t2->id);
+    ok($status, "Merged tickets: $msg");
+}

commit 1a39d6f96a221c2507319f932101c720a7a732c7
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Mar 25 19:00:42 2010 +0300

    LoadModules method in RT::Scrip class
    
    Thanks to Eynat Nir Mishor

diff --git a/lib/RT/Scrip_Overlay.pm b/lib/RT/Scrip_Overlay.pm
index 3310289..6c2cbd5 100755
--- a/lib/RT/Scrip_Overlay.pm
+++ b/lib/RT/Scrip_Overlay.pm
@@ -257,6 +257,19 @@ sub ConditionObj {
 
 # }}}
 
+=head2 LoadModules
+
+Loads scrip's condition and action modules.
+
+=cut
+
+sub LoadModules {
+    my $self = shift;
+
+    $self->ConditionObj->LoadCondition;
+    $self->ActionObj->LoadAction;
+}
+
 # {{{ sub TemplateObj
 
 =head2 TemplateObj

commit 0a95c85de9a3f45a57e6279e70bb175f5661cbaa
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Mar 26 17:01:59 2010 +0300

    drop default value of RTAddressRegexp option

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index e1d7917..24fdc4e 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -286,7 +286,7 @@ avoid sending mail to itself.  It will also hide RT addresses from the list of
 
 =cut
 
-Set($RTAddressRegexp , '^rt\@example.com$');
+Set($RTAddressRegexp , undef);
 
 =item C<$CanonicalizeEmailAddressMatch>, C<$CanonicalizeEmailAddressReplace>
 

commit 9e409174445910dac1ed1e512013c7bd68cfb139
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Mar 26 17:03:17 2010 +0300

    RT::I18N::LoadLexicons function that forces parsing and unties

diff --git a/lib/RT/I18N.pm b/lib/RT/I18N.pm
index aa13c67..2206b51 100755
--- a/lib/RT/I18N.pm
+++ b/lib/RT/I18N.pm
@@ -128,6 +128,22 @@ sub Init {
     return 1;
 }
 
+sub LoadLexicons {
+
+    no strict 'refs';
+    foreach my $k (keys %{RT::I18N::} ) {
+        next if $k eq 'main::';
+        next unless index($k, '::', -2) >= 0;
+        next unless exists ${ 'RT::I18N::'. $k }{'Lexicon'};
+
+        my $lex = *{ ${'RT::I18N::'. $k }{'Lexicon'} }{HASH};
+        # run fetch to force load
+        my $tmp = $lex->{'foo'};
+        # untie that has to lower fetch impact
+        untie %$lex if tied %$lex;
+    }
+}
+
 =head2 encoding
 
 Returns the encoding of the current lexicon, as yanked out of __ContentType's "charset" field.

commit 21f181dd3080fe145c223381b4d1438167c9be32
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Mar 26 17:04:40 2010 +0300

    Heavy argument in RT::InitClasses - load more if true
    
    * load scrips' modules
    * load custom fields' source classes
    * load all trnslations and parse them

diff --git a/lib/RT.pm.in b/lib/RT.pm.in
index 9ada958..1cf2443 100755
--- a/lib/RT.pm.in
+++ b/lib/RT.pm.in
@@ -425,6 +425,8 @@ Load all modules that define base classes.
 =cut
 
 sub InitClasses {
+    shift if @_%2; # so we can call it as a function or method
+    my %args = (@_);
     require RT::Tickets;
     require RT::Transactions;
     require RT::Attachments;
@@ -469,6 +471,25 @@ sub InitClasses {
         RT::ObjectCustomFieldValue
         RT::Attribute
     );
+
+    if ( $args{'Heavy'} ) {
+        # load scrips' modules
+        my $scrips = RT::Scrips->new($RT::SystemUser);
+        $scrips->Limit( FIELD => 'Stage', OPERATOR => '!=', VALUE => 'Disabled' );
+        while ( my $scrip = $scrips->Next ) {
+            $scrip->LoadModules;
+        }
+
+	foreach my $class ( grep $_, RT->Config->Get('CustomFieldValuesSources') ) {
+            local $@;
+            eval "require $class; 1" or $RT::Logger->error(
+                "Class '$class' is listed in CustomFieldValuesSources option"
+                ." in the config, but we failed to load it:\n$@\n"
+            );
+        }
+
+        RT::I18N->LoadLexicons;
+    }
 }
 
 =head2 InitSystemObjects

commit 1a79e58bad3b7cc4a91e16b7554c9474e18648dc
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Mar 26 17:20:02 2010 +0300

    use heavy load in forking web handlers

diff --git a/bin/fastcgi_server.in b/bin/fastcgi_server.in
index 522320c..a637144 100644
--- a/bin/fastcgi_server.in
+++ b/bin/fastcgi_server.in
@@ -195,6 +195,7 @@ if ( $opt{'help'} ) {
     );
 }
 
+$ENV{'RT_WEBMUX_HEAVY_LOAD'} = 1;
 use File::Basename;
 require (dirname(__FILE__) .'/webmux.pl');
 
diff --git a/bin/standalone_httpd.in b/bin/standalone_httpd.in
index b87a332..aa9204b 100755
--- a/bin/standalone_httpd.in
+++ b/bin/standalone_httpd.in
@@ -120,7 +120,7 @@ EOF
 } else {
     RT->ConnectToDatabase();
     RT->InitSystemObjects();
-    RT->InitClasses();
+    RT->InitClasses( Heavy => 1 );
     RT->InitPlugins();
     RT->Config->PostLoadCheck();
 
diff --git a/bin/webmux.pl.in b/bin/webmux.pl.in
index 1e62f52..50b959a 100755
--- a/bin/webmux.pl.in
+++ b/bin/webmux.pl.in
@@ -152,6 +152,9 @@ $RT::Mason::Handler = RT::Interface::Web::Handler->new(
     RT->Config->Get('MasonParameters')
 );
 
+# load more for mod_perl before forking
+RT::InitClasses( Heavy => 1 ) if $ENV{'MOD_PERL'} || $ENV{RT_WEBMUX_HEAVY_LOAD};
+
 # we must disconnect DB before fork
 $RT::Handle->dbh(undef);
 undef $RT::Handle;

commit ce37fc8ae3360140589b83c7274ae356ea5c6eb3
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Mar 26 17:57:41 2010 +0300

    properly apply entry aggregator on Content searches
    
    only when DontSearchFileAttachments option is
    enabled

diff --git a/lib/RT/Tickets_Overlay.pm b/lib/RT/Tickets_Overlay.pm
index 486d0cd..e8d350d 100755
--- a/lib/RT/Tickets_Overlay.pm
+++ b/lib/RT/Tickets_Overlay.pm
@@ -723,7 +723,7 @@ sub _TransLimit {
     # them all into the same subclause when you have (A op B op C) - the
     # way they get parsed in the tree they're in different subclauses.
 
-    my ( $self, $field, $op, $value, @rest ) = @_;
+    my ( $self, $field, $op, $value, %rest ) = @_;
 
     unless ( $self->{_sql_transalias} ) {
         $self->{_sql_transalias} = $self->Join(
@@ -749,41 +749,36 @@ sub _TransLimit {
         );
     }
 
-    $self->_OpenParen;
-
     #Search for the right field
     if ( $field eq 'Content' and RT->Config->Get('DontSearchFileAttachments') ) {
-       $self->_SQLLimit(
-			ALIAS         => $self->{_sql_trattachalias},
-			FIELD         => 'Filename',
-			OPERATOR      => 'IS',
-			VALUE         => 'NULL',
-			SUBCLAUSE     => 'contentquery',
-			ENTRYAGGREGATOR => 'AND',
-		       );
-       $self->_SQLLimit(
+        $self->_OpenParen;
+        $self->_SQLLimit(
+			%rest,
 			ALIAS         => $self->{_sql_trattachalias},
 			FIELD         => $field,
 			OPERATOR      => $op,
 			VALUE         => $value,
 			CASESENSITIVE => 0,
-			@rest,
+		       );
+        $self->_SQLLimit(
 			ENTRYAGGREGATOR => 'AND',
-			SUBCLAUSE     => 'contentquery',
+			ALIAS           => $self->{_sql_trattachalias},
+			FIELD           => 'Filename',
+			OPERATOR        => 'IS',
+			VALUE           => 'NULL',
 		       );
+        $self->_CloseParen;
     } else {
         $self->_SQLLimit(
+			%rest,
 			ALIAS         => $self->{_sql_trattachalias},
 			FIELD         => $field,
 			OPERATOR      => $op,
 			VALUE         => $value,
 			CASESENSITIVE => 0,
-			ENTRYAGGREGATOR => 'AND',
-			@rest
         );
     }
 
-    $self->_CloseParen;
 
 }
 

commit 9ec507e62ecea047bdbc9792f3274c248a2a2626
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Fri Mar 26 21:06:50 2010 +0300

    untie may fail

diff --git a/lib/RT/I18N.pm b/lib/RT/I18N.pm
index 2206b51..7f56886 100755
--- a/lib/RT/I18N.pm
+++ b/lib/RT/I18N.pm
@@ -139,8 +139,10 @@ sub LoadLexicons {
         my $lex = *{ ${'RT::I18N::'. $k }{'Lexicon'} }{HASH};
         # run fetch to force load
         my $tmp = $lex->{'foo'};
-        # untie that has to lower fetch impact
-        untie %$lex if tied %$lex;
+        # XXX: untie may fail with "untie attempted
+        # while 1 inner references still exist"
+        # TODO: untie that has to lower fetch impact
+        # untie %$lex if tied %$lex;
     }
 }
 
diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index a5ca328..b8d1683 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -225,6 +225,7 @@ Set( \$WebPort , $port);
 Set( \$WebBaseURL , "http://localhost:\$WebPort");
 Set( \$LogToSyslog , undef);
 Set( \$LogToScreen , "warning");
+Set( \$RTAddressRegexp , qr/^bad_re_that_doesnt_match\$/);
 Set( \$MailCommand, 'testfile');
 };
     if ( $ENV{'RT_TEST_DB_SID'} ) { # oracle case

commit f4b65d5140e9db5d30464bfad83ca00e546356ab
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Mon Mar 29 17:22:50 2010 +0800

    add DroidSans.ttf

diff --git a/share/fonts/DroidSans.ttf b/share/fonts/DroidSans.ttf
new file mode 100755
index 0000000..458ba59
Binary files /dev/null and b/share/fonts/DroidSans.ttf differ

commit 56e5da5ff661fba61a4e342e3442e12aaca4ddb1
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Mon Mar 29 17:24:00 2010 +0800

    change ChartFont config to a hash

diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in
index 24fdc4e..4ad1411 100755
--- a/etc/RT_Config.pm.in
+++ b/etc/RT_Config.pm.in
@@ -1453,7 +1453,7 @@ ticket searches.
 
 Set($DontSearchFileAttachments, undef);
 
-=item C<$ChartFont>
+=item C<%ChartFont>
 
 The L<GD> module (which RT uses for graphs) uses a builtin font that doesn't
 have full Unicode support. You can use a particular TrueType font by setting
@@ -1462,7 +1462,13 @@ support for TrueType fonts to use this option.
 
 =cut
 
-Set($ChartFont, "$RT::BasePath/share/fonts/DroidSansFallback.ttf");
+Set(
+    %ChartFont,
+    'zh-cn'  => "$RT::BasePath/share/fonts/DroidSansFallback.ttf",
+    'zh-tw'  => "$RT::BasePath/share/fonts/DroidSansFallback.ttf",
+    'ja'     => "$RT::BasePath/share/fonts/DroidSansFallback.ttf",
+    'others' => "$RT::BasePath/share/fonts/DroidSans.ttf",
+);
 
 =item C<@Active_MakeClicky>
 
diff --git a/share/html/Search/Chart b/share/html/Search/Chart
index 19bd310..06d634e 100644
--- a/share/html/Search/Chart
+++ b/share/html/Search/Chart
@@ -126,7 +126,9 @@ unless (keys %data) {
 
 my $chart = $chart_class->new( 600 => 400 );
 $chart->set( pie_height => 60 ) if $chart_class eq 'GD::Graph::pie';
-my $font = RT->Config->Get('ChartFont');
+my %font_config = RT->Config->Get('ChartFont');
+my $font = $font_config{ $session{CurrentUser}->UserObj->Lang || '' }
+  || $font_config{'others'};
 $chart->set_title_font( $font, 16 ) if $chart->can('set_title_font');
 $chart->set_legend_font( $font, 16 ) if $chart->can('set_legend_font');
 $chart->set_x_label_font( $font, 14 ) if $chart->can('set_x_label_font');

commit 4e084240816cd4865c0d5b179e8e2b803e868d5f
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Mon Mar 29 21:01:21 2010 +0800

    to install share/fonts

diff --git a/Makefile.in b/Makefile.in
index b96d8f3..898dc8a 100755
--- a/Makefile.in
+++ b/Makefile.in
@@ -106,6 +106,7 @@ RT_LIB_PATH		=	@RT_LIB_PATH_R@
 RT_MAN_PATH		=	@RT_MAN_PATH_R@
 RT_VAR_PATH		=	@RT_VAR_PATH_R@
 RT_DOC_PATH		=	@RT_DOC_PATH_R@
+RT_FONT_PATH		=	@RT_FONT_PATH_R@
 RT_LOCAL_PATH		=	@RT_LOCAL_PATH_R@
 LOCAL_PLUGIN_PATH	=	@RT_LOCAL_PATH_R@/plugins
 LOCAL_ETC_PATH		=	@LOCAL_ETC_PATH_R@
@@ -287,7 +288,7 @@ upgrade-instruct:
 
 upgrade: testdeps config-install dirs files-install fixperms upgrade-instruct
 
-upgrade-noclobber: config-install dirs libs-install html-install bin-install local-install doc-install fixperms
+upgrade-noclobber: config-install dirs libs-install html-install bin-install local-install doc-install font-install fixperms
 
 
 # {{{ dependencies
@@ -352,6 +353,7 @@ fixperms:
 # {{{ dirs
 dirs:
 	$(INSTALL) -m 0755 -d $(DESTDIR)$(RT_LOG_PATH)
+	$(INSTALL) -m 0755 -d $(DESTDIR)$(RT_FONT_PATH)
 	$(INSTALL) -m 0770 -d $(DESTDIR)$(MASON_DATA_PATH)
 	$(INSTALL) -m 0770 -d $(DESTDIR)$(MASON_DATA_PATH)/cache
 	$(INSTALL) -m 0770 -d $(DESTDIR)$(MASON_DATA_PATH)/etc
@@ -367,7 +369,7 @@ dirs:
 
 install: testdeps config-install dirs files-install fixperms instruct
 
-files-install: libs-install etc-install config-install bin-install sbin-install html-install local-install doc-install
+files-install: libs-install etc-install config-install bin-install sbin-install html-install local-install doc-install font-install
 
 config-install:
 @COMMENT_INPLACE_LAYOUT@	$(INSTALL) -m 0755 -o $(BIN_OWNER) -g $(RTGROUP) -d $(DESTDIR)$(CONFIG_FILE_PATH)
@@ -426,6 +428,14 @@ html-install:
 @COMMENT_INPLACE_LAYOUT@	done
 # }}}
 
+# {{{ font-install
+font-install:
+ at COMMENT_INPLACE_LAYOUT@	[ -d $(DESTDIR)$(RT_FONT_PATH) ] || $(INSTALL) -m 0755 -d $(DESTDIR)$(RT_FONT_PATH)
+ at COMMENT_INPLACE_LAYOUT@	-( cd share/fonts && find . -type f -print ) | while read file ; do \
+ at COMMENT_INPLACE_LAYOUT@	    $(INSTALL) -m 0644 "share/fonts/$$file" "$(DESTDIR)$(RT_FONT_PATH)/$$file" ; \
+ at COMMENT_INPLACE_LAYOUT@	done
+# }}}
+
 # {{{ doc-install
 doc-install:
 @COMMENT_INPLACE_LAYOUT@	# RT 3.0.0 - RT 3.0.2 would accidentally create a file instead of a dir
diff --git a/aclocal.m4 b/aclocal.m4
index 0e041b6..044af5a 100755
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -90,7 +90,7 @@ AC_DEFUN([RT_LAYOUT],[
 			. $pldconf
 			changequote({,})
 			for var in prefix exec_prefix bindir sbindir \
-				 sysconfdir mandir libdir datadir htmldir \
+				 sysconfdir mandir libdir datadir htmldir fontdir\
 				 localstatedir logfiledir masonstatedir \
 				 sessionstatedir customdir custometcdir customhtmldir \
 				 customlexdir customlibdir manualdir; do
@@ -115,6 +115,7 @@ AC_DEFUN([RT_LAYOUT],[
 	RT_SUBST_EXPANDED_ARG(libdir)
 	RT_SUBST_EXPANDED_ARG(datadir)
 	RT_SUBST_EXPANDED_ARG(htmldir)
+	RT_SUBST_EXPANDED_ARG(fontdir)
 	RT_SUBST_EXPANDED_ARG(manualdir)
 	RT_SUBST_EXPANDED_ARG(plugindir)
 	RT_SUBST_EXPANDED_ARG(localstatedir)
diff --git a/config.layout b/config.layout
index 52fcef1..87078a1 100755
--- a/config.layout
+++ b/config.layout
@@ -10,7 +10,7 @@
 ##
 ##  The following variables must _all_ be set:
 ##	prefix exec_prefix bindir sbindir sysconfdir mandir libdir
-##	datadir htmldir localstatedir logfiledir masonstatedir
+##	datadir htmldir localstatedir logfiledir masonstatedir fontdir
 ##	sessionstatedir customdir customhtmldir customlexdir
 ##  (This can be seen in m4/rt_layout.m4.)
 ##
@@ -27,6 +27,7 @@
   libdir:		${prefix}/lib
   datadir:		${prefix}/share
   htmldir:		${datadir}/html
+  fontdir:		${datadir}/fonts
   manualdir:		${datadir}/doc
   localstatedir:	${prefix}/var
   logfiledir:		${localstatedir}/log
@@ -49,6 +50,7 @@
   libdir:		${prefix}/lib
   datadir:		${prefix}/share
   htmldir:		${datadir}/html
+  fontdir:		${datadir}/fonts
   manualdir:		${datadir}/doc
   localstatedir:	${prefix}/var
   logfiledir:		${localstatedir}/log
@@ -74,6 +76,7 @@
 # FIXME: no such directory in FHS; shouldn't go to somewhere in "${datadir}/rt/"?
   plugindir:		${datadir}/plugins
   htmldir:		${datadir}/html
+  fontdir:		${datadir}/fonts
   manualdir:		${datadir}/doc
   localstatedir:	/var
   logfiledir:		${localstatedir}/log
@@ -98,6 +101,7 @@
   libdir:		${prefix}/lib+
   datadir:		${prefix}/share+
   htmldir:		${datadir}/html
+  fontdir:		${datadir}/fonts
   manualdir:		${prefix}/share/doc+
   logfiledir:		/var/log
   localstatedir:	/var/run+
@@ -121,6 +125,7 @@
   libdir:		${prefix}/lib
   datadir:		${prefix}
   htmldir:		${datadir}/html
+  fontdir:		${datadir}/fonts
   manualdir:		${datadir}/doc
   localstatedir:	${prefix}/var
   logfiledir:		${localstatedir}/log
@@ -144,6 +149,7 @@
   libdir:		${prefix}/lib/rt
   datadir:		/var/rt
   htmldir:		${datadir}/html
+  fontdir:		${datadir}/fonts
   manualdir:		${datadir}/doc
   plugindir:		${datadir}/plugins
   localstatedir:	/var
@@ -168,6 +174,7 @@
   libdir:		lib
   datadir:		share
   htmldir:		${datadir}/html
+  fontdir:		${datadir}/fonts
   manualdir:	${datadir}/doc
   localstatedir:	var
   logfiledir:		${localstatedir}/log
diff --git a/configure.ac b/configure.ac
index 37f0a6c..7e6d757 100755
--- a/configure.ac
+++ b/configure.ac
@@ -334,6 +334,7 @@ AC_SUBST([RT_BIN_PATH],			${exp_bindir})
 AC_SUBST([RT_SBIN_PATH],		${exp_sbindir})
 AC_SUBST([RT_VAR_PATH],			${exp_localstatedir})
 AC_SUBST([RT_MAN_PATH],			${exp_mandir})
+AC_SUBST([RT_FONT_PATH],			${exp_fontdir})
 AC_SUBST([RT_PLUGIN_PATH],			${exp_plugindir})
 AC_SUBST([MASON_DATA_PATH],		${exp_masonstatedir})
 AC_SUBST([MASON_SESSION_PATH],		${exp_sessionstatedir})
@@ -355,6 +356,7 @@ AC_SUBST([RT_BIN_PATH_R],			${exp_prefix}/${exp_bindir})
 AC_SUBST([RT_SBIN_PATH_R],		${exp_prefix}/${exp_sbindir})
 AC_SUBST([RT_VAR_PATH_R],			${exp_prefix}/${exp_localstatedir})
 AC_SUBST([RT_MAN_PATH_R],			${exp_prefix}/${exp_mandir})
+AC_SUBST([RT_FONT_PATH_R],			${exp_prefix}/${exp_fontdir})
 AC_SUBST([RT_PLUGIN_PATH_R],		${exp_prefix}/${exp_plugindir})
 AC_SUBST([MASON_DATA_PATH_R],		${exp_prefix}/${exp_masonstatedir})
 AC_SUBST([MASON_SESSION_PATH_R],		${exp_prefix}/${exp_sessionstatedir})
@@ -376,6 +378,7 @@ AC_SUBST([RT_BIN_PATH_R],			${exp_bindir})
 AC_SUBST([RT_SBIN_PATH_R],		${exp_sbindir})
 AC_SUBST([RT_VAR_PATH_R],			${exp_localstatedir})
 AC_SUBST([RT_MAN_PATH_R],			${exp_mandir})
+AC_SUBST([RT_FONT_PATH_R],			${exp_fontdir})
 AC_SUBST([MASON_DATA_PATH_R],		${exp_masonstatedir})
 AC_SUBST([MASON_SESSION_PATH_R],		${exp_sessionstatedir})
 AC_SUBST([MASON_HTML_PATH_R],		${exp_htmldir})
diff --git a/m4/rt_layout.m4 b/m4/rt_layout.m4
index fbb2890..bdc4b2c 100755
--- a/m4/rt_layout.m4
+++ b/m4/rt_layout.m4
@@ -37,7 +37,7 @@ AC_DEFUN([RT_LAYOUT],[
 			. $pldconf
 			changequote({,})
 			for var in prefix exec_prefix bindir sbindir \
-				 sysconfdir mandir libdir datadir htmldir \
+				 sysconfdir mandir libdir datadir htmldir fontdir \
 				 localstatedir logfiledir masonstatedir plugindir \
 				 sessionstatedir customdir custometcdir customhtmldir \
 				 customlexdir customlibdir manualdir; do
@@ -62,6 +62,7 @@ AC_DEFUN([RT_LAYOUT],[
 	RT_SUBST_EXPANDED_ARG(libdir)
 	RT_SUBST_EXPANDED_ARG(datadir)
 	RT_SUBST_EXPANDED_ARG(htmldir)
+	RT_SUBST_EXPANDED_ARG(fontdir)
 	RT_SUBST_EXPANDED_ARG(manualdir)
 	RT_SUBST_EXPANDED_ARG(plugindir)
 	RT_SUBST_EXPANDED_ARG(localstatedir)

commit 947714494f9cde79953defb22ce4ff35cdf1b9ac
Merge: 4e08424 ebe5485
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Mon Mar 29 18:57:44 2010 +0400

    Merge branch 'rt-address-regexp' into 3.8-trunk


commit da90b2fd5b22d2fe6ad22481ecc54b99fd546f1e
Author: Shawn M Moore <sartak at bestpractical.com>
Date:   Mon Mar 29 11:05:21 2010 -0400

    Verbiage fixes for the RTAddressRegexp warnings

diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm
index f552b0c..f8d121c 100644
--- a/lib/RT/Config.pm
+++ b/lib/RT/Config.pm
@@ -341,11 +341,11 @@ our %META = (
             return if $value;
 
             $RT::Logger->error(
-                'RTAddressRegexp option is not set in the config.'
-                .' Not setting this option result in additional SQL queries to check'
-                .' every address if it belongs to RT or not.'
-                .' Especially important to set this option if RT recieves'
-                .' emails on addresses that are not in DB or config.'
+                'The RTAddressRegexp option is not set in the config.'
+                .' Not setting this option results in additional SQL queries to'
+                .' check whether each address belongs to RT or not.'
+                .' It is especially important to set this option if RT recieves'
+                .' emails on addresses that are not in the database or config.'
             );
         },
     },

commit 3e5afef13d314cdc29a148eed75bc7339eac3fe9
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 30 15:10:20 2010 +0800

    make y_max_value a bit larger

diff --git a/share/html/Search/Chart b/share/html/Search/Chart
index 06d634e..ca33902 100644
--- a/share/html/Search/Chart
+++ b/share/html/Search/Chart
@@ -170,7 +170,7 @@ if ($chart_class eq "GD::Graph::bars") {
         y_label_position => 0.6,
         values_space => -1,
 # the following line to make sure there's enough space for values to show
-        y_max_value => 5*(int($max_value/5) + 1),
+        y_max_value => 5*(int($max_value/5) + 2),
 # if there're too many bars or at least one key is too long, use vertical
         x_labels_vertical => ( keys(%data) * $max_key_length > 60 ) ? 1 : 0,
     );

commit e5e4b610bb4428980c36aa7bf0ea94458c4beac5
Author: Kevin Falcone <falcone at bestpractical.com>
Date:   Mon Mar 1 17:02:09 2010 -0500

    Refactor this duplicated code that cleans up 1970 dates into lib
    
    This also makes sure that we handle Hourly grouping correctly in
    both pieces of code.

diff --git a/lib/RT/Report/Tickets/Entry.pm b/lib/RT/Report/Tickets/Entry.pm
index 49c1a92..4f2a8a3 100644
--- a/lib/RT/Report/Tickets/Entry.pm
+++ b/lib/RT/Report/Tickets/Entry.pm
@@ -52,6 +52,32 @@ use base qw/RT::Record/;
 # XXX TODO: how the heck do we acl a report?
 sub CurrentUserHasRight {1}
 
+=head2 LabelValue
+
+If you're pulling a value out of this collection and using it as a label,
+you may want the "cleaned up" version.  This includes scrubbing 1970 dates
+and ensuring that dates are in local not DB timezones.
+
+=cut
+
+sub LabelValue {
+    my $self  = shift;
+    my $field = shift;
+    my $value = $self->__Value( $field );
+
+    if ( $field =~ /(Daily|Monthly|Annually|Hourly)$/ ) {
+        my $re;
+        $re = qr{1970-01-01 00} if $field =~ /Hourly$/;
+        $re = qr{1970-01-01} if $field =~ /Daily$/;
+        $re = qr{1970-01} if $field =~ /Monthly$/;
+        $re = qr{1970} if $field =~ /Annually$/;
+        $value =~ s/^$re/Not Set/;
+    }
+
+    return $value;
+
+}
+
 eval "require RT::Report::Tickets::Entry_Vendor";
 if ($@ && $@ !~ qr{^Can't locate RT/Report/Tickets/Entry_Vendor.pm}) {
     die $@;
diff --git a/share/html/Search/Chart b/share/html/Search/Chart
index ca33902..abee3e5 100644
--- a/share/html/Search/Chart
+++ b/share/html/Search/Chart
@@ -86,11 +86,11 @@ while ( my $entry = $tix->Next ) {
     my $key;
     if ( $class ) {
         my $q = $class->new( $session{'CurrentUser'} );
-        $q->Load( $entry->__Value( $value_name ) );
+        $q->Load( $entry->LabelValue( $value_name ) );
         $key = $q->Name;
     }
     else {
-        $key = $entry->__Value($value_name);
+        $key = $entry->LabelValue($value_name);
     }
     $key ||= '(no value)';
     
@@ -105,20 +105,6 @@ while ( my $entry = $tix->Next ) {
     $max_key_length = length $key if $max_key_length < length $key;
 }
 
-# XXX: Convert 1970-01-01 date to the 'Not Set'
-# this code should be generalized!!!
-if ( $PrimaryGroupBy =~ /(Daily|Monthly|Annually)$/ ) {
-    my $re;
-    $re = qr{1970-01-01} if $PrimaryGroupBy =~ /Daily$/;
-    $re = qr{1970-01} if $PrimaryGroupBy =~ /Monthly$/;
-    $re = qr{1970} if $PrimaryGroupBy =~ /Annually$/;
-    foreach my $k (keys %data) {
-        my $tmp = $k;
-        $tmp =~ s/^$re/loc('Not Set')/e or next;
-        $data{$tmp} = delete $data{$k};
-    }
-}
-
 unless (keys %data) {
     $data{''} = 0;
 }
diff --git a/share/html/Search/Elements/Chart b/share/html/Search/Elements/Chart
index 593d1b7..4355006 100644
--- a/share/html/Search/Elements/Chart
+++ b/share/html/Search/Elements/Chart
@@ -72,29 +72,16 @@ my (@keys, @values);
 while ( my $entry = $tix->Next ) {
     if ($class) {
         my $q = $class->new( $session{'CurrentUser'} );
-        $q->Load( $entry->__Value( $value_name ) );
+        $q->Load( $entry->LabelValue( $value_name ) );
         push @keys, $q->Name;
     }
     else {
-        push @keys, $entry->__Value( $value_name );
+        push @keys, $entry->LabelValue( $value_name );
     }
     $keys[-1] ||= loc('(no value)');
     push @values, $entry->__Value( $count_name );
 }
 
-# XXX: Convert 1970-01-01 date to the 'Not Set'
-# this code should be generalized!!!
-if ( $PrimaryGroupBy =~ /(Hourly|Daily|Monthly|Annually)$/ ) {
-    my $re;
-    $re = qr{1970-01-01 00} if $PrimaryGroupBy =~ /Hourly$/;
-    $re = qr{1970-01-01} if $PrimaryGroupBy =~ /Daily$/;
-    $re = qr{1970-01} if $PrimaryGroupBy =~ /Monthly$/;
-    $re = qr{1970} if $PrimaryGroupBy =~ /Annually$/;
-    foreach (@keys) {
-        s/^$re/loc('Not Set')/e;
-    }
-}
-
 my %data;
 my %loc_keys;
 foreach my $key (@keys) { $data{$key} = shift @values; $loc_keys{$key} = loc($key); }

-----------------------------------------------------------------------


More information about the Rt-commit mailing list