fix ancient vendor branch CVS bs
authorivan <ivan>
Sun, 19 Feb 2012 22:45:24 +0000 (22:45 +0000)
committerivan <ivan>
Sun, 19 Feb 2012 22:45:24 +0000 (22:45 +0000)
41 files changed:
rt/etc/acl.Oracle
rt/etc/acl.Pg
rt/etc/acl.mysql
rt/lib/RT/ACE.pm
rt/lib/RT/ACL.pm
rt/lib/RT/Action/Autoreply.pm
rt/lib/RT/Action/Generic.pm
rt/lib/RT/Action/Notify.pm
rt/lib/RT/Action/NotifyAsComment.pm
rt/lib/RT/Action/ResolveMembers.pm
rt/lib/RT/Action/SendEmail.pm
rt/lib/RT/Attachment.pm
rt/lib/RT/Attachments.pm
rt/lib/RT/Condition/AnyTransaction.pm
rt/lib/RT/Condition/Generic.pm
rt/lib/RT/Condition/StatusChange.pm
rt/lib/RT/CurrentUser.pm
rt/lib/RT/Group.pm
rt/lib/RT/GroupMember.pm
rt/lib/RT/GroupMembers.pm
rt/lib/RT/Groups.pm
rt/lib/RT/Handle.pm
rt/lib/RT/Interface/CLI.pm
rt/lib/RT/Link.pm
rt/lib/RT/Links.pm
rt/lib/RT/Queue.pm
rt/lib/RT/Queues.pm
rt/lib/RT/Scrip.pm
rt/lib/RT/ScripAction.pm
rt/lib/RT/ScripActions.pm
rt/lib/RT/ScripCondition.pm
rt/lib/RT/ScripConditions.pm
rt/lib/RT/Scrips.pm
rt/lib/RT/Template.pm
rt/lib/RT/Templates.pm
rt/lib/RT/Ticket.pm
rt/lib/RT/Tickets.pm
rt/lib/RT/Transaction.pm
rt/lib/RT/Transactions.pm
rt/lib/RT/User.pm
rt/lib/RT/Users.pm

index c8667c0..9ca4122 100644 (file)
@@ -1,10 +1,4 @@
-sub acl {
-return (
-"CREATE USER ${RT::DatabaseUser} identified by ${RT::DatabasePassword}".
-"temporary tablespace TEMP" .
-"default tablespace USERS" .
-"quota unlimited on USERS;" ,
-"grant connect, resource to ${RT::DatabaseUser};",
-"exit;");
-}
+
+sub acl { return () }
+
 1;
index 16ea71b..8a0d4f2 100755 (executable)
@@ -1,63 +1,76 @@
+
 sub acl {
     my $dbh = shift;
 
     my @acls;
 
     my @tables = qw (
-
-      attachments_id_seq
-      Attachments
-      queues_id_seq
-      Queues
-      links_id_seq
-      Links
-      principals_id_seq
-      Principals
-      groups_id_seq
-      Groups
-      scripconditions_id_seq
-      ScripConditions
-      transactions_id_seq
-      Transactions
-      scrips_id_seq
-      Scrips
-      acl_id_seq
-      ACL
-      groupmembers_id_seq
-      GroupMembers
-      cachedgroupmembers_id_seq
-      CachedGroupMembers
-      users_id_seq
-      Users
-      tickets_id_seq
-      Tickets
-      scripactions_id_seq
-      ScripActions
-      templates_id_seq
-      Templates
-      ticketcustomfieldvalues_id_s
-      TicketCustomFieldValues
-      customfields_id_seq
-      CustomFields
-      customfieldvalues_id_seq
-      CustomFieldValues
-      sessions
+        attachments_id_seq
+        Attachments
+        Attributes
+        attributes_id_seq
+        queues_id_seq
+        Queues 
+        links_id_seq
+        Links 
+        principals_id_seq
+        Principals 
+        groups_id_seq
+        Groups 
+        scripconditions_id_seq
+        ScripConditions 
+        transactions_id_seq
+        Transactions 
+        scrips_id_seq
+        Scrips 
+        acl_id_seq
+        ACL 
+        groupmembers_id_seq
+        GroupMembers 
+        cachedgroupmembers_id_seq
+        CachedGroupMembers 
+        users_id_seq
+        Users 
+        tickets_id_seq
+        Tickets 
+        scripactions_id_seq
+        ScripActions 
+        templates_id_seq
+        Templates 
+        objectcustomfieldvalues_id_s
+        ObjectCustomFieldValues 
+        customfields_id_seq
+        CustomFields 
+        objectcustomfields_id_s
+        ObjectCustomFields 
+        customfieldvalues_id_seq
+        CustomFieldValues
+        sessions
     );
 
-    # if there's already an rt_user, drop it.
-    my @row =
-      $dbh->selectrow_array( "select usename from pg_user where usename = '" . $RT::DatabaseUser."'" );
-    if ( $row[0] ) {
-        push @acls, "drop user ${RT::DatabaseUser};",;
+    my $db_user = RT->Config->Get('DatabaseUser');
+    my $db_pass = RT->Config->Get('DatabasePassword');
+
+    # if there's already an rt_user, use it.
+    my @row = $dbh->selectrow_array( "SELECT usename FROM pg_user WHERE usename = '$db_user'" );
+    unless ( $row[0] ) {
+        push @acls, "CREATE USER \"$db_user\" WITH PASSWORD '$db_pass' NOCREATEDB NOCREATEUSER;";
     }
 
-    push @acls, "create user ${RT::DatabaseUser} with password '${RT::DatabasePassword}' NOCREATEDB NOCREATEUSER;";
+    my $sequence_right
+        = ( $dbh->{pg_server_version} >= 80200 )
+        ? "USAGE, SELECT, UPDATE"
+        : "SELECT, UPDATE";
     foreach my $table (@tables) {
-        push @acls,
-          "GRANT SELECT, INSERT, UPDATE, DELETE ON $table to "
-          . $RT::DatabaseUser . ";";
-
+        if ( $table =~ /^[a-z]/ && $table ne 'sessions' ) {
+# table like objectcustomfields_id_s
+            push @acls, "GRANT $sequence_right ON $table TO \"$db_user\";"
+        }
+        else {
+            push @acls, "GRANT SELECT, INSERT, UPDATE, DELETE ON $table TO \"$db_user\";"
+        }
     }
     return (@acls);
 }
+
 1;
index 0ecaa3b..1688237 100755 (executable)
@@ -1,8 +1,25 @@
+
 sub acl {
-return  (
-"USE mysql;",
-"DELETE FROM user WHERE user = '${RT::DatabaseUser}';",
-"DELETE FROM db where db = '${RT::DatabaseName}';",
-"GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE ON ${RT::DatabaseName}.* TO ${RT::DatabaseUser}\@${RT::DatabaseRTHost} IDENTIFIED BY '${RT::DatabasePassword}';");
+    my $db_name = RT->Config->Get('DatabaseName');
+    my $db_rthost = RT->Config->Get('DatabaseRTHost');
+    my $db_user = RT->Config->Get('DatabaseUser');
+    my $db_pass = RT->Config->Get('DatabasePassword');
+    unless ( $db_user ) {
+        print STDERR "DatabaseUser option is not defined or empty. Skipping...\n";
+        return;
+    }
+    if ( $db_user eq 'root' ) {
+        print STDERR "DatabaseUser is root. Skipping...\n";
+        return;
+    }
+    print "Granting access to $db_user\@'$db_rthost' on $db_name.\n";
+    $db_name =~ s/([_%])/\\$1/g;
+    return (
+        "GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE
+               ON `$db_name`.*
+               TO '$db_user'\@'$db_rthost'
+               IDENTIFIED BY '$db_pass';",
+    );
 }
+
 1;
index 1501a12..dca50c3 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -44,11 +69,7 @@ RT::ACE
 =cut
 
 package RT::ACE;
-use RT::Record; 
-
-
-use vars qw( @ISA );
-@ISA= qw( RT::Record );
+use base 'RT::Record';
 
 sub _Init {
   my $self = shift; 
@@ -61,7 +82,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -104,7 +125,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -113,14 +134,14 @@ Returns the current value of id.
 =cut
 
 
-=item PrincipalType
+=head2 PrincipalType
 
 Returns the current value of PrincipalType. 
 (In the database, PrincipalType is stored as varchar(25).)
 
 
 
-=item SetPrincipalType VALUE
+=head2 SetPrincipalType VALUE
 
 
 Set PrincipalType to VALUE. 
@@ -131,14 +152,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item PrincipalId
+=head2 PrincipalId
 
 Returns the current value of PrincipalId. 
 (In the database, PrincipalId is stored as int(11).)
 
 
 
-=item SetPrincipalId VALUE
+=head2 SetPrincipalId VALUE
 
 
 Set PrincipalId to VALUE. 
@@ -149,14 +170,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item RightName
+=head2 RightName
 
 Returns the current value of RightName. 
 (In the database, RightName is stored as varchar(25).)
 
 
 
-=item SetRightName VALUE
+=head2 SetRightName VALUE
 
 
 Set RightName to VALUE. 
@@ -167,14 +188,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ObjectType
+=head2 ObjectType
 
 Returns the current value of ObjectType. 
 (In the database, ObjectType is stored as varchar(25).)
 
 
 
-=item SetObjectType VALUE
+=head2 SetObjectType VALUE
 
 
 Set ObjectType to VALUE. 
@@ -185,14 +206,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ObjectId
+=head2 ObjectId
 
 Returns the current value of ObjectId. 
 (In the database, ObjectId is stored as int(11).)
 
 
 
-=item SetObjectId VALUE
+=head2 SetObjectId VALUE
 
 
 Set ObjectId to VALUE. 
@@ -203,14 +224,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item DelegatedBy
+=head2 DelegatedBy
 
 Returns the current value of DelegatedBy. 
 (In the database, DelegatedBy is stored as int(11).)
 
 
 
-=item SetDelegatedBy VALUE
+=head2 SetDelegatedBy VALUE
 
 
 Set DelegatedBy to VALUE. 
@@ -221,14 +242,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item DelegatedFrom
+=head2 DelegatedFrom
 
 Returns the current value of DelegatedFrom. 
 (In the database, DelegatedFrom is stored as int(11).)
 
 
 
-=item SetDelegatedFrom VALUE
+=head2 SetDelegatedFrom VALUE
 
 
 Set DelegatedFrom to VALUE. 
@@ -240,47 +261,30 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         PrincipalType => 
-               {read => 1, write => 1, type => 'varchar(25)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 25,  is_blob => 0,  is_numeric => 0,  type => 'varchar(25)', default => ''},
         PrincipalId => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         RightName => 
-               {read => 1, write => 1, type => 'varchar(25)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 25,  is_blob => 0,  is_numeric => 0,  type => 'varchar(25)', default => ''},
         ObjectType => 
-               {read => 1, write => 1, type => 'varchar(25)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 25,  is_blob => 0,  is_numeric => 0,  type => 'varchar(25)', default => ''},
         ObjectId => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         DelegatedBy => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         DelegatedFrom => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
 
  }
 };
 
-
-        eval "require RT::ACE_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/ACE_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ACE_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/ACE_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ACE_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/ACE_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -290,7 +294,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 81f59c6..94a0c91 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -47,12 +72,9 @@ use strict;
 
 package RT::ACL;
 
-use RT::SearchBuilder;
+use base 'RT::SearchBuilder';
 use RT::ACE;
 
-use vars qw( @ISA );
-@ISA= qw(RT::SearchBuilder);
-
 
 sub _Init {
     my $self = shift;
@@ -64,7 +86,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::ACE item
 
@@ -74,24 +96,7 @@ sub NewItem {
     my $self = shift;
     return(RT::ACE->new($self->CurrentUser));
 }
-
-        eval "require RT::ACL_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/ACL_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ACL_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/ACL_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ACL_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/ACL_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +106,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 81f7bdd..e3e792e 100755 (executable)
@@ -1,34 +1,71 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 package RT::Action::Autoreply;
-require RT::Action::SendEmail;
 
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Action::SendEmail);
+use warnings;
+
+use base qw(RT::Action::SendEmail);
+
+=head2 Prepare
+
+Set up the relevant recipients, then call our parent.
+
+=cut
 
 
+sub Prepare {
+    my $self = shift;
+    $self->SetRecipients();
+    $self->SUPER::Prepare();
+}
+
 # {{{ sub SetRecipients
 
 =head2 SetRecipients
@@ -59,38 +96,37 @@ Set this message\'s return address to the apropriate queue address
 
 sub SetReturnAddress {
     my $self = shift;
-    my %args = ( is_comment => 0,
-                @_
-              );
     
-    my $replyto;
-    if ($args{'is_comment'}) { 
-       $replyto = $self->TicketObj->QueueObj->CommentAddress || 
-                    $RT::CommentAddress;
-    }
-    else {
-       $replyto = $self->TicketObj->QueueObj->CorrespondAddress ||
-                    $RT::CorrespondAddress;
-    }
-    
-    unless ($self->TemplateObj->MIMEObj->head->get('From')) {
-       my $friendly_name = $self->TicketObj->QueueObj->Description ||
-               $self->TicketObj->QueueObj->Name;
-       $friendly_name =~ s/"/\\"/g;
-       $self->SetHeader('From', "\"$friendly_name\" <$replyto>");
-    }
-    
-    unless ($self->TemplateObj->MIMEObj->head->get('Reply-To')) {
-       $self->SetHeader('Reply-To', "$replyto");
-    }
+    my $friendly_name;
+
+       if (RT->Config->Get('UseFriendlyFromLine')) {
+           $friendly_name = $self->TicketObj->QueueObj->Description ||
+                   $self->TicketObj->QueueObj->Name;
+       }
+
+    $self->SUPER::SetReturnAddress( @_, friendly_name => $friendly_name );
     
 }
   
 # }}}
 
-eval "require RT::Action::Autoreply_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Autoreply_Vendor.pm});
-eval "require RT::Action::Autoreply_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Autoreply_Local.pm});
+# {{{{ sub SetRTSpecialHeaders
+
+=head2 SetRTSpecialHeaders
+
+Set the C<Auto-Generated> header to C<auto-replied>, in accordance
+with RFC3834.
+
+=cut
+
+sub SetRTSpecialHeaders {
+    my $self = shift;
+    $self->SUPER::SetRTSpecialHeaders(@_);
+    $self->SetHeader( 'Auto-Submitted', 'auto-replied' );
+}
+
+# }}}
+
+RT::Base->_ImportOverlays();
 
 1;
index 007d299..d747813 100755 (executable)
@@ -1,29 +1,54 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 =head1 NAME
 
-  RT::Action::Generic - a generic baseclass for RT Actions
+  RT::Action::Generic - deprecated, see RT::Action
 
 =head1 SYNOPSIS
 
 
 =head1 DESCRIPTION
 
-=head1 METHODS
-
-=begin testing
+This module is provided only for backwards compatibility.
 
-ok (require RT::Action::Generic);
+=head1 METHODS
 
-=end testing
 
 =cut
 
-package RT::Action::Generic;
-
 use strict;
+use warnings;
+package RT::Action::Generic;
+use base 'RT::Action';
 
-# {{{ sub new 
-sub new  {
-  my $proto = shift;
-  my $class = ref($proto) || $proto;
-  my $self  = {};
-  bless ($self, $class);
-  $self->_Init(@_);
-  return $self;
-}
-# }}}
-
-# {{{ sub new 
-sub loc {
-    my $self = shift;
-    return $self->{'ScripObj'}->loc(@_);
-}
-# }}}
-
-# {{{ sub _Init 
-sub _Init  {
-  my $self = shift;
-  my %args = ( TransactionObj => undef,
-              TicketObj => undef,
-              ScripObj => undef,
-              TemplateObj => undef,
-              Argument => undef,
-              Type => undef,
-              @_ );
-  
-  
-  $self->{'Argument'} = $args{'Argument'};
-  $self->{'ScripObj'} = $args{'ScripObj'};
-  $self->{'TicketObj'} = $args{'TicketObj'};
-  $self->{'TransactionObj'} = $args{'TransactionObj'};
-  $self->{'TemplateObj'} = $args{'TemplateObj'};
-  $self->{'Type'} = $args{'Type'};
-}
-# }}}
-
-# Access Scripwide data
-
-# {{{ sub Argument 
-sub Argument  {
-  my $self = shift;
-  return($self->{'Argument'});
-}
-# }}}
-
-# {{{ sub TicketObj
-sub TicketObj  {
-  my $self = shift;
-  return($self->{'TicketObj'});
-}
-# }}}
-
-# {{{ sub TransactionObj
-sub TransactionObj  {
-  my $self = shift;
-  return($self->{'TransactionObj'});
-}
-# }}}
-
-# {{{ sub TemplateObj
-sub TemplateObj  {
-  my $self = shift;
-  return($self->{'TemplateObj'});
-}
-# }}}
-
-# {{{ sub ScripObj
-sub ScripObj  {
-  my $self = shift;
-  return($self->{'ScripObj'});
-}
-# }}}
-
-# {{{ sub Type
-sub Type  {
-  my $self = shift;
-  return($self->{'Type'});
-}
-# }}}
-
-
-# Scrip methods
-
-#Do what we need to do and send it out.
-
-# {{{ sub Commit 
-sub Commit  {
-  my $self = shift;
-  return(0, $self->loc("Commit Stubbed"));
-}
-# }}}
-
-
-#What does this type of Action does
-
-# {{{ sub Describe 
-sub Describe  {
-  my $self = shift;
-  return $self->loc("No description for [_1]", ref $self);
-}
-# }}}
-
-
-#Parse the templates, get things ready to go.
-
-# {{{ sub Prepare 
-sub Prepare  {
-  my $self = shift;
-  return (0, $self->loc("Prepare Stubbed"));
-}
-# }}}
-
-
-#If this rule applies to this transaction, return true.
-
-# {{{ sub IsApplicable 
-sub IsApplicable  {
-  my $self = shift;
-  return(undef);
-}
-# }}}
-
-# {{{ sub DESTROY
-sub DESTROY {
-    my $self = shift;
-
-    # We need to clean up all the references that might maybe get
-    # oddly circular
-    $self->{'TemplateObj'} =undef
-    $self->{'TicketObj'} = undef;
-    $self->{'TransactionObj'} = undef;
-    $self->{'ScripObj'} = undef;
-
-
-     
-}
-
-# }}}
-
-eval "require RT::Action::Generic_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Generic_Vendor.pm});
-eval "require RT::Action::Generic_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Generic_Local.pm});
-
+RT::Base->_ImportOverlays();
 1;
+
index 1e4e4c0..3f58bf5 100755 (executable)
@@ -1,34 +1,73 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
+#
 package RT::Action::Notify;
-require RT::Action::SendEmail;
 
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Action::SendEmail);
+use warnings;
 
-# {{{ sub SetRecipients
+use base qw(RT::Action::SendEmail);
+
+use Email::Address;
+
+=head2 Prepare
+
+Set up the relevant recipients, then call our parent.
+
+=cut
+
+
+sub Prepare {
+    my $self = shift;
+    $self->SetRecipients();
+    $self->SUPER::Prepare();
+}
 
 =head2 SetRecipients
 
@@ -40,93 +79,89 @@ Explicitly B<does not> notify the creator of the transaction by default
 sub SetRecipients {
     my $self = shift;
 
-    my $arg = $self->Argument;
+    my $ticket = $self->TicketObj;
 
+    my $arg = $self->Argument;
     $arg =~ s/\bAll\b/Owner,Requestor,AdminCc,Cc/;
 
     my ( @To, @PseudoTo, @Cc, @Bcc );
 
 
-    if ($arg =~ /\bOtherRecipients\b/) {
-        if ($self->TransactionObj->Attachments->First) {
-            push (@Cc, $self->TransactionObj->Attachments->First->GetHeader('RT-Send-Cc'));
-            push (@Bcc, $self->TransactionObj->Attachments->First->GetHeader('RT-Send-Bcc'));
+    if ( $arg =~ /\bOtherRecipients\b/ ) {
+        if ( my $attachment = $self->TransactionObj->Attachments->First ) {
+            push @Cc, map { $_->address } Email::Address->parse(
+                $attachment->GetHeader('RT-Send-Cc')
+            );
+            push @Bcc, map { $_->address } Email::Address->parse(
+                $attachment->GetHeader('RT-Send-Bcc')
+            );
         }
     }
 
     if ( $arg =~ /\bRequestor\b/ ) {
-        push ( @To, $self->TicketObj->Requestors->MemberEmailAddresses  );
+        push @To, $ticket->Requestors->MemberEmailAddresses;
     }
 
-    
-
     if ( $arg =~ /\bCc\b/ ) {
 
         #If we have a To, make the Ccs, Ccs, otherwise, promote them to To
         if (@To) {
-            push ( @Cc, $self->TicketObj->Cc->MemberEmailAddresses );
-            push ( @Cc, $self->TicketObj->QueueObj->Cc->MemberEmailAddresses  );
+            push ( @Cc, $ticket->Cc->MemberEmailAddresses );
+            push ( @Cc, $ticket->QueueObj->Cc->MemberEmailAddresses  );
         }
         else {
-            push ( @Cc, $self->TicketObj->Cc->MemberEmailAddresses  );
-            push ( @To, $self->TicketObj->QueueObj->Cc->MemberEmailAddresses  );
+            push ( @Cc, $ticket->Cc->MemberEmailAddresses  );
+            push ( @To, $ticket->QueueObj->Cc->MemberEmailAddresses  );
         }
     }
 
-    if ( ( $arg =~ /\bOwner\b/ )
-        && ( $self->TicketObj->OwnerObj->id != $RT::Nobody->id ) )
-    {
-
-        # If we're not sending to Ccs or requestors, 
+    if ( $arg =~ /\bOwner\b/ && $ticket->OwnerObj->id != $RT::Nobody->id ) {
+        # If we're not sending to Ccs or requestors,
         # then the Owner can be the To.
         if (@To) {
-            push ( @Bcc, $self->TicketObj->OwnerObj->EmailAddress );
+            push ( @Bcc, $ticket->OwnerObj->EmailAddress );
         }
         else {
-            push ( @To, $self->TicketObj->OwnerObj->EmailAddress );
+            push ( @To, $ticket->OwnerObj->EmailAddress );
         }
 
     }
 
     if ( $arg =~ /\bAdminCc\b/ ) {
-        push ( @Bcc, $self->TicketObj->AdminCc->MemberEmailAddresses  );
-        push ( @Bcc, $self->TicketObj->QueueObj->AdminCc->MemberEmailAddresses  );
+        push ( @Bcc, $ticket->AdminCc->MemberEmailAddresses  );
+        push ( @Bcc, $ticket->QueueObj->AdminCc->MemberEmailAddresses  );
     }
 
-    if ($RT::UseFriendlyToLine) {
+    if ( RT->Config->Get('UseFriendlyToLine') ) {
         unless (@To) {
-            push (
-               @PseudoTo,
-               sprintf($RT::FriendlyToLineFormat, $arg, $self->TicketObj->id),
-           );
+            push @PseudoTo,
+                sprintf RT->Config->Get('FriendlyToLineFormat'), $arg, $ticket->id;
         }
     }
 
-    my $creator = $self->TransactionObj->CreatorObj->EmailAddress();
+    my $creatorObj = $self->TransactionObj->CreatorObj;
+    my $creator = $creatorObj->EmailAddress();
 
     #Strip the sender out of the To, Cc and AdminCc and set the 
     # recipients fields used to build the message by the superclass.
     # unless a flag is set 
-    if ($RT::NotifyActor) {
+    my $TransactionCurrentUser = RT::CurrentUser->new;
+    $TransactionCurrentUser->LoadByName($creatorObj->Name);
+    if (RT->Config->Get('NotifyActor',$TransactionCurrentUser)) {
         @{ $self->{'To'} }  = @To;
         @{ $self->{'Cc'} }  = @Cc;
         @{ $self->{'Bcc'} } = @Bcc;
     }
     else {
-        @{ $self->{'To'} }  = grep ( !/^$creator$/, @To );
-        @{ $self->{'Cc'} }  = grep ( !/^$creator$/, @Cc );
-        @{ $self->{'Bcc'} } = grep ( !/^$creator$/, @Bcc );
+        @{ $self->{'To'} }  = grep ( lc $_ ne lc $creator, @To );
+        @{ $self->{'Cc'} }  = grep ( lc $_ ne lc $creator, @Cc );
+        @{ $self->{'Bcc'} } = grep ( lc $_ ne lc $creator, @Bcc );
     }
     @{ $self->{'PseudoTo'} } = @PseudoTo;
-    return (1);
 
-}
 
-# }}}
+}
 
-eval "require RT::Action::Notify_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Notify_Vendor.pm});
-eval "require RT::Action::Notify_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/Notify_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
index 210e4ab..504d139 100755 (executable)
@@ -1,55 +1,75 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 package RT::Action::NotifyAsComment;
-require RT::Action::Notify;
 
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Action::Notify);
+use warnings;
 
+use base qw(RT::Action::Notify);
 
 =head2 SetReturnAddress
 
-Tell SendEmail that this message should come out as a comment. 
+Tell SendEmail that this message should come out as a comment.
 Calls SUPER::SetReturnAddress.
 
 =cut
 
 sub SetReturnAddress {
-       my $self = shift;
-       
-       # Tell RT::Action::SendEmail that this should come 
-       # from the relevant comment email address.
-       $self->{'comment'} = 1;
-       
-       return($self->SUPER::SetReturnAddress(is_comment => 1));
+    my $self = shift;
+
+    # Tell RT::Action::SendEmail that this should come
+    # from the relevant comment email address.
+    $self->{'comment'} = 1;
+
+    return $self->SUPER::SetReturnAddress( @_, is_comment => 1 );
 }
 
-eval "require RT::Action::NotifyAsComment_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/NotifyAsComment_Vendor.pm});
-eval "require RT::Action::NotifyAsComment_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/NotifyAsComment_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
-
index 02ff3a5..aff6365 100644 (file)
@@ -1,35 +1,58 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # This Action will resolve all members of a resolved group ticket
 
 package RT::Action::ResolveMembers;
-require RT::Action::Generic;
+use base 'RT::Action';
 require RT::Links;
 
 use strict;
-use vars qw/@ISA/;
-@ISA=qw(RT::Action::Generic);
 
 #Do what we need to do and send it out.
 
@@ -79,10 +102,7 @@ sub IsApplicable  {
 }
 # }}}
 
-eval "require RT::Action::ResolveMembers_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/ResolveMembers_Vendor.pm});
-eval "require RT::Action::ResolveMembers_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/ResolveMembers_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
 
index dac8fc8..9e93e4a 100755 (executable)
@@ -1,38 +1,65 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Portions Copyright 2000 Tobias Brox <tobix@cpan.org>
 
 package RT::Action::SendEmail;
-require RT::Action::Generic;
 
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Action::Generic);
+use warnings;
 
-use MIME::Words qw(encode_mimeword);
+use base qw(RT::Action);
 
 use RT::EmailParser;
+use RT::Interface::Email;
+use Email::Address;
+our @EMAIL_RECIPIENT_HEADERS = qw(To Cc Bcc);
+
 
 =head1 NAME
 
@@ -42,273 +69,495 @@ RT::Action::AutoReply is a good example subclass.
 
 =head1 SYNOPSIS
 
-  require RT::Action::SendEmail;
-  @ISA  = qw(RT::Action::SendEmail);
-
+  use base 'RT::Action::SendEmail';
 
 =head1 DESCRIPTION
 
 Basically, you create another module RT::Action::YourAction which ISA
 RT::Action::SendEmail.
 
-If you want to set the recipients of the mail to something other than
-the addresses mentioned in the To, Cc, Bcc and headers in
-the template, you should subclass RT::Action::SendEmail and override
-either the SetRecipients method or the SetTo, SetCc, etc methods (see
-the comments for the SetRecipients sub).
+=head1 METHODS
 
+=head2 CleanSlate
 
-=begin testing
+Cleans class-wide options, like L</SquelchMailTo> or L</AttachTickets>.
 
-ok (require RT::Action::SendEmail);
+=cut
 
-=end testing
+sub CleanSlate {
+    my $self = shift;
+    $self->SquelchMailTo(undef);
+    $self->AttachTickets(undef);
+}
 
+=head2 Commit
 
-=head1 AUTHOR
+Sends the prepared message and writes outgoing record into DB if the feature is
+activated in the config.
 
-Jesse Vincent <jesse@bestpractical.com> and Tobias Brox <tobix@cpan.org>
+=cut
 
-=head1 SEE ALSO
+sub Commit {
+    my $self = shift;
 
-perl(1).
+    $self->DeferDigestRecipients() if RT->Config->Get('RecordOutgoingEmail');
+    my $message = $self->TemplateObj->MIMEObj;
+
+    my $orig_message;
+    if (   RT->Config->Get('RecordOutgoingEmail')
+        && RT->Config->Get('GnuPG')->{'Enable'} )
+    {
+
+        # it's hacky, but we should know if we're going to crypt things
+        my $attachment = $self->TransactionObj->Attachments->First;
+
+        my %crypt;
+        foreach my $argument (qw(Sign Encrypt)) {
+            if ( $attachment
+                && defined $attachment->GetHeader("X-RT-$argument") )
+            {
+                $crypt{$argument} = $attachment->GetHeader("X-RT-$argument");
+            } else {
+                $crypt{$argument} = $self->TicketObj->QueueObj->$argument();
+            }
+        }
+        if ( $crypt{'Sign'} || $crypt{'Encrypt'} ) {
+            $orig_message = $message->dup;
+        }
+    }
 
-=cut
+    my ($ret) = $self->SendMessage($message);
+    if ( $ret > 0 && RT->Config->Get('RecordOutgoingEmail') ) {
+        if ($orig_message) {
+            $message->attach(
+                Type        => 'application/x-rt-original-message',
+                Disposition => 'inline',
+                Data        => $orig_message->as_string,
+            );
+        }
+        $self->RecordOutgoingMailTransaction($message);
+        $self->RecordDeferredRecipients();
+    }
 
-# {{{ Scrip methods (_Init, Commit, Prepare, IsApplicable)
 
-# {{{ sub _Init
-# We use _Init from RT::Action
-# }}}
+    return ( abs $ret );
+}
 
-# {{{ sub Commit
-#Do what we need to do and send it out.
-sub Commit {
-    my $self = shift;
+=head2 Prepare
 
-    my $MIMEObj = $self->TemplateObj->MIMEObj;
-    my $msgid = $MIMEObj->head->get('Message-Id');
-    chomp $msgid;
-    $RT::Logger->info($msgid." #".$self->TicketObj->id."/".$self->TransactionObj->id." - Scrip ". $self->ScripObj->id ." ".$self->ScripObj->Description);
-    #send the email
+Builds an outgoing email we're going to send using scrip's template.
 
-        # Weed out any RT addresses. We really don't want to talk to ourselves!
-        @{$self->{'To'}} = RT::EmailParser::CullRTAddresses("", @{$self->{'To'}});
-        @{$self->{'Cc'}} = RT::EmailParser::CullRTAddresses("", @{$self->{'Cc'}});
-        @{$self->{'Bcc'}} = RT::EmailParser::CullRTAddresses("", @{$self->{'Bcc'}});
-    # If there are no recipients, don't try to send the message.
-    # If the transaction has content and has the header RT-Squelch-Replies-To
+=cut
+
+sub Prepare {
+    my $self = shift;
 
-    if ( defined $self->TransactionObj->Attachments->First() ) {
+    my ( $result, $message ) = $self->TemplateObj->Parse(
+        Argument       => $self->Argument,
+        TicketObj      => $self->TicketObj,
+        TransactionObj => $self->TransactionObj
+    );
+    if ( !$result ) {
+        return (undef);
+    }
 
-        my $squelch = $self->TransactionObj->Attachments->First->GetHeader( 'RT-Squelch-Replies-To');
+    my $MIMEObj = $self->TemplateObj->MIMEObj;
 
-        if ($squelch) {
-            my @blacklist = split ( /,/, $squelch );
+    # Header
+    $self->SetRTSpecialHeaders();
 
-            # Cycle through the people we're sending to and pull out anyone on the
-            # system blacklist
+    $self->RemoveInappropriateRecipients();
 
-            foreach my $person_to_yank (@blacklist) {
-                $person_to_yank =~ s/\s//g;
-                @{ $self->{'To'} } =
-                  grep ( !/^$person_to_yank$/, @{ $self->{'To'} } );
-                @{ $self->{'Cc'} } =
-                  grep ( !/^$person_to_yank$/, @{ $self->{'Cc'} } );
-                @{ $self->{'Bcc'} } =
-                  grep ( !/^$person_to_yank$/, @{ $self->{'Bcc'} } );
-            }
-        }
+    my %seen;
+    foreach my $type (@EMAIL_RECIPIENT_HEADERS) {
+        @{ $self->{$type} }
+            = grep defined && length && !$seen{ lc $_ }++,
+            @{ $self->{$type} };
     }
 
     # Go add all the Tos, Ccs and Bccs that we need to to the message to
     # make it happy, but only if we actually have values in those arrays.
 
-    $self->SetHeader( 'To', join ( ',', @{ $self->{'To'} } ) )
-      if ( $self->{'To'} && @{ $self->{'To'} } );
-    $self->SetHeader( 'Cc', join ( ',', @{ $self->{'Cc'} } ) )
-      if ( $self->{'Cc'} && @{ $self->{'Cc'} } );
-    $self->SetHeader( 'Bcc', join ( ',', @{ $self->{'Bcc'} } ) )
-      if ( $self->{'Cc'} && @{ $self->{'Bcc'} } );
+# TODO: We should be pulling the recipients out of the template and shove them into To, Cc and Bcc
 
+    for my $header (@EMAIL_RECIPIENT_HEADERS) {
 
-    $self->SetHeader('MIME-Version', '1.0');
+        $self->SetHeader( $header, join( ', ', @{ $self->{$header} } ) )
+          if (!$MIMEObj->head->get($header)
+            && $self->{$header}
+            && @{ $self->{$header} } );
+    }
+    # PseudoTo (fake to headers) shouldn't get matched for message recipients.
+    # If we don't have any 'To' header (but do have other recipients), drop in
+    # the pseudo-to header.
+    $self->SetHeader( 'To', join( ', ', @{ $self->{'PseudoTo'} } ) )
+        if $self->{'PseudoTo'}
+            && @{ $self->{'PseudoTo'} }
+            && !$MIMEObj->head->get('To')
+            && ( $MIMEObj->head->get('Cc') or $MIMEObj->head->get('Bcc') );
+
+    # We should never have to set the MIME-Version header
+    $self->SetHeader( 'MIME-Version', '1.0' );
+
+    # fsck.com #5959: Since RT sends 8bit mail, we should say so.
+    $self->SetHeader( 'Content-Transfer-Encoding', '8bit' );
+
+    # For security reasons, we only send out textual mails.
+    foreach my $part ( grep !$_->is_multipart, $MIMEObj->parts_DFS ) {
+        my $type = $part->mime_type || 'text/plain';
+        $type = 'text/plain' unless RT::I18N::IsTextualContentType($type);
+        $part->head->mime_attr( "Content-Type" => $type );
+        # utf-8 here is for _FindOrGuessCharset in I18N.pm
+        # it's not the final charset/encoding sent
+        $part->head->mime_attr( "Content-Type.charset" => 'utf-8' );
+    }
 
-    # try to convert message body from utf-8 to $RT::EmailOutputEncoding
-    $self->SetHeader( 'Content-Type', 'text/plain; charset="utf-8"' );
+    RT::I18N::SetMIMEEntityToEncoding( $MIMEObj,
+        RT->Config->Get('EmailOutputEncoding'),
+        'mime_words_ok', );
 
-    RT::I18N::SetMIMEEntityToEncoding( $MIMEObj, $RT::EmailOutputEncoding, 'mime_words_ok' );
-    $self->SetHeader( 'Content-Type', 'text/plain; charset="' . $RT::EmailOutputEncoding . '"' );
+    # Build up a MIME::Entity that looks like the original message.
+    $self->AddAttachments if ( $MIMEObj->head->get('RT-Attach-Message')
+                               && ( $MIMEObj->head->get('RT-Attach-Message') !~ /^(n|no|0|off|false)$/i ) );
+
+    $self->AddTickets;
+
+    my $attachment = $self->TransactionObj->Attachments->First;
+    if ($attachment
+        && !(
+               $attachment->GetHeader('X-RT-Encrypt')
+            || $self->TicketObj->QueueObj->Encrypt
+        )
+        )
+    {
+        $attachment->SetHeader( 'X-RT-Encrypt' => 1 )
+            if ( $attachment->GetHeader("X-RT-Incoming-Encryption") || '' ) eq
+            'Success';
+    }
 
+    return $result;
+}
 
-    # Build up a MIME::Entity that looks like the original message.
+=head2 To
 
-    my $do_attach = $self->TemplateObj->MIMEObj->head->get('RT-Attach-Message');
+Returns an array of L<Email::Address> objects containing all the To: recipients for this notification
 
-    if ($do_attach) {
-        $self->TemplateObj->MIMEObj->head->delete('RT-Attach-Message');
+=cut
 
-        my $attachments = RT::Attachments->new($RT::SystemUser);
-        $attachments->Limit( FIELD => 'TransactionId',
-                             VALUE => $self->TransactionObj->Id );
-        $attachments->OrderBy('id');
+sub To {
+    my $self = shift;
+    return ( $self->AddressesFromHeader('To') );
+}
 
-        my $transaction_content_obj = $self->TransactionObj->ContentObj;
+=head2 Cc
 
-        # attach any of this transaction's attachments
-        while ( my $attach = $attachments->Next ) {
+Returns an array of L<Email::Address> objects containing all the Cc: recipients for this notification
 
-            # Don't attach anything blank
-            next unless ( $attach->ContentLength );
+=cut
 
-            # We want to make sure that we don't include the attachment that's being sued as the "Content" of this message"
-            next
-              if (    $transaction_content_obj
-                   && $transaction_content_obj->Id == $attach->Id 
-                   && $transaction_content_obj->ContentType =~ qr{text/plain}i
-                );
-            $MIMEObj->make_multipart('mixed');
-            $MIMEObj->attach( Type => $attach->ContentType,
-                              Charset => $attach->OriginalEncoding,
-                              Data => $attach->OriginalContent,
-                              Filename => $self->MIMEEncodeString( $attach->Filename, $RT::EmailOutputEncoding ),
-                              Encoding    => '-SUGGEST');
-        }
+sub Cc {
+    my $self = shift;
+    return ( $self->AddressesFromHeader('Cc') );
+}
 
-    }
+=head2 Bcc
 
+Returns an array of L<Email::Address> objects containing all the Bcc: recipients for this notification
 
-    my $retval = $self->SendMessage($MIMEObj);
+=cut
 
+sub Bcc {
+    my $self = shift;
+    return ( $self->AddressesFromHeader('Bcc') );
 
-    return ($retval);
 }
 
-# }}}
+sub AddressesFromHeader {
+    my $self      = shift;
+    my $field     = shift;
+    my $header    = $self->TemplateObj->MIMEObj->head->get($field);
+    my @addresses = Email::Address->parse($header);
+
+    return (@addresses);
+}
 
-# {{{ sub Prepare
+=head2 SendMessage MIMEObj
 
-sub Prepare {
-    my $self = shift;
+sends the message using RT's preferred API.
+TODO: Break this out to a separate module
 
-    # This actually populates the MIME::Entity fields in the Template Object
+=cut
 
-    unless ( $self->TemplateObj ) {
-        $RT::Logger->warning("No template object handed to $self\n");
-    }
+sub SendMessage {
 
-    unless ( $self->TransactionObj ) {
-        $RT::Logger->warning("No transaction object handed to $self\n");
+    # DO NOT SHIFT @_ in this subroutine.  It breaks Hook::LexWrap's
+    # ability to pass @_ to a 'post' routine.
+    my ( $self, $MIMEObj ) = @_;
 
-    }
+    my $msgid = $MIMEObj->head->get('Message-ID');
+    chomp $msgid;
+
+    $self->ScripActionObj->{_Message_ID}++;
+
+    $RT::Logger->info( $msgid . " #"
+            . $self->TicketObj->id . "/"
+            . $self->TransactionObj->id
+            . " - Scrip "
+            . ($self->ScripObj->id || '#rule'). " "
+            . ( $self->ScripObj->Description || '' ) );
 
-    unless ( $self->TicketObj ) {
-        $RT::Logger->warning("No ticket object handed to $self\n");
+    my $status = RT::Interface::Email::SendEmail(
+        Entity      => $MIMEObj,
+        Ticket      => $self->TicketObj,
+        Transaction => $self->TransactionObj,
+    );
+
+     
+    return $status unless ($status > 0 || exists $self->{'Deferred'});
 
+    my $success = $msgid . " sent ";
+    foreach (@EMAIL_RECIPIENT_HEADERS) {
+        my $recipients = $MIMEObj->head->get($_);
+        $success .= " $_: " . $recipients if $recipients;
     }
 
-    my ( $result, $message ) = $self->TemplateObj->Parse(
-                                         Argument       => $self->Argument,
-                                         TicketObj      => $self->TicketObj,
-                                         TransactionObj => $self->TransactionObj
+    if( exists $self->{'Deferred'} ) {
+        for (qw(daily weekly susp)) {
+            $success .= "\nBatched email $_ for: ". join(", ", keys %{ $self->{'Deferred'}{ $_ } } )
+                if exists $self->{'Deferred'}{ $_ };
+        }
+    }
+
+    $success =~ s/\n//g;
+
+    $RT::Logger->info($success);
+
+    return (1);
+}
+
+=head2 AddAttachments
+
+Takes any attachments to this transaction and attaches them to the message
+we're building.
+
+=cut
+
+sub AddAttachments {
+    my $self = shift;
+
+    my $MIMEObj = $self->TemplateObj->MIMEObj;
+
+    $MIMEObj->head->delete('RT-Attach-Message');
+
+    my $attachments = RT::Attachments->new($RT::SystemUser);
+    $attachments->Limit(
+        FIELD => 'TransactionId',
+        VALUE => $self->TransactionObj->Id
     );
-    if ($result) {
-
-        # Header
-        $self->SetSubject();
-        $self->SetSubjectToken();
-        $self->SetRecipients();
-        $self->SetReturnAddress();
-        $self->SetRTSpecialHeaders();
-        if ($RT::EmailOutputEncoding) {
-
-            # l10n related header
-            $self->SetHeaderAsEncoding( 'Subject', $RT::EmailOutputEncoding );
+
+    # Don't attach anything blank
+    $attachments->LimitNotEmpty;
+    $attachments->OrderBy( FIELD => 'id' );
+
+    # We want to make sure that we don't include the attachment that's
+    # being used as the "Content" of this message" unless that attachment's
+    # content type is not like text/...
+    my $transaction_content_obj = $self->TransactionObj->ContentObj;
+
+    if (   $transaction_content_obj
+        && $transaction_content_obj->ContentType =~ m{text/}i )
+    {
+        # If this was part of a multipart/alternative, skip all of the kids
+        my $parent = $transaction_content_obj->ParentObj;
+        if ($parent and $parent->Id and $parent->ContentType eq "multipart/alternative") {
+            $attachments->Limit(
+                ENTRYAGGREGATOR => 'AND',
+                FIELD           => 'parent',
+                OPERATOR        => '!=',
+                VALUE           => $parent->Id,
+            );
+        } else {
+            $attachments->Limit(
+                ENTRYAGGREGATOR => 'AND',
+                FIELD           => 'id',
+                OPERATOR        => '!=',
+                VALUE           => $transaction_content_obj->Id,
+            );
         }
     }
 
-    return $result;
+    # attach any of this transaction's attachments
+    my $seen_attachment = 0;
+    while ( my $attach = $attachments->Next ) {
+        if ( !$seen_attachment ) {
+            $MIMEObj->make_multipart( 'mixed', Force => 1 );
+            $seen_attachment = 1;
+        }
+        $self->AddAttachment($attach);
+    }
+}
+
+=head2 AddAttachment $attachment
+
+Takes one attachment object of L<RT::Attachmment> class and attaches it to the message
+we're building.
+
+=cut
 
+sub AddAttachment {
+    my $self    = shift;
+    my $attach  = shift;
+    my $MIMEObj = shift || $self->TemplateObj->MIMEObj;
+
+    $MIMEObj->attach(
+        Type     => $attach->ContentType,
+        Charset  => $attach->OriginalEncoding,
+        Data     => $attach->OriginalContent,
+        Filename => $self->MIMEEncodeString( $attach->Filename ),
+        'RT-Attachment:' => $self->TicketObj->Id . "/"
+            . $self->TransactionObj->Id . "/"
+            . $attach->id,
+        Encoding => '-SUGGEST',
+    );
 }
 
-# }}}
+=head2 AttachTickets [@IDs]
 
-# }}}
+Returns or set list of ticket's IDs that should be attached to an outgoing message.
 
-# {{{ SendMessage
-=head2 SendMessage MIMEObj
+B<Note> this method works as a class method and setup things global, so you have to
+clean list by passing undef as argument.
 
-sends the message using RT's preferred API.
-TODO: Break this out to a seperate module
+=cut
+
+{
+    my $list = [];
+
+    sub AttachTickets {
+        my $self = shift;
+        $list = [ grep defined, @_ ] if @_;
+        return @$list;
+    }
+}
+
+=head2 AddTickets
+
+Attaches tickets to the current message, list of tickets' ids get from
+L</AttachTickets> method.
 
 =cut
 
-sub SendMessage {
+sub AddTickets {
     my $self = shift;
-    my $MIMEObj = shift;
+    $self->AddTicket($_) foreach $self->AttachTickets;
+    return;
+}
 
-    my $msgid = $MIMEObj->head->get('Message-Id');
+=head2 AddTicket $ID
 
+Attaches a ticket with ID to the message.
 
-    #If we don't have any recipients to send to, don't send a message;
-    unless (    $MIMEObj->head->get('To')
-             || $MIMEObj->head->get('Cc')
-             || $MIMEObj->head->get('Bcc') ) {
-        $RT::Logger->info($msgid.  " No recipients found. Not sending.\n");
-        return (1);
-    }
+Each ticket is attached as multipart entity and all its messages and attachments
+are attached as sub entities in order of creation, but only if transaction type
+is Create or Correspond.
 
-    # PseudoTo (fake to headers) shouldn't get matched for message recipients.
-    # If we don't have any 'To' header, drop in the pseudo-to header.
+=cut
 
-    $self->SetHeader( 'To', join ( ',', @{ $self->{'PseudoTo'} } ) )
-      if ( $self->{'PseudoTo'} && ( @{ $self->{'PseudoTo'} } )
-           and ( !$MIMEObj->head->get('To') ) );
-    if ( $RT::MailCommand eq 'sendmailpipe' ) {
-        eval {
-            open( MAIL, "|$RT::SendmailPath $RT::SendmailArguments" );
-            print MAIL $MIMEObj->as_string;
-            close(MAIL);
-          };
-          if ($@) {
-            $RT::Logger->crit($msgid.  "Could not send mail. -".$@ );
-        }
+sub AddTicket {
+    my $self = shift;
+    my $tid  = shift;
+
+    # XXX: we need a current user here, but who is current user?
+    my $attachs   = RT::Attachments->new($RT::SystemUser);
+    my $txn_alias = $attachs->TransactionAlias;
+    $attachs->Limit( ALIAS => $txn_alias, FIELD => 'Type', VALUE => 'Create' );
+    $attachs->Limit(
+        ALIAS => $txn_alias,
+        FIELD => 'Type',
+        VALUE => 'Correspond'
+    );
+    $attachs->LimitByTicket($tid);
+    $attachs->LimitNotEmpty;
+    $attachs->OrderBy( FIELD => 'Created' );
+
+    my $ticket_mime = MIME::Entity->build(
+        Type        => 'multipart/mixed',
+        Top         => 0,
+        Description => "ticket #$tid",
+    );
+    while ( my $attachment = $attachs->Next ) {
+        $self->AddAttachment( $attachment, $ticket_mime );
     }
-    else {
-       my @mailer_args = ($RT::MailCommand);
-       local $ENV{MAILADDRESS};
+    if ( $ticket_mime->parts ) {
+        my $email_mime = $self->TemplateObj->MIMEObj;
+        $email_mime->make_multipart;
+        $email_mime->add_part($ticket_mime);
+    }
+    return;
+}
 
-        if ( $RT::MailCommand eq 'sendmail' ) {
-           push @mailer_args, $RT::SendmailArguments;
-        }
-        elsif ( $RT::MailCommand eq 'smtp' ) {
-           $ENV{MAILADDRESS} = $RT::SMTPFrom || $MIMEObj->head->get('From');
-           push @mailer_args, (Server => $RT::SMTPServer);
-           push @mailer_args, (Debug => $RT::SMTPDebug);
-        }
-       else {
-           push @mailer_args, $RT::MailParams;
-       }
+=head2 RecordOutgoingMailTransaction MIMEObj
+
+Record a transaction in RT with this outgoing message for future record-keeping purposes
+
+=cut
+
+sub RecordOutgoingMailTransaction {
+    my $self    = shift;
+    my $MIMEObj = shift;
 
-        unless ( $MIMEObj->send( @mailer_args ) ) {
-            $RT::Logger->crit($msgid.  "Could not send mail." );
-            return (0);
+    my @parts = $MIMEObj->parts;
+    my @attachments;
+    my @keep;
+    foreach my $part (@parts) {
+        my $attach = $part->head->get('RT-Attachment');
+        if ($attach) {
+            $RT::Logger->debug(
+                "We found an attachment. we want to not record it.");
+            push @attachments, $attach;
+        } else {
+            $RT::Logger->debug("We found a part. we want to record it.");
+            push @keep, $part;
         }
     }
+    $MIMEObj->parts( \@keep );
+    foreach my $attachment (@attachments) {
+        $MIMEObj->head->add( 'RT-Attachment', $attachment );
+    }
 
+    RT::I18N::SetMIMEEntityToEncoding( $MIMEObj, 'utf-8', 'mime_words_ok' );
 
-     my $success = ($msgid. " sent To: ".$MIMEObj->head->get('To') . " Cc: ".$MIMEObj->head->get('Cc') . " Bcc: ".$MIMEObj->head->get('Bcc'));
-    $success =~ s/\n//gi;
-    $RT::Logger->info($success);
+    my $transaction
+        = RT::Transaction->new( $self->TransactionObj->CurrentUser );
 
-    return (1);
-}
+# XXX: TODO -> Record attachments as references to things in the attachments table, maybe.
+
+    my $type;
+    if ( $self->TransactionObj->Type eq 'Comment' ) {
+        $type = 'CommentEmailRecord';
+    } else {
+        $type = 'EmailRecord';
+    }
 
-# }}}
+    my $msgid = $MIMEObj->head->get('Message-ID');
+    chomp $msgid;
 
-# {{{ Deal with message headers (Set* subs, designed for  easy overriding)
+    my ( $id, $msg ) = $transaction->Create(
+        Ticket         => $self->TicketObj->Id,
+        Type           => $type,
+        Data           => $msgid,
+        MIMEObj        => $MIMEObj,
+        ActivateScrips => 0
+    );
 
-# {{{ sub SetRTSpecialHeaders
+    if ($id) {
+        $self->{'OutgoingMailTransaction'} = $id;
+    } else {
+        $RT::Logger->warning(
+            "Could not record outgoing message transaction: $msg");
+    }
+    return $id;
+}
 
 =head2 SetRTSpecialHeaders 
 
@@ -320,85 +569,272 @@ that don't matter much to anybody else.
 sub SetRTSpecialHeaders {
     my $self = shift;
 
-    $self->SetReferences();
+    $self->SetSubject();
+    $self->SetSubjectToken();
+    $self->SetHeaderAsEncoding( 'Subject',
+        RT->Config->Get('EmailOutputEncoding') )
+        if ( RT->Config->Get('EmailOutputEncoding') );
+    $self->SetReturnAddress();
+    $self->SetReferencesHeaders();
+
+    unless ( $self->TemplateObj->MIMEObj->head->get('Message-ID') ) {
+
+        # Get Message-ID for this txn
+        my $msgid = "";
+        if ( my $msg = $self->TransactionObj->Message->First ) {
+            $msgid = $msg->GetHeader("RT-Message-ID")
+                || $msg->GetHeader("Message-ID");
+        }
 
-    $self->SetMessageID();
+        # If there is one, and we can parse it, then base our Message-ID on it
+        if (    $msgid
+            and $msgid
+            =~ s/<(rt-.*?-\d+-\d+)\.(\d+)-\d+-\d+\@\QRT->Config->Get('Organization')\E>$/
+                         "<$1." . $self->TicketObj->id
+                          . "-" . $self->ScripObj->id
+                          . "-" . $self->ScripActionObj->{_Message_ID}
+                          . "@" . RT->Config->Get('Organization') . ">"/eg
+            and $2 == $self->TicketObj->id
+            )
+        {
+            $self->SetHeader( "Message-ID" => $msgid );
+        } else {
+            $self->SetHeader(
+                'Message-ID' => RT::Interface::Email::GenMessageId(
+                    Ticket      => $self->TicketObj,
+                    Scrip       => $self->ScripObj,
+                    ScripAction => $self->ScripActionObj
+                ),
+            );
+        }
+    }
 
-    $self->SetPrecedence();
+    if (my $precedence = RT->Config->Get('DefaultMailPrecedence')
+        and !$self->TemplateObj->MIMEObj->head->get("Precedence")
+    ) {
+        $self->SetHeader( 'Precedence', $precedence );
+    }
 
-    $self->SetHeader( 'X-RT-Loop-Prevention', $RT::rtname );
+    $self->SetHeader( 'X-RT-Loop-Prevention', RT->Config->Get('rtname') );
     $self->SetHeader( 'RT-Ticket',
-                      $RT::rtname . " #" . $self->TicketObj->id() );
+        RT->Config->Get('rtname') . " #" . $self->TicketObj->id() );
     $self->SetHeader( 'Managed-by',
-                      "RT $RT::VERSION (http://www.bestpractical.com/rt/)" );
-
-    $self->SetHeader( 'RT-Originator',
-                      $self->TransactionObj->CreatorObj->EmailAddress );
-    return ();
+        "RT $RT::VERSION (http://www.bestpractical.com/rt/)" );
+
+# XXX, TODO: use /ShowUser/ShowUserEntry(or something like that) when it would be
+#            refactored into user's method.
+    if ( my $email = $self->TransactionObj->CreatorObj->EmailAddress
+         and RT->Config->Get('UseOriginatorHeader')
+    ) {
+        $self->SetHeader( 'RT-Originator', $email );
+    }
 
 }
 
-# {{{ sub SetReferences
 
-=head2 SetReferences 
-  
-  # This routine will set the References: and In-Reply-To headers,
-# autopopulating it with all the correspondence on this ticket so
-# far. This should make RT responses threadable.
+sub DeferDigestRecipients {
+    my $self = shift;
+    $RT::Logger->debug( "Calling SetRecipientDigests for transaction " . $self->TransactionObj . ", id " . $self->TransactionObj->id );
+
+    # The digest attribute will be an array of notifications that need to
+    # be sent for this transaction.  The array will have the following
+    # format for its objects.
+    # $digest_hash -> {daily|weekly|susp} -> address -> {To|Cc|Bcc}
+    #                                     -> sent -> {true|false}
+    # The "sent" flag will be used by the cron job to indicate that it has
+    # run on this transaction.
+    # In a perfect world we might move this hash construction to the
+    # extension module itself.
+    my $digest_hash = {};
+
+    foreach my $mailfield (@EMAIL_RECIPIENT_HEADERS) {
+        # If we have a "PseudoTo", the "To" contains it, so we don't need to access it
+        next if ( ( $self->{'PseudoTo'} && @{ $self->{'PseudoTo'} } ) && ( $mailfield eq 'To' ) );
+        $RT::Logger->debug( "Working on mailfield $mailfield; recipients are " . join( ',', @{ $self->{$mailfield} } ) );
+
+        # Store the 'daily digest' folk in an array.
+        my ( @send_now, @daily_digest, @weekly_digest, @suspended );
+
+        # Have to get the list of addresses directly from the MIME header
+        # at this point.
+        $RT::Logger->debug( $self->TemplateObj->MIMEObj->head->as_string );
+        foreach my $rcpt ( map { $_->address } $self->AddressesFromHeader($mailfield) ) {
+            next unless $rcpt;
+            my $user_obj = RT::User->new($RT::SystemUser);
+            $user_obj->LoadByEmail($rcpt);
+            if  ( ! $user_obj->id ) {
+                # If there's an email address in here without an associated
+                # RT user, pass it on through.
+                $RT::Logger->debug( "User $rcpt is not associated with an RT user object.  Send mail.");
+                push( @send_now, $rcpt );
+                next;
+            }
 
-=cut
+            my $mailpref = RT->Config->Get( 'EmailFrequency', $user_obj ) || '';
+            $RT::Logger->debug( "Got user mail preference '$mailpref' for user $rcpt");
+
+            if ( $mailpref =~ /daily/i ) { push( @daily_digest, $rcpt ) }
+            elsif ( $mailpref =~ /weekly/i ) { push( @weekly_digest, $rcpt ) }
+            elsif ( $mailpref =~ /suspend/i ) { push( @suspended, $rcpt ) }
+            else { push( @send_now, $rcpt ) }
+        }
+
+        # Reset the relevant mail field.
+        $RT::Logger->debug( "Removing deferred recipients from $mailfield: line");
+        if (@send_now) {
+            $self->SetHeader( $mailfield, join( ', ', @send_now ) );
+        } else {    # No recipients!  Remove the header.
+            $self->TemplateObj->MIMEObj->head->delete($mailfield);
+        }
 
-sub SetReferences {
+        # Push the deferred addresses into the appropriate field in
+        # our attribute hash, with the appropriate mail header.
+        $RT::Logger->debug(
+            "Setting deferred recipients for attribute creation");
+        $digest_hash->{'daily'}->{$_} = {'header' => $mailfield , _sent => 0}  for (@daily_digest);
+        $digest_hash->{'weekly'}->{$_} ={'header' =>  $mailfield, _sent => 0}  for (@weekly_digest);
+        $digest_hash->{'susp'}->{$_} = {'header' => $mailfield, _sent =>0 }  for (@suspended);
+    }
+
+    if ( scalar keys %$digest_hash ) {
+
+        # Save the hash so that we can add it as an attribute to the
+        # outgoing email transaction.
+        $self->{'Deferred'} = $digest_hash;
+    } else {
+        $RT::Logger->debug( "No recipients found for deferred delivery on "
+                . "transaction #"
+                . $self->TransactionObj->id );
+    }
+}
+
+
+    
+sub RecordDeferredRecipients {
     my $self = shift;
+    return unless exists $self->{'Deferred'};
 
-    # TODO: this one is broken.  What is this email really a reply to?
-    # If it's a reply to an incoming message, we'll need to use the
-    # actual message-id from the appropriate Attachment object.  For
-    # incoming mails, we would like to preserve the In-Reply-To and/or
-    # References.
+    my $txn_id = $self->{'OutgoingMailTransaction'};
+    return unless $txn_id;
 
-    $self->SetHeader( 'In-Reply-To',
-                   "<rt-" . $self->TicketObj->id() . "\@" . $RT::rtname . ">" );
+    my $txn_obj = RT::Transaction->new( $self->CurrentUser );
+    $txn_obj->Load( $txn_id );
+    my( $ret, $msg ) = $txn_obj->AddAttribute(
+        Name => 'DeferredRecipients',
+        Content => $self->{'Deferred'}
+    );
+    $RT::Logger->warning( "Unable to add deferred recipients to outgoing transaction: $msg" ) 
+        unless $ret;
 
-    # TODO We should always add References headers for all message-ids
-    # of previous messages related to this ticket.
+    return ($ret,$msg);
 }
 
-# }}}
+=head2 SquelchMailTo [@ADDRESSES]
+
+Mark ADDRESSES to be removed from list of the recipients. Returns list of the addresses.
+To empty list pass undefined argument.
 
-# {{{ sub SetMessageID
+B<Note> that this method can be called as class method and works globaly. Don't forget to
+clean this list when blocking is not required anymore, pass undef to do this.
 
-=head2 SetMessageID 
+=cut
+
+{
+    my $squelch = [];
+
+    sub SquelchMailTo {
+        my $self = shift;
+        if (@_) {
+            $squelch = [ grep defined, @_ ];
+        }
+        return @$squelch;
+    }
+}
 
-Without this one, threading won't work very nice in email agents.
-Anyway, I'm not really sure it's that healthy if we need to send
-several separate/different emails about the same transaction.
+=head2 RemoveInappropriateRecipients
+
+Remove addresses that are RT addresses or that are on this transaction's blacklist
 
 =cut
 
-sub SetMessageID {
+sub RemoveInappropriateRecipients {
     my $self = shift;
 
-    # TODO this one might be sort of broken.  If we have several scrips +++
-    # sending several emails to several different persons, we need to
-    # pull out different message-ids.  I'd suggest message ids like
-    # "rt-ticket#-transaction#-scrip#-receipient#"
-
-    $self->SetHeader( 'Message-ID',
-                      "<rt-"
-                        . $RT::VERSION ."-"
-                        . $self->TicketObj->id() . "-"
-                        . $self->TransactionObj->id() . "."
-                        . rand(20) . "\@"
-                        . $RT::Organization . ">" )
-      unless $self->TemplateObj->MIMEObj->head->get('Message-ID');
-}
+    my @blacklist = ();
 
-# }}}
+    # If there are no recipients, don't try to send the message.
+    # If the transaction has content and has the header RT-Squelch-Replies-To
+
+    my $msgid = $self->TemplateObj->MIMEObj->head->get('Message-Id');
+    if ( my $attachment = $self->TransactionObj->Attachments->First ) {
+
+        if ( $attachment->GetHeader('RT-DetectedAutoGenerated') ) {
+
+            # What do we want to do with this? It's probably (?) a bounce
+            # caused by one of the watcher addresses being broken.
+            # Default ("true") is to redistribute, for historical reasons.
+
+            if ( !RT->Config->Get('RedistributeAutoGeneratedMessages') ) {
+
+                # Don't send to any watchers.
+                @{ $self->{$_} } = () for (@EMAIL_RECIPIENT_HEADERS);
+                $RT::Logger->info( $msgid
+                        . " The incoming message was autogenerated. "
+                        . "Not redistributing this message based on site configuration."
+                );
+            } elsif ( RT->Config->Get('RedistributeAutoGeneratedMessages') eq
+                'privileged' )
+            {
+
+                # Only send to "privileged" watchers.
+                foreach my $type (@EMAIL_RECIPIENT_HEADERS) {
+                    foreach my $addr ( @{ $self->{$type} } ) {
+                        my $user = RT::User->new($RT::SystemUser);
+                        $user->LoadByEmail($addr);
+                        push @blacklist, $addr if ( !$user->Privileged );
+                    }
+                }
+                $RT::Logger->info( $msgid
+                        . " The incoming message was autogenerated. "
+                        . "Not redistributing this message to unprivileged users based on site configuration."
+                );
+            }
+        }
+
+        if ( my $squelch = $attachment->GetHeader('RT-Squelch-Replies-To') ) {
+            push @blacklist, split( /,/, $squelch );
+        }
+    }
+
+# Let's grab the SquelchMailTo attribue and push those entries into the @blacklist
+    push @blacklist, map $_->Content, $self->TicketObj->SquelchMailTo;
+    push @blacklist, $self->SquelchMailTo;
+
+    # Cycle through the people we're sending to and pull out anyone on the
+    # system blacklist
 
-# }}}
+    # Trim leading and trailing spaces. 
+    @blacklist = map { RT::User->CanonicalizeEmailAddress( $_->address ) } Email::Address->parse(join(', ', grep {defined} @blacklist));
 
-# {{{ sub SetReturnAddress
+    foreach my $type (@EMAIL_RECIPIENT_HEADERS) {
+        my @addrs;
+        foreach my $addr ( @{ $self->{$type} } ) {
+
+         # Weed out any RT addresses. We really don't want to talk to ourselves!
+         # If we get a reply back, that means it's not an RT address
+            if ( !RT::EmailParser->CullRTAddresses($addr) ) {
+                $RT::Logger->info( $msgid . "$addr appears to point to this RT instance. Skipping" );
+                next;
+            }
+            if ( grep /^\Q$addr\E$/, @blacklist ) {
+                $RT::Logger->info( $msgid . "$addr was blacklisted for outbound mail on this transaction. Skipping");
+                next;
+            }
+            push @addrs, $addr;
+        }
+        @{ $self->{$type} } = @addrs;
+    }
+}
 
 =head2 SetReturnAddress is_comment => BOOLEAN
 
@@ -409,8 +845,11 @@ Calculate and set From and Reply-To headers based on the is_comment flag.
 sub SetReturnAddress {
 
     my $self = shift;
-    my %args = ( is_comment => 0,
-                 @_ );
+    my %args = (
+        is_comment => 0,
+        friendly_name => undef,
+        @_
+    );
 
     # From and Reply-To
     # $args{is_comment} should be set if the comment address is to be used.
@@ -418,29 +857,37 @@ sub SetReturnAddress {
 
     if ( $args{'is_comment'} ) {
         $replyto = $self->TicketObj->QueueObj->CommentAddress
-          || $RT::CommentAddress;
-    }
-    else {
+            || RT->Config->Get('CommentAddress');
+    } else {
         $replyto = $self->TicketObj->QueueObj->CorrespondAddress
-          || $RT::CorrespondAddress;
+            || RT->Config->Get('CorrespondAddress');
     }
 
     unless ( $self->TemplateObj->MIMEObj->head->get('From') ) {
-       if ($RT::UseFriendlyFromLine) {
-           my $friendly_name = $self->TransactionObj->CreatorObj->RealName;
-           if ( $friendly_name =~ /^"(.*)"$/ ) {    # a quoted string
-               $friendly_name = $1;
-           }
-
-           $friendly_name =~ s/"/\\"/g;
-           $self->SetHeader( 'From',
-                       sprintf($RT::FriendlyFromLineFormat, 
-                $self->MIMEEncodeString( $friendly_name, $RT::EmailOutputEncoding ), $replyto),
-           );
-       }
-       else {
-           $self->SetHeader( 'From', $replyto );
-       }
+        if ( RT->Config->Get('UseFriendlyFromLine') ) {
+            my $friendly_name = $args{friendly_name};
+
+            unless ( $friendly_name ) {
+                $friendly_name = $self->TransactionObj->CreatorObj->FriendlyName;
+                if ( $friendly_name =~ /^"(.*)"$/ ) {    # a quoted string
+                    $friendly_name = $1;
+                }
+            }
+
+            $friendly_name =~ s/"/\\"/g;
+            $self->SetHeader(
+                'From',
+                sprintf(
+                    RT->Config->Get('FriendlyFromLineFormat'),
+                    $self->MIMEEncodeString(
+                        $friendly_name, RT->Config->Get('EmailOutputEncoding')
+                    ),
+                    $replyto
+                ),
+            );
+        } else {
+            $self->SetHeader( 'From', $replyto );
+        }
     }
 
     unless ( $self->TemplateObj->MIMEObj->head->get('Reply-To') ) {
@@ -449,10 +896,6 @@ sub SetReturnAddress {
 
 }
 
-# }}}
-
-# {{{ sub SetHeader
-
 =head2 SetHeader FIELD, VALUE
 
 Set the FIELD of the current MIME object into VALUE.
@@ -466,163 +909,157 @@ sub SetHeader {
 
     chomp $val;
     chomp $field;
-    $self->TemplateObj->MIMEObj->head->fold_length( $field, 10000 );
-    $self->TemplateObj->MIMEObj->head->replace( $field,     $val );
-    return $self->TemplateObj->MIMEObj->head->get($field);
+    my $head = $self->TemplateObj->MIMEObj->head;
+    $head->fold_length( $field, 10000 );
+    $head->replace( $field, $val );
+    return $head->get($field);
 }
 
-# }}}
-
-# {{{ sub SetRecipients
-
-=head2 SetRecipients
+=head2 SetSubject
 
-Dummy method to be overriden by subclasses which want to set the recipients.
+This routine sets the subject. it does not add the rt tag. That gets done elsewhere
+If subject is already defined via template, it uses that. otherwise, it tries to get
+the transaction's subject.
 
-=cut
+=cut 
 
-sub SetRecipients {
+sub SetSubject {
     my $self = shift;
-    return ();
-}
+    my $subject;
 
-# }}}
+    if ( $self->TemplateObj->MIMEObj->head->get('Subject') ) {
+        return ();
+    }
 
-# {{{ sub SetTo
+    # don't use Transaction->Attachments because it caches
+    # and anything which later calls ->Attachments will be hurt
+    # by our RowsPerPage() call.  caching is hard.
+    my $message = RT::Attachments->new( $self->CurrentUser );
+    $message->Limit( FIELD => 'TransactionId', VALUE => $self->TransactionObj->id);
+    $message->OrderBy( FIELD => 'id', ORDER => 'ASC' );
+    $message->RowsPerPage(1);
+
+    if ( $self->{'Subject'} ) {
+        $subject = $self->{'Subject'};
+    } elsif ( my $first = $message->First ) {
+        my $tmp = $first->GetHeader('Subject');
+        $subject = defined $tmp ? $tmp : $self->TicketObj->Subject;
+    } else {
+        $subject = $self->TicketObj->Subject;
+    }
+    $subject = '' unless defined $subject;
+    chomp $subject;
 
-=head2 SetTo
+    $subject =~ s/(\r\n|\n|\s)/ /g;
 
-Takes a string that is the addresses you want to send mail to
+    $self->SetHeader( 'Subject', $subject );
 
-=cut
-
-sub SetTo {
-    my $self      = shift;
-    my $addresses = shift;
-    return $self->SetHeader( 'To', $addresses );
 }
 
-# }}}
-
-# {{{ sub SetCc
-
-=head2 SetCc
+=head2 SetSubjectToken
 
-Takes a string that is the addresses you want to Cc
+This routine fixes the RT tag in the subject. It's unlikely that you want to overwrite this.
 
 =cut
 
-sub SetCc {
-    my $self      = shift;
-    my $addresses = shift;
+sub SetSubjectToken {
+    my $self = shift;
 
-    return $self->SetHeader( 'Cc', $addresses );
+    my $head = $self->TemplateObj->MIMEObj->head;
+    $head->replace(
+        Subject => RT::Interface::Email::AddSubjectTag(
+            Encode::decode_utf8( $head->get('Subject') ),
+            $self->TicketObj,
+        ),
+    );
 }
 
-# }}}
-
-# {{{ sub SetBcc
-
-=head2 SetBcc
+=head2 SetReferencesHeaders
 
-Takes a string that is the addresses you want to Bcc
+Set References and In-Reply-To headers for this message.
 
 =cut
 
-sub SetBcc {
-    my $self      = shift;
-    my $addresses = shift;
-
-    return $self->SetHeader( 'Bcc', $addresses );
-}
-
-# }}}
-
-# {{{ sub SetPrecedence
-
-sub SetPrecedence {
+sub SetReferencesHeaders {
     my $self = shift;
-
-    unless ( $self->TemplateObj->MIMEObj->head->get("Precedence") ) {
-        $self->SetHeader( 'Precedence', "bulk" );
+    my ( @in_reply_to, @references, @msgid );
+
+    if ( my $top = $self->TransactionObj->Message->First ) {
+        @in_reply_to = split( /\s+/m, $top->GetHeader('In-Reply-To') || '' );
+        @references  = split( /\s+/m, $top->GetHeader('References')  || '' );
+        @msgid       = split( /\s+/m, $top->GetHeader('Message-ID')  || '' );
+    } else {
+        return (undef);
     }
-}
 
-# }}}
+    # There are two main cases -- this transaction was created with
+    # the RT Web UI, and hence we want to *not* append its Message-ID
+    # to the References and In-Reply-To.  OR it came from an outside
+    # source, and we should treat it as per the RFC
+    my $org = RT->Config->Get('Organization');
+    if ( "@msgid" =~ /<(rt-.*?-\d+-\d+)\.(\d+)-0-0\@\Q$org\E>/ ) {
+
+        # Make all references which are internal be to version which we
+        # have sent out
+
+        for ( @references, @in_reply_to ) {
+            s/<(rt-.*?-\d+-\d+)\.(\d+-0-0)\@\Q$org\E>$/
+          "<$1." . $self->TicketObj->id .
+             "-" . $self->ScripObj->id .
+             "-" . $self->ScripActionObj->{_Message_ID} .
+             "@" . $org . ">"/eg
+        }
 
-# {{{ sub SetSubject
+        # In reply to whatever the internal message was in reply to
+        $self->SetHeader( 'In-Reply-To', join( " ", (@in_reply_to) ) );
 
-=head2 SetSubject
+        # Default the references to whatever we're in reply to
+        @references = @in_reply_to unless @references;
 
-This routine sets the subject. it does not add the rt tag. that gets done elsewhere
-If $self->{'Subject'} is already defined, it uses that. otherwise, it tries to get
-the transaction's subject.
+        # References are unchanged from internal
+    } else {
 
-=cut 
+        # In reply to that message
+        $self->SetHeader( 'In-Reply-To', join( " ", (@msgid) ) );
 
-sub SetSubject {
-    my $self = shift;
-    my $subject;
-
-    unless ( $self->TemplateObj->MIMEObj->head->get('Subject') ) {
-        my $message = $self->TransactionObj->Attachments;
-        my $ticket  = $self->TicketObj->Id;
+        # Default the references to whatever we're in reply to
+        @references = @in_reply_to unless @references;
 
-        if ( $self->{'Subject'} ) {
-            $subject = $self->{'Subject'};
-        }
-        elsif (    ( $message->First() )
-                && ( $message->First->Headers ) ) {
-            my $header = $message->First->Headers();
-            $header =~ s/\n\s+/ /g;
-            if ( $header =~ /^Subject: (.*?)$/m ) {
-                $subject = $1;
-            }
-            else {
-                $subject = $self->TicketObj->Subject();
-            }
+        # Push that message onto the end of the references
+        push @references, @msgid;
+    }
 
-        }
-        else {
-            $subject = $self->TicketObj->Subject();
-        }
+    # Push pseudo-ref to the front
+    my $pseudo_ref = $self->PseudoReference;
+    @references = ( $pseudo_ref, grep { $_ ne $pseudo_ref } @references );
 
-        $subject =~ s/(\r\n|\n|\s)/ /gi;
+    # If there are more than 10 references headers, remove all but the
+    # first four and the last six (Gotta keep this from growing
+    # forever)
+    splice( @references, 4, -6 ) if ( $#references >= 10 );
 
-        chomp $subject;
-        $self->SetHeader( 'Subject', $subject );
+    # Add on the references
+    $self->SetHeader( 'References', join( " ", @references ) );
+    $self->TemplateObj->MIMEObj->head->fold_length( 'References', 80 );
 
-    }
-    return ($subject);
 }
 
-# }}}
-
-# {{{ sub SetSubjectToken
+=head2 PseudoReference
 
-=head2 SetSubjectToken
-
-This routine fixes the RT tag in the subject. It's unlikely that you want to overwrite this.
+Returns a fake Message-ID: header for the ticket to allow a base level of threading
 
 =cut
 
-sub SetSubjectToken {
+sub PseudoReference {
+
     my $self = shift;
-    my $tag  = "[$RT::rtname #" . $self->TicketObj->id . "]";
-    my $sub  = $self->TemplateObj->MIMEObj->head->get('Subject');
-    unless ( $sub =~ /\Q$tag\E/ ) {
-        $sub =~ s/(\r\n|\n|\s)/ /gi;
-        chomp $sub;
-        $self->TemplateObj->MIMEObj->head->replace( 'Subject', "$tag $sub" );
-    }
+    my $pseudo_ref
+        = '<RT-Ticket-'
+        . $self->TicketObj->id . '@'
+        . RT->Config->Get('Organization') . '>';
+    return $pseudo_ref;
 }
 
-# }}}
-
-# }}}
-
-# {{{
-
 =head2 SetHeaderAsEncoding($field_name, $charset_encoding)
 
 This routine converts the field into specified charset encoding.
@@ -633,53 +1070,34 @@ sub SetHeaderAsEncoding {
     my $self = shift;
     my ( $field, $enc ) = ( shift, shift );
 
-    if ($field eq 'From' and $RT::SMTPFrom) {
-        $self->TemplateObj->MIMEObj->head->replace( $field, $RT::SMTPFrom );
-       return;
-    }
-
-    my $value = $self->TemplateObj->MIMEObj->head->get($field);
-
-    # don't bother if it's us-ascii
+    my $head = $self->TemplateObj->MIMEObj->head;
 
-    # See RT::I18N, 'NOTES:  Why Encode::_utf8_off before Encode::from_to'
-
-    $value =  $self->MIMEEncodeString($value, $enc);
-
-    $self->TemplateObj->MIMEObj->head->replace( $field, $value );
+    if ( lc($field) eq 'from' and RT->Config->Get('SMTPFrom') ) {
+        $head->replace( $field, RT->Config->Get('SMTPFrom') );
+        return;
+    }
 
+    my $value = $head->get( $field );
+    $value = $self->MIMEEncodeString( $value, $enc );
+    $head->replace( $field, $value );
 
-} 
-# }}}
+}
 
-# {{{ MIMENcodeString
+=head2 MIMEEncodeString
 
-=head2 MIMEEncodeString STRING ENCODING
+Takes a perl string and optional encoding pass it over
+L<RT::Interface::Email/EncodeToMIME>.
 
-Takes a string and a possible encoding and returns the string wrapped in MIME goo.
+Basicly encode a string using B encoding according to RFC2047.
 
 =cut
 
 sub MIMEEncodeString {
-    my  $self = shift;
-    my $value = shift;
-    my $enc = shift;
-
-    chomp $value;
-    return ($value) unless $value =~ /[^\x20-\x7e]/;
-
-    $value =~ s/\s*$//;
-    Encode::_utf8_off($value);
-    my $res = Encode::from_to( $value, "utf-8", $enc );
-    $value = encode_mimeword( $value,  'B', $enc );
+    my $self  = shift;
+    return RT::Interface::Email::EncodeToMIME( String => $_[0], Charset => $_[1] );
 }
 
-# }}}
-
-eval "require RT::Action::SendEmail_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SendEmail_Vendor.pm});
-eval "require RT::Action::SendEmail_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Action/SendEmail_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
 
index 2ed5201..e9a3dc6 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -110,7 +135,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -119,14 +144,14 @@ Returns the current value of id.
 =cut
 
 
-=item TransactionId
+=head2 TransactionId
 
 Returns the current value of TransactionId. 
 (In the database, TransactionId is stored as int(11).)
 
 
 
-=item SetTransactionId VALUE
+=head2 SetTransactionId VALUE
 
 
 Set TransactionId to VALUE. 
@@ -137,14 +162,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Parent
+=head2 Parent
 
 Returns the current value of Parent. 
 (In the database, Parent is stored as int(11).)
 
 
 
-=item SetParent VALUE
+=head2 SetParent VALUE
 
 
 Set Parent to VALUE. 
@@ -155,14 +180,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item MessageId
+=head2 MessageId
 
 Returns the current value of MessageId. 
 (In the database, MessageId is stored as varchar(160).)
 
 
 
-=item SetMessageId VALUE
+=head2 SetMessageId VALUE
 
 
 Set MessageId to VALUE. 
@@ -173,14 +198,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Subject
+=head2 Subject
 
 Returns the current value of Subject. 
 (In the database, Subject is stored as varchar(255).)
 
 
 
-=item SetSubject VALUE
+=head2 SetSubject VALUE
 
 
 Set Subject to VALUE. 
@@ -191,14 +216,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Filename
+=head2 Filename
 
 Returns the current value of Filename. 
 (In the database, Filename is stored as varchar(255).)
 
 
 
-=item SetFilename VALUE
+=head2 SetFilename VALUE
 
 
 Set Filename to VALUE. 
@@ -209,14 +234,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ContentType
+=head2 ContentType
 
 Returns the current value of ContentType. 
 (In the database, ContentType is stored as varchar(80).)
 
 
 
-=item SetContentType VALUE
+=head2 SetContentType VALUE
 
 
 Set ContentType to VALUE. 
@@ -227,14 +252,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ContentEncoding
+=head2 ContentEncoding
 
 Returns the current value of ContentEncoding. 
 (In the database, ContentEncoding is stored as varchar(80).)
 
 
 
-=item SetContentEncoding VALUE
+=head2 SetContentEncoding VALUE
 
 
 Set ContentEncoding to VALUE. 
@@ -245,14 +270,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Content
+=head2 Content
 
 Returns the current value of Content. 
 (In the database, Content is stored as longtext.)
 
 
 
-=item SetContent VALUE
+=head2 SetContent VALUE
 
 
 Set Content to VALUE. 
@@ -263,14 +288,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Headers
+=head2 Headers
 
 Returns the current value of Headers. 
 (In the database, Headers is stored as longtext.)
 
 
 
-=item SetHeaders VALUE
+=head2 SetHeaders VALUE
 
 
 Set Headers to VALUE. 
@@ -281,7 +306,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -290,7 +315,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -300,55 +325,38 @@ Returns the current value of Created.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         TransactionId => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Parent => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         MessageId => 
-               {read => 1, write => 1, type => 'varchar(160)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 160,  is_blob => 0,  is_numeric => 0,  type => 'varchar(160)', default => ''},
         Subject => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Filename => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         ContentType => 
-               {read => 1, write => 1, type => 'varchar(80)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 80,  is_blob => 0,  is_numeric => 0,  type => 'varchar(80)', default => ''},
         ContentEncoding => 
-               {read => 1, write => 1, type => 'varchar(80)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 80,  is_blob => 0,  is_numeric => 0,  type => 'varchar(80)', default => ''},
         Content => 
-               {read => 1, write => 1, type => 'longtext', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longtext', default => ''},
         Headers => 
-               {read => 1, write => 1, type => 'longtext', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longtext', default => ''},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::Attachment_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Attachment_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Attachment_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Attachment_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Attachment_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Attachment_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -358,7 +366,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 177cdd0..40f25e4 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Attachment item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Attachment->new($self->CurrentUser));
 }
-
-        eval "require RT::Attachments_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Attachments_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Attachments_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Attachments_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Attachments_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Attachments_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 4519fcf..7558794 100644 (file)
@@ -1,34 +1,55 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
 
 package RT::Condition::AnyTransaction;
-require RT::Condition::Generic;
+use base 'RT::Condition';
 
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Condition::Generic);
 
 
 =head2 IsApplicable
@@ -42,10 +63,7 @@ sub IsApplicable {
     return(1);
 }
 
-eval "require RT::Condition::AnyTransaction_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/AnyTransaction_Vendor.pm});
-eval "require RT::Condition::AnyTransaction_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/AnyTransaction_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
 
index bd26931..a3bfa75 100755 (executable)
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 =head1 NAME
 
-  RT::Condition::Generic - ;
+  RT::Condition::Generic - deprecated, see RT::Condition
 
 =head1 SYNOPSIS
 
-    use RT::Condition::Generic;
-    my $foo = new RT::Condition::IsApplicable( 
-               TransactionObj => $tr, 
-               TicketObj => $ti, 
-               ScripObj => $scr, 
-               Argument => $arg, 
-               Type => $type);
-
-    if ($foo->IsApplicable) {
-          # do something
-    }
-
+  use RT::Condition::Generic;
 
 =head1 DESCRIPTION
 
+This module is provided only for backwards compatibility.
 
 =head1 METHODS
 
 
-=begin testing
-
-ok (require RT::Condition::Generic);
-
-=end testing
-
-
 =cut
 
-package RT::Condition::Generic;
-
-use RT::Base;
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Base);
-
-# {{{ sub new 
-sub new  {
-  my $proto = shift;
-  my $class = ref($proto) || $proto;
-  my $self  = {};
-  bless ($self, $class);
-  $self->_Init(@_);
-  return $self;
-}
-# }}}
-
-# {{{ sub _Init 
-sub _Init  {
-  my $self = shift;
-  my %args = ( TransactionObj => undef,
-              TicketObj => undef,
-              ScripObj => undef,
-              TemplateObj => undef,
-              Argument => undef,
-              ApplicableTransTypes => undef,
-              @_ );
-  
-  $self->{'Argument'} = $args{'Argument'};
-  $self->{'ScripObj'} = $args{'ScripObj'};
-  $self->{'TicketObj'} = $args{'TicketObj'};
-  $self->{'TransactionObj'} = $args{'TransactionObj'};
-  $self->{'ApplicableTransTypes'} = $args{'ApplicableTransTypes'};
-}
-# }}}
-
-# Access Scripwide data
-
-# {{{ sub Argument 
-
-=head2 Argument
-
-Return the optional argument associated with this ScripCondition
-
-=cut
-
-sub Argument  {
-  my $self = shift;
-  return($self->{'Argument'});
-}
-# }}}
-
-# {{{ sub TicketObj
-
-=head2 TicketObj
-
-Return the ticket object we're talking about
-
-=cut
-
-sub TicketObj  {
-  my $self = shift;
-  return($self->{'TicketObj'});
-}
-# }}}
-
-# {{{ sub ScripObj
-
-=head2 ScripObj
-
-Return the Scrip object we're talking about
-
-=cut
-
-sub ScripObj  {
-  my $self = shift;
-  return($self->{'ScripObj'});
-}
-# }}}
-# {{{ sub TransactionObj
-
-=head2 TransactionObj
-
-Return the transaction object we're talking about
-
-=cut
-
-sub TransactionObj  {
-  my $self = shift;
-  return($self->{'TransactionObj'});
-}
-# }}}
-
-# {{{ sub Type
-
-=head2 Type 
-
-
-
-=cut
-
-sub ApplicableTransTypes  {
-  my $self = shift;
-  return($self->{'ApplicableTransTypes'});
-}
-# }}}
-
-
-# Scrip methods
-
-
-#What does this type of Action does
-
-# {{{ sub Describe 
-sub Describe  {
-  my $self = shift;
-  return ($self->loc("No description for [_1]", ref $self));
-}
-# }}}
-
-
-#Parse the templates, get things ready to go.
-
-#If this rule applies to this transaction, return true.
-
-# {{{ sub IsApplicable 
-sub IsApplicable  {
-  my $self = shift;
-  return(undef);
-}
-# }}}
-
-# {{{ sub DESTROY
-sub DESTROY {
-    my $self = shift;
-
-    # We need to clean up all the references that might maybe get
-    # oddly circular
-    $self->{'TemplateObj'} =undef
-    $self->{'TicketObj'} = undef;
-    $self->{'TransactionObj'} = undef;
-    $self->{'ScripObj'} = undef;
-     
-}
-
-# }}}
+use warnings;
+package RT::Condition::Generic;
+use base 'RT::Condition';
 
-eval "require RT::Condition::Generic_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/Generic_Vendor.pm});
-eval "require RT::Condition::Generic_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/Generic_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
+
index 8afabcd..b20a5ac 100644 (file)
@@ -1,35 +1,54 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
-
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
 
 package RT::Condition::StatusChange;
-require RT::Condition::Generic;
-
+use base 'RT::Condition';
 use strict;
-use vars qw/@ISA/;
-@ISA = qw(RT::Condition::Generic);
 
 
 =head2 IsApplicable
@@ -50,10 +69,7 @@ sub IsApplicable {
     }
 }
 
-eval "require RT::Condition::StatusChange_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/StatusChange_Vendor.pm});
-eval "require RT::Condition::StatusChange_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Condition/StatusChange_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
 
index 4ca2f98..85b95f8 100755 (executable)
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 =head1 NAME
 
   RT::CurrentUser - an RT object representing the current user
 
 =head1 SYNOPSIS
 
-  use RT::CurrentUser
+    use RT::CurrentUser;
+
+    # laod
+    my $current_user = new RT::CurrentUser;
+    $current_user->Load(...);
+    # or
+    my $current_user = RT::CurrentUser->new( $user_obj );
+    # or
+    my $current_user = RT::CurrentUser->new( $address || $name || $id );
+
+    # manipulation
+    $current_user->UserObj->SetName('new_name');
 
 
 =head1 DESCRIPTION
 
+B<Read-only> subclass of L<RT::User> class. Used to define the current
+user. You should pass an instance of this class to constructors of
+many RT classes, then the instance used to check ACLs and localize
+strings.
 
 =head1 METHODS
 
+See also L<RT::User> for a list of methods this class has.
 
-=begin testing
-
-ok (require RT::CurrentUser);
+=head2 new
 
-=end testing
+Returns new CurrentUser object. Unlike all other classes of RT it takes
+either subclass of C<RT::User> class object or scalar value that is
+passed to Load method.
 
 =cut
 
 
 package RT::CurrentUser;
 
-use RT::Record;
 use RT::I18N;
 
 use strict;
-use vars qw/@ISA/;
-@ISA= qw(RT::Record);
+use warnings;
 
-# {{{ sub _Init 
+use base qw/RT::User/;
 
 #The basic idea here is that $self->CurrentUser is always supposed
 # to be a CurrentUser object. but that's hard to do when we're trying to load
 # the CurrentUser object
 
-sub _Init  {
-  my $self = shift;
-  my $Name = shift;
-
-  $self->{'table'} = "Users";
+sub _Init {
+    my $self = shift;
+    my $User = shift;
+
+    $self->{'table'} = "Users";
+
+    if ( defined $User ) {
+
+        if ( UNIVERSAL::isa( $User, 'RT::User' ) ) {
+            $self->LoadById( $User->id );
+        }
+        elsif ( ref $User ) {
+            $RT::Logger->crit(
+                "RT::CurrentUser->new() called with a bogus argument: $User");
+        }
+        else {
+            $self->Load( $User );
+        }
+    }
 
-  if (defined($Name)) {
-    $self->Load($Name);
-  }
-  
-  $self->CurrentUser($self);
+    $self->_BuildTableAttributes;
 
 }
-# }}}
 
-# {{{ sub Create
+=head2 Create, Delete and Set*
+
+As stated above it's a subclass of L<RT::User>, but this class is read-only
+and calls to these methods are illegal. Return 'permission denied' message
+and log an error.
+
+=cut
 
 sub Create {
     my $self = shift;
+    $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation');
     return (0, $self->loc('Permission Denied'));
 }
 
-# }}}
-
-# {{{ sub Delete
-
 sub Delete {
     my $self = shift;
+    $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation');
     return (0, $self->loc('Permission Denied'));
 }
 
-# }}}
-
-# {{{ sub UserObj
-
-=head2 UserObj
-
-  Returns the RT::User object associated with this CurrentUser object.
-
-=cut
-
-sub UserObj {
-    my $self = shift;
-    
-    unless ($self->{'UserObj'}) {
-       use RT::User;
-       $self->{'UserObj'} = RT::User->new($self);
-       unless ($self->{'UserObj'}->Load($self->Id)) {
-           $RT::Logger->err($self->loc("Couldn't load [_1] from the users database.\n", $self->Id));
-       }
-       
-    }
-    return ($self->{'UserObj'});
-}
-# }}}
-
-# {{{ sub PrincipalObj 
-
-=head2 PrincipalObj
-
-    Returns this user's principal object.  this is just a helper routine for
-    $self->UserObj->PrincipalObj
-
-=cut
-
-sub PrincipalObj {
+sub _Set {
     my $self = shift;
-    return($self->UserObj->PrincipalObj);
+    $RT::Logger->error('RT::CurrentUser is read-only, RT::User for manipulation');
+    return (0, $self->loc('Permission Denied'));
 }
 
+=head2 UserObj
 
-# }}}
-
-
-# {{{ sub PrincipalId 
-
-=head2 PrincipalId
-
-    Returns this user's principal Id.  this is just a helper routine for
-    $self->UserObj->PrincipalId
+Returns the L<RT::User> object associated with this CurrentUser object.
 
 =cut
 
-sub PrincipalId {
+sub UserObj {
     my $self = shift;
-    return($self->UserObj->PrincipalId);
-}
 
-
-# }}}
-
-
-# {{{ sub _Accessible 
-sub _Accessible  {
-  my $self = shift;
-  my %Cols = (
-             Name => 'read',
-             Gecos => 'read',
-             RealName => 'read',
-             Password => 'neither',
-             EmailAddress => 'read',
-             Privileged => 'read',
-             IsAdministrator => 'read'
-            );
-  return($self->SUPER::_Accessible(@_, %Cols));
+    my $user = RT::User->new( $self );
+    unless ( $user->LoadById( $self->Id ) ) {
+        $RT::Logger->error(
+            $self->loc("Couldn't load [_1] from the users database.\n", $self->Id)
+        );
+    }
+    return $user;
 }
-# }}}
 
-# {{{ sub LoadByEmail
-
-=head2 LoadByEmail
-
-Loads a User into this CurrentUser object.
-Takes the email address of the user to load.
-
-=cut
-
-sub LoadByEmail  {
-    my $self = shift;
-    my $identifier = shift;
-
-    $identifier = RT::User::CanonicalizeEmailAddress(undef, $identifier);
-        
-    $self->LoadByCol("EmailAddress",$identifier);
-    
+sub _CoreAccessible  {
+     {
+         Name           => { 'read' => 1 },
+           Gecos        => { 'read' => 1 },
+           RealName     => { 'read' => 1 },
+           Lang     => { 'read' => 1 },
+           Password     => { 'read' => 0, 'write' => 0 },
+          EmailAddress => { 'read' => 1, 'write' => 0 }
+     };
+  
 }
-# }}}
-
-# {{{ sub LoadByGecos
 
 =head2 LoadByGecos
 
@@ -199,155 +188,62 @@ Takes a unix username as its only argument.
 
 sub LoadByGecos  {
     my $self = shift;
-    my $identifier = shift;
-        
-    $self->LoadByCol("Gecos",$identifier);
-    
+    return $self->LoadByCol( "Gecos", shift );
 }
-# }}}
-
-# {{{ sub LoadByName
 
 =head2 LoadByName
 
 Loads a User into this CurrentUser object.
 Takes a Name.
-=cut
-
-sub LoadByName {
-    my $self = shift;
-    my $identifier = shift;
-    $self->LoadByCol("Name",$identifier);
-    
-}
-# }}}
-
-# {{{ sub Load 
-
-=head2 Load
-
-Loads a User into this CurrentUser object.
-Takes either an integer (users id column reference) or a Name
-The latter is deprecated. Instead, you should use LoadByName.
-Formerly, this routine also took email addresses. 
-
-=cut
-
-sub Load  {
-  my $self = shift;
-  my $identifier = shift;
-
-  #if it's an int, load by id. otherwise, load by name.
-  if ($identifier !~ /\D/) {
-    $self->SUPER::LoadById($identifier);
-  }
-  else {
-      # This is a bit dangerous, we might get false authen if somebody
-      # uses ambigous userids or real names:
-      $self->LoadByCol("Name",$identifier);
-  }
-}
-
-# }}}
-
-# {{{ sub IsPassword
-
-=head2 IsPassword
-
-Takes a password as a string.  Passes it off to IsPassword in this
-user's UserObj.  If it is the user's password and the user isn't
-disabled, returns 1.
-
-Otherwise, returns undef.
-
-=cut
-
-sub IsPassword { 
-  my $self = shift;
-  my $value = shift;
-  
-  return ($self->UserObj->IsPassword($value)); 
-}
-
-# }}}
-
-# {{{ sub Privileged
-
-=head2 Privileged
-
-Returns true if the current user can be granted rights and be
-a member of groups.
 
 =cut
 
-sub Privileged {
+sub LoadByName {
     my $self = shift;
-    return ($self->UserObj->Privileged());
+    return $self->LoadByCol( "Name", shift );
 }
 
-# }}}
-
-
-# {{{ sub HasRight
-
-=head2 HasRight
-
-calls $self->UserObj->HasRight with the arguments passed in
-
-=cut
-
-sub HasRight {
-  my $self = shift;
-  return ($self->UserObj->HasRight(@_));
-}
-
-# }}}
-
-# {{{ Localization
-
 =head2 LanguageHandle
 
 Returns this current user's langauge handle. Should take a language
 specification. but currently doesn't
 
-=begin testing
-
-ok (my $cu = RT::CurrentUser->new('root'));
-ok (my $lh = $cu->LanguageHandle);
-ok ($lh != undef);
-ok ($lh->isa('Locale::Maketext'));
-ok ($cu->loc('TEST_STRING') eq "Concrete Mixer", "Localized TEST_STRING into English");
-ok ($lh = $cu->LanguageHandle('fr'));
-ok ($cu->loc('Before') eq "Avant", "Localized TEST_STRING into Frenc");
-
-=end testing
-
 =cut 
 
 sub LanguageHandle {
     my $self = shift;
-    if  ((!defined $self->{'LangHandle'}) || 
-         (!UNIVERSAL::can($self->{'LangHandle'}, 'maketext')) || 
-         (@_))  {
+    if (   !defined $self->{'LangHandle'}
+        || !UNIVERSAL::can( $self->{'LangHandle'}, 'maketext' )
+        || @_ )
+    {
+        if ( my $lang = $self->Lang ) {
+            push @_, $lang;
+        }
+        elsif ( $self->id && ($self->id == ($RT::SystemUser->id||0) || $self->id == ($RT::Nobody->id||0)) ) {
+            # don't use ENV magic for system users
+            push @_, 'en';
+        }
+
         $self->{'LangHandle'} = RT::I18N->get_handle(@_);
     }
+
     # Fall back to english.
-    unless ($self->{'LangHandle'}) {
-        die "We couldn't get a dictionary. Nye mogu naidti slovar. No puedo encontrar dictionario.";
+    unless ( $self->{'LangHandle'} ) {
+        die "We couldn't get a dictionary. Ne mogu naidti slovar. No puedo encontrar dictionario.";
     }
-    return ($self->{'LangHandle'});
+    return $self->{'LangHandle'};
 }
 
 sub loc {
     my $self = shift;
-    return '' if $_[0] eq '';
+    return '' if !defined $_[0] || $_[0] eq '';
 
     my $handle = $self->LanguageHandle;
 
     if (@_ == 1) {
-       # pre-scan the lexicon hashes to return _AUTO keys verbatim,
-       # to keep locstrings containing '[' and '~' from tripping over Maketext
-       return $_[0] unless grep { exists $_->{$_[0]} } @{ $handle->_lex_refs };
+        # pre-scan the lexicon hashes to return _AUTO keys verbatim,
+        # to keep locstrings containing '[' and '~' from tripping over Maketext
+        return $_[0] unless grep exists $_->{$_[0]}, @{ $handle->_lex_refs };
     }
 
     return $handle->maketext(@_);
@@ -355,20 +251,66 @@ sub loc {
 
 sub loc_fuzzy {
     my $self = shift;
-    return '' if $_[0] eq '';
+    return '' if !defined $_[0] || $_[0] eq '';
 
     # XXX: work around perl's deficiency when matching utf8 data
     return $_[0] if Encode::is_utf8($_[0]);
-    my $result = $self->LanguageHandle->maketext_fuzzy(@_);
 
-    return($result);
+    return $self->LanguageHandle->maketext_fuzzy( @_ );
+}
+
+=head2 CurrentUser
+
+Return the current currentuser object
+
+=cut
+
+sub CurrentUser {
+    my $self = shift;
+    return($self);
+
+}
+
+=head2 Authenticate
+
+Takes $password, $created and $nonce, and returns a boolean value
+representing whether the authentication succeeded.
+
+If both $nonce and $created are specified, validate $password against:
+
+    encode_base64(sha1(
+        $nonce .
+        $created .
+        sha1_hex( "$username:$realm:$server_pass" )
+    ))
+
+where $server_pass is the md5_hex(password) digest stored in the
+database, $created is in ISO time format, and $nonce is a random
+string no longer than 32 bytes.
+
+=cut
+
+sub Authenticate { 
+    my ($self, $password, $created, $nonce, $realm) = @_;
+
+    require Digest::MD5;
+    require Digest::SHA1;
+    require MIME::Base64;
+
+    my $username = $self->UserObj->Name or return;
+    my $server_pass = $self->UserObj->__Value('Password') or return;
+    my $auth_digest = MIME::Base64::encode_base64(Digest::SHA1::sha1(
+        $nonce .
+        $created .
+        Digest::MD5::md5_hex("$username:$realm:$server_pass")
+    ));
+
+    chomp($password);
+    chomp($auth_digest);
+
+    return ($password eq $auth_digest);
 }
-# }}}
 
-eval "require RT::CurrentUser_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Vendor.pm});
-eval "require RT::CurrentUser_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/CurrentUser_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
index 4dcef3f..7af79ce 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -69,7 +94,7 @@ Create takes a hash of values and creates a row in the database:
   varchar(255) 'Description'.
   varchar(64) 'Domain'.
   varchar(64) 'Type'.
-  varchar(64) 'Instance'.
+  int(11) 'Instance'.
 
 =cut
 
@@ -98,7 +123,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -107,14 +132,14 @@ Returns the current value of id.
 =cut
 
 
-=item Name
+=head2 Name
 
 Returns the current value of Name. 
 (In the database, Name is stored as varchar(200).)
 
 
 
-=item SetName VALUE
+=head2 SetName VALUE
 
 
 Set Name to VALUE. 
@@ -125,14 +150,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Description
+=head2 Description
 
 Returns the current value of Description. 
 (In the database, Description is stored as varchar(255).)
 
 
 
-=item SetDescription VALUE
+=head2 SetDescription VALUE
 
 
 Set Description to VALUE. 
@@ -143,14 +168,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Domain
+=head2 Domain
 
 Returns the current value of Domain. 
 (In the database, Domain is stored as varchar(64).)
 
 
 
-=item SetDomain VALUE
+=head2 SetDomain VALUE
 
 
 Set Domain to VALUE. 
@@ -161,14 +186,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Type
+=head2 Type
 
 Returns the current value of Type. 
 (In the database, Type is stored as varchar(64).)
 
 
 
-=item SetType VALUE
+=head2 SetType VALUE
 
 
 Set Type to VALUE. 
@@ -179,62 +204,45 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Instance
+=head2 Instance
 
 Returns the current value of Instance. 
-(In the database, Instance is stored as varchar(64).)
+(In the database, Instance is stored as int(11).)
 
 
 
-=item SetInstance VALUE
+=head2 SetInstance VALUE
 
 
 Set Instance to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Instance will be stored as a varchar(64).)
+(In the database, Instance will be stored as a int(11).)
 
 
 =cut
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Description => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Domain => 
-               {read => 1, write => 1, type => 'varchar(64)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
         Type => 
-               {read => 1, write => 1, type => 'varchar(64)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
         Instance => 
-               {read => 1, write => 1, type => 'varchar(64)', default => ''},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
 
  }
 };
 
-
-        eval "require RT::Group_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Group_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Group_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Group_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Group_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Group_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -244,7 +252,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 8de1a73..ae0160c 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -89,7 +114,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -98,14 +123,14 @@ Returns the current value of id.
 =cut
 
 
-=item GroupId
+=head2 GroupId
 
 Returns the current value of GroupId. 
 (In the database, GroupId is stored as int(11).)
 
 
 
-=item SetGroupId VALUE
+=head2 SetGroupId VALUE
 
 
 Set GroupId to VALUE. 
@@ -116,14 +141,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item MemberId
+=head2 MemberId
 
 Returns the current value of MemberId. 
 (In the database, MemberId is stored as int(11).)
 
 
 
-=item SetMemberId VALUE
+=head2 SetMemberId VALUE
 
 
 Set MemberId to VALUE. 
@@ -135,37 +160,20 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         GroupId => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         MemberId => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
 
  }
 };
 
-
-        eval "require RT::GroupMember_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/GroupMember_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::GroupMember_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/GroupMember_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::GroupMember_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/GroupMember_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -175,7 +183,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 31cb953..5d821ad 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::GroupMember item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::GroupMember->new($self->CurrentUser));
 }
-
-        eval "require RT::GroupMembers_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/GroupMembers_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::GroupMembers_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/GroupMembers_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::GroupMembers_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/GroupMembers_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 29f12a5..2ec2f79 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Group item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Group->new($self->CurrentUser));
 }
-
-        eval "require RT::Groups_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Groups_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Groups_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Groups_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Groups_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Groups_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 5cdb65e..38905de 100644 (file)
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 =head1 NAME
 
-  RT::Handle - RT's database handle
+RT::Handle - RT's database handle
 
 =head1 SYNOPSIS
 
-  use RT::Handle;
+    use RT;
+    BEGIN { RT::LoadConfig() };
+    use RT::Handle;
 
 =head1 DESCRIPTION
 
-=begin testing
-
-ok(require RT::Handle);
-
-=end testing
-
-=head1 METHODS
+C<RT::Handle> is RT specific wrapper over one of L<DBIx::SearchBuilder::Handle>
+classes. As RT works with different types of DBs we subclass repsective handler
+from L<DBIx::SerachBuilder>. Type of the DB is defined by C<DatabasseType> RT's
+config option. You B<must> load this module only when the configs have been
+loaded.
 
 =cut
 
 package RT::Handle;
 
 use strict;
+use warnings;
 use vars qw/@ISA/;
 
-eval "use DBIx::SearchBuilder::Handle::$RT::DatabaseType;
-\@ISA= qw(DBIx::SearchBuilder::Handle::$RT::DatabaseType);";
-#TODO check for errors here.
+=head1 METHODS
+
+=head2 FinalizeDatabaseType
+
+Sets RT::Handle's superclass to the correct subclass of
+L<DBIx::SearchBuilder::Handle>, using the C<DatabaseType> configuration.
+
+=cut
+
+sub FinalizeDatabaseType {
+    eval {
+        use base "DBIx::SearchBuilder::Handle::". RT->Config->Get('DatabaseType');
+    };
+
+    if ($@) {
+        die "Unable to load DBIx::SearchBuilder database handle for '". RT->Config->Get('DatabaseType') ."'.\n".
+            "Perhaps you've picked an invalid database type or spelled it incorrectly.\n".
+            $@;
+    }
+}
 
 =head2 Connect
 
-Connects to RT's database handle.
-Takes nothing. Calls SUPER::Connect with the needed args
+Connects to RT's database using credentials and options from the RT config.
+Takes nothing.
 
 =cut
 
 sub Connect {
-my $self=shift;
+    my $self = shift;
+
+    my $db_type = RT->Config->Get('DatabaseType');
+    if ( $db_type eq 'Oracle' ) {
+        $ENV{'NLS_LANG'} = "AMERICAN_AMERICA.AL32UTF8";
+        $ENV{'NLS_NCHAR'} = "AL32UTF8";
+    }
+
+    $self->SUPER::Connect(
+        User => RT->Config->Get('DatabaseUser'),
+        Password => RT->Config->Get('DatabasePassword'),
+    );
+
+    if ( $db_type eq 'mysql' ) {
+        my $version = $self->DatabaseVersion;
+        ($version) = $version =~ /^(\d+\.\d+)/;
+        $self->dbh->do("SET NAMES 'utf8'") if $version >= 4.1;
+    }
+
 
-# Unless the database port is a positive integer, we really don't want to pass it.
+    if ( $db_type eq 'Pg' ) {
+        my $version = $self->DatabaseVersion;
+        ($version) = $version =~ /^(\d+\.\d+)/;
+        $self->dbh->do("SET bytea_output = 'escape'") if $version >= 9.0;
+    }
 
-$self->SUPER::Connect(
-                        User => $RT::DatabaseUser,
-                        Password => $RT::DatabasePassword,
-                       );
-   
+
+
+    $self->dbh->{'LongReadLen'} = RT->Config->Get('MaxAttachmentSize');
 }
 
-=item BuildDSN
+=head2 BuildDSN
 
-Build the DSN for the RT database. doesn't take any parameters, draws all that
-from the config file.
+Build the DSN for the RT database. Doesn't take any parameters, draws all that
+from the config.
 
 =cut
 
+require File::Spec;
 
 sub BuildDSN {
     my $self = shift;
-$RT::DatabasePort = undef unless (defined $RT::DatabasePort && $RT::DatabasePort =~ /^(\d+)$/);
-$RT::DatabaseHost = undef unless (defined $RT::DatabaseHost && $RT::DatabaseHost ne '');
+    # Unless the database port is a positive integer, we really don't want to pass it.
+    my $db_port = RT->Config->Get('DatabasePort');
+    $db_port = undef unless (defined $db_port && $db_port =~ /^(\d+)$/);
+    my $db_host = RT->Config->Get('DatabaseHost');
+    $db_host = undef unless $db_host;
+    my $db_name = RT->Config->Get('DatabaseName');
+    my $db_type = RT->Config->Get('DatabaseType');
+    $db_name = File::Spec->catfile($RT::VarPath, $db_name)
+        if $db_type eq 'SQLite' && !File::Spec->file_name_is_absolute($db_name);
+
+    my %args = (
+        Host       => $db_host,
+        Database   => $db_name,
+        Port       => $db_port,
+        Driver     => $db_type,
+        RequireSSL => RT->Config->Get('DatabaseRequireSSL'),
+        DisconnectHandleOnDestroy => 1,
+    );
+    if ( $db_type eq 'Oracle' && $db_host ) {
+        $args{'SID'} = delete $args{'Database'};
+    }
+    $self->SUPER::BuildDSN( %args );
+}
+
+=head2 DSN
+
+Returns the DSN for this handle. In order to get correct value you must
+build DSN first, see L</BuildDSN>.
+
+This is method can be called as class method, in this case creates
+temporary handle object, L</BuildDSN builds DSN> and returns it.
+
+=cut
+
+sub DSN {
+    my $self = shift;
+    return $self->SUPER::DSN if ref $self;
+
+    my $handle = $self->new;
+    $handle->BuildDSN;
+    return $handle->DSN;
+}
+
+=head2 SystemDSN
+
+Returns a DSN suitable for database creates and drops
+and user creates and drops.
+
+Gets RT's DSN first (see L<DSN>) and then change it according
+to requirements of a database system RT's using.
+
+=cut
+
+sub SystemDSN {
+    my $self = shift;
 
-    $self->SUPER::BuildDSN(Host => $RT::DatabaseHost, 
-                        Database => $RT::DatabaseName, 
-                        Port => $RT::DatabasePort,
-                        Driver => $RT::DatabaseType,
-                        RequireSSL => $RT::DatabaseRequireSSL,
-             DisconnectHandleOnDestroy => 1
-                       );
-   
+    my $db_name = RT->Config->Get('DatabaseName');
+    my $db_type = RT->Config->Get('DatabaseType');
 
+    my $dsn = $self->DSN;
+    if ( $db_type eq 'mysql' ) {
+        # with mysql, you want to connect sans database to funge things
+        $dsn =~ s/dbname=\Q$db_name//;
+    }
+    elsif ( $db_type eq 'Pg' ) {
+        # with postgres, you want to connect to template1 database
+        $dsn =~ s/dbname=\Q$db_name/dbname=template1/;
+    }
+    elsif ( $db_type eq 'Informix' ) {
+        # with Informix, you want to connect sans database:
+        $dsn =~ s/Informix:\Q$db_name/Informix:/;
+    }
+    return $dsn;
 }
 
-eval "require RT::Handle_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Handle_Vendor.pm});
-eval "require RT::Handle_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Handle_Local.pm});
+=head2 Database compatibility and integrity checks
+
+
+
+=cut
+
+sub CheckIntegrity {
+    my $self = shift;
+    
+    my $dsn = $self->DSN;
+    my $user = RT->Config->Get('DatabaseUser');
+    my $pass = RT->Config->Get('DatabasePassword');
+
+    my $dbh = DBI->connect(
+        $dsn, $user, $pass,
+        { RaiseError => 0, PrintError => 0 },
+    );
+    unless ( $dbh ) {
+        return (0, 'no connection', "Failed to connect to $dsn as user '$user': ". $DBI::errstr);
+    }
+
+    RT::ConnectToDatabase();
+    RT::InitLogging();
+
+    require RT::CurrentUser;
+    my $test_user = new RT::CurrentUser;
+    $test_user->Load('RT_System');
+    unless ( $test_user->id ) {
+        return (0, 'no system user', "Couldn't find RT_System user in the DB '$dsn'");
+    }
+
+    $test_user = new RT::CurrentUser;
+    $test_user->Load('Nobody');
+    unless ( $test_user->id ) {
+        return (0, 'no nobody user', "Couldn't find Nobody user in the DB '$dsn'");
+    }
+
+    return $dbh;
+}
+
+sub CheckCompatibility {
+    my $self = shift;
+    my $dbh = shift;
+    my $state = shift || 'post';
+
+    my $db_type = RT->Config->Get('DatabaseType');
+    if ( $db_type eq "mysql" ) {
+        # Check which version we're running
+        my $version = ($dbh->selectrow_array("show variables like 'version'"))[1];
+        return (0, "couldn't get version of the mysql server")
+            unless $version;
+
+        ($version) = $version =~ /^(\d+\.\d+)/;
+        return (0, "RT is unsupported on MySQL versions before 4.0.x, it's $version")
+            if $version < 4;
+
+        # MySQL must have InnoDB support
+        my $innodb = ($dbh->selectrow_array("show variables like 'have_innodb'"))[1];
+        if ( lc $innodb eq "no" ) {
+            return (0, "RT requires that MySQL be compiled with InnoDB table support.\n".
+                "See http://dev.mysql.com/doc/mysql/en/InnoDB.html");
+        } elsif ( lc $innodb eq "disabled" ) {
+            return (0, "RT requires that MySQL InnoDB table support be enabled.\n".
+                "Remove the 'skip-innodb' line from your my.cnf file, restart MySQL, and try again.\n");
+        }
+
+        if ( $state eq 'post' ) {
+            my $create_table = $dbh->selectrow_arrayref("SHOW CREATE TABLE Tickets")->[1];
+            unless ( $create_table =~ /(?:ENGINE|TYPE)\s*=\s*InnoDB/i ) {
+                return (0, "RT requires that all its tables be of InnoDB type. Upgrade RT tables.");
+            }
+        }
+        if ( $version >= 4.1 && $state eq 'post' ) {
+            my $create_table = $dbh->selectrow_arrayref("SHOW CREATE TABLE Attachments")->[1];
+            unless ( $create_table =~ /\bContent\b[^,]*BLOB/i ) {
+                return (0, "RT since version 3.8 has new schema for MySQL versions after 4.1.0\n"
+                    ."Follow instructions in the UPGRADING.mysql file.");
+            }
+        }
+    }
+    return (1)
+}
+
+=head2 Database maintanance
+
+=head3 CreateDatabase $DBH
+
+Creates a new database. This method can be used as class method.
+
+Takes DBI handle. Many database systems require special handle to
+allow you to create a new database, so you have to use L<SystemDSN>
+method during connection.
+
+Fetches type and name of the DB from the config.
+
+=cut
+
+sub CreateDatabase {
+    my $self = shift;
+    my $dbh  = shift or return (0, "No DBI handle provided");
+    my $db_type = RT->Config->Get('DatabaseType');
+    my $db_name = RT->Config->Get('DatabaseName');
+
+    my $status;
+    if ( $db_type eq 'SQLite' ) {
+        return (1, 'Skipped as SQLite doesn\'t need any action');
+    }
+    elsif ( $db_type eq 'Oracle' ) {
+        my $db_user = RT->Config->Get('DatabaseUser');
+        my $db_pass = RT->Config->Get('DatabasePassword');
+        $status = $dbh->do(
+            "CREATE USER $db_user IDENTIFIED BY $db_pass"
+            ." default tablespace USERS"
+            ." temporary tablespace TEMP"
+            ." quota unlimited on USERS"
+        );
+        unless ( $status ) {
+            return $status, "Couldn't create user $db_user identified by $db_pass."
+                ."\nError: ". $dbh->errstr;
+        }
+        $status = $dbh->do( "GRANT connect, resource TO $db_user" );
+        unless ( $status ) {
+            return $status, "Couldn't grant connect and resource to $db_user."
+                ."\nError: ". $dbh->errstr;
+        }
+        return (1, "Created user $db_user. All RT's objects should be in his schema.");
+    }
+    elsif ( $db_type eq 'Pg' ) {
+        # XXX: as we get external DBH we don't know if RaiseError or PrintError
+        # are enabled, so we have to setup it here and restore them back
+        $status = $dbh->do("CREATE DATABASE $db_name WITH ENCODING='UNICODE' TEMPLATE template0")
+            || $dbh->do("CREATE DATABASE $db_name TEMPLATE template0");
+    }
+    elsif ( $db_type eq 'Informix' ) {
+        local $ENV{'DB_LOCALE'} = 'en_us.utf8';
+        $status = $dbh->do("CREATE DATABASE $db_name WITH BUFFERED LOG");
+    }
+    else {
+        $status = $dbh->do("CREATE DATABASE $db_name");
+    }
+    return ($status, $DBI::errstr);
+}
+
+=head3 DropDatabase $DBH [Force => 0]
+
+Drops RT's database. This method can be used as class method.
+
+Takes DBI handle as first argument. Many database systems require
+special handle to allow you to create a new database, so you have
+to use L<SystemDSN> method during connection.
+
+Fetches type and name of the DB from the config.
+
+=cut
+
+sub DropDatabase {
+    my $self = shift;
+    my $dbh  = shift or return (0, "No DBI handle provided");
+
+    my $db_type = RT->Config->Get('DatabaseType');
+    my $db_name = RT->Config->Get('DatabaseName');
+
+    if ( $db_type eq 'Oracle' || $db_type eq 'Informix' ) {
+        my $db_user = RT->Config->Get('DatabaseUser');
+        my $status = $dbh->do( "DROP USER $db_user CASCADE" );
+        unless ( $status ) {
+            return 0, "Couldn't drop user $db_user."
+                ."\nError: ". $dbh->errstr;
+        }
+        return (1, "Successfully dropped user '$db_user' with his schema.");
+    }
+    elsif ( $db_type eq 'SQLite' ) {
+        my $path = $db_name;
+        $path = "$RT::VarPath/$path" unless substr($path, 0, 1) eq '/';
+        unlink $path or return (0, "Couldn't remove '$path': $!");
+        return (1);
+    } else {
+        $dbh->do("DROP DATABASE ". $db_name)
+            or return (0, $DBI::errstr);
+    }
+    return (1);
+}
+
+=head2 InsertACL
+
+=cut
+
+sub InsertACL {
+    my $self      = shift;
+    my $dbh       = shift;
+    my $base_path = shift || $RT::EtcPath;
+
+    my $db_type = RT->Config->Get('DatabaseType');
+    return (1) if $db_type eq 'SQLite';
+
+    $dbh = $self->dbh if !$dbh && ref $self;
+    return (0, "No DBI handle provided") unless $dbh;
+
+    return (0, "'$base_path' doesn't exist") unless -e $base_path;
+
+    my $path;
+    if ( -d $base_path ) {
+        $path = File::Spec->catfile( $base_path, "acl.$db_type");
+        $path = $self->GetVersionFile($dbh, $path);
+
+        $path = File::Spec->catfile( $base_path, "acl")
+            unless $path && -e $path;
+        return (0, "Couldn't find ACLs for $db_type")
+            unless -e $path;
+    } else {
+        $path = $base_path;
+    }
+
+    local *acl;
+    do $path || return (0, "Couldn't load ACLs: " . $@);
+    my @acl = acl($dbh);
+    foreach my $statement (@acl) {
+        my $sth = $dbh->prepare($statement)
+            or return (0, "Couldn't prepare SQL query:\n $statement\n\nERROR: ". $dbh->errstr);
+        unless ( $sth->execute ) {
+            return (0, "Couldn't run SQL query:\n $statement\n\nERROR: ". $sth->errstr);
+        }
+    }
+    return (1);
+}
+
+=head2 InsertSchema
+
+=cut
+
+sub InsertSchema {
+    my $self = shift;
+    my $dbh  = shift;
+    my $base_path = (shift || $RT::EtcPath);
+
+    $dbh = $self->dbh if !$dbh && ref $self;
+    return (0, "No DBI handle provided") unless $dbh;
+
+    my $db_type = RT->Config->Get('DatabaseType');
+
+    my $file;
+    if ( -d $base_path ) {
+        $file = $base_path . "/schema." . $db_type;
+    } else {
+        $file = $base_path;
+    }
+
+    $file = $self->GetVersionFile( $dbh, $file );
+    unless ( $file ) {
+        return (0, "Couldn't find schema file(s) '$file*'");
+    }
+    unless ( -f $file && -r $file ) {
+        return (0, "File '$file' doesn't exist or couldn't be read");
+    }
+
+    my (@schema);
+
+    open( my $fh_schema, '<', $file ) or die $!;
+
+    my $has_local = 0;
+    open( my $fh_schema_local, "<", $self->GetVersionFile( $dbh, $RT::LocalEtcPath . "/schema." . $db_type ))
+        and $has_local = 1;
+
+    my $statement = "";
+    foreach my $line ( <$fh_schema>, ($_ = ';;'), $has_local? <$fh_schema_local>: () ) {
+        $line =~ s/\#.*//g;
+        $line =~ s/--.*//g;
+        $statement .= $line;
+        if ( $line =~ /;(\s*)$/ ) {
+            $statement =~ s/;(\s*)$//g;
+            push @schema, $statement;
+            $statement = "";
+        }
+    }
+    close $fh_schema; close $fh_schema_local;
+
+    if ( $db_type eq 'Oracle' ) {
+        my $db_user = RT->Config->Get('DatabaseUser');
+        my $status = $dbh->do( "ALTER SESSION SET CURRENT_SCHEMA=$db_user" );
+        unless ( $status ) {
+            return $status, "Couldn't set current schema to $db_user."
+                ."\nError: ". $dbh->errstr;
+        }
+    }
+
+    local $SIG{__WARN__} = sub {};
+    my $is_local = 0;
+    $dbh->begin_work or return (0, "Couldn't begin transaction: ". $dbh->errstr);
+    foreach my $statement (@schema) {
+        if ( $statement =~ /^\s*;$/ ) {
+            $is_local = 1; next;
+        }
+
+        my $sth = $dbh->prepare($statement)
+            or return (0, "Couldn't prepare SQL query:\n$statement\n\nERROR: ". $dbh->errstr);
+        unless ( $sth->execute or $is_local ) {
+            return (0, "Couldn't run SQL query:\n$statement\n\nERROR: ". $sth->errstr);
+        }
+    }
+    $dbh->commit or return (0, "Couldn't commit transaction: ". $dbh->errstr);
+    return (1);
+}
+
+=head1 GetVersionFile
+
+Takes base name of the file as argument, scans for <base name>-<version> named
+files and returns file name with closest version to the version of the RT DB.
+
+=cut
+
+sub GetVersionFile {
+    my $self = shift;
+    my $dbh = shift;
+    my $base_name = shift;
+
+    my $db_version = ref $self
+        ? $self->DatabaseVersion
+        : do {
+            my $tmp = RT::Handle->new;
+            $tmp->dbh($dbh);
+            $tmp->DatabaseVersion;
+        };
+
+    require File::Glob;
+    my @files = File::Glob::bsd_glob("$base_name*");
+    return '' unless @files;
+
+    my %version = map { $_ =~ /\.\w+-([-\w\.]+)$/; ($1||0) => $_ } @files;
+    my $version;
+    foreach ( reverse sort cmp_version keys %version ) {
+        if ( cmp_version( $db_version, $_ ) >= 0 ) {
+            $version = $_;
+            last;
+        }
+    }
+
+    return defined $version? $version{ $version } : undef;
+}
+
+sub cmp_version($$) {
+    my ($a, $b) = (@_);
+    $b =~ s/HEAD$/9999/;
+    my @a = split /[^0-9]+/, $a;
+    my @b = split /[^0-9]+/, $b;
+    for ( my $i = 0; $i < @a; $i++ ) {
+        return 1 unless defined $b[$i];
+        return $a[$i] <=> $b[$i] if $a[$i] <=> $b[$i];
+    }
+    return 0 if @a == @b;
+    return -1;
+}
+
+
+=head2 InsertInitialData
+
+Inserts system objects into RT's DB, like system user or 'nobody',
+internal groups and other records required. However, this method
+doesn't insert any real users like 'root' and you have to use
+InsertData or another way to do that.
+
+Takes no arguments. Returns status and message tuple.
+
+It's safe to call this method even if those objects already exist.
+
+=cut
+
+sub InsertInitialData {
+    my $self    = shift;
+
+    my @warns;
+
+    # create RT_System user and grant him rights
+    {
+        require RT::CurrentUser;
+
+        my $test_user = RT::User->new( new RT::CurrentUser );
+        $test_user->Load('RT_System');
+        if ( $test_user->id ) {
+            push @warns, "Found system user in the DB.";
+        }
+        else {
+            my $user = RT::User->new( new RT::CurrentUser );
+            my ( $val, $msg ) = $user->_BootstrapCreate(
+                Name     => 'RT_System',
+                RealName => 'The RT System itself',
+                Comments => 'Do not delete or modify this user. '
+                    . 'It is integral to RT\'s internal database structures',
+                Creator  => '1',
+                LastUpdatedBy => '1',
+            );
+            return ($val, $msg) unless $val;
+        }
+        DBIx::SearchBuilder::Record::Cachable->FlushCache;
+    }
+
+    # init RT::SystemUser and RT::System objects
+    RT::InitSystemObjects();
+    unless ( $RT::SystemUser->id ) {
+        return (0, "Couldn't load system user");
+    }
+
+    # grant SuperUser right to system user
+    {
+        my $test_ace = RT::ACE->new( $RT::SystemUser );
+        $test_ace->LoadByCols(
+            PrincipalId   => ACLEquivGroupId( $RT::SystemUser->Id ),
+            PrincipalType => 'Group',
+            RightName     => 'SuperUser',
+            ObjectType    => 'RT::System',
+            ObjectId      => 1,
+        );
+        if ( $test_ace->id ) {
+            push @warns, "System user has global SuperUser right.";
+        } else {
+            my $ace = RT::ACE->new( $RT::SystemUser );
+            my ( $val, $msg ) = $ace->_BootstrapCreate(
+                PrincipalId   => ACLEquivGroupId( $RT::SystemUser->Id ),
+                PrincipalType => 'Group',
+                RightName     => 'SuperUser',
+                ObjectType    => 'RT::System',
+                ObjectId      => 1,
+            );
+            return ($val, $msg) unless $val;
+        }
+        DBIx::SearchBuilder::Record::Cachable->FlushCache;
+    }
+
+    # system groups
+    # $self->loc('Everyone'); # For the string extractor to get a string to localize
+    # $self->loc('Privileged'); # For the string extractor to get a string to localize
+    # $self->loc('Unprivileged'); # For the string extractor to get a string to localize
+    foreach my $name (qw(Everyone Privileged Unprivileged)) {
+        my $group = RT::Group->new( $RT::SystemUser );
+        $group->LoadSystemInternalGroup( $name );
+        if ( $group->id ) {
+            push @warns, "System group '$name' already exists.";
+            next;
+        }
+
+        $group = RT::Group->new( $RT::SystemUser );
+        my ( $val, $msg ) = $group->_Create(
+            Type        => $name,
+            Domain      => 'SystemInternal',
+            Description => 'Pseudogroup for internal use',  # loc
+            Name        => '',
+            Instance    => '',
+        );
+        return ($val, $msg) unless $val;
+    }
+
+    # nobody
+    {
+        my $user = RT::User->new( $RT::SystemUser );
+        $user->Load('Nobody');
+        if ( $user->id ) {
+            push @warns, "Found 'Nobody' user in the DB.";
+        }
+        else {
+            my ( $val, $msg ) = $user->Create(
+                Name     => 'Nobody',
+                RealName => 'Nobody in particular',
+                Comments => 'Do not delete or modify this user. It is integral '
+                    .'to RT\'s internal data structures',
+                Privileged => 0,
+            );
+            return ($val, $msg) unless $val;
+        }
+
+        if ( $user->HasRight( Right => 'OwnTicket', Object => $RT::System ) ) {
+            push @warns, "User 'Nobody' has global OwnTicket right.";
+        } else {
+            my ( $val, $msg ) = $user->PrincipalObj->GrantRight(
+                Right => 'OwnTicket',
+                Object => $RT::System,
+            );
+            return ($val, $msg) unless $val;
+        }
+    }
+
+    # rerun to get init Nobody as well
+    RT::InitSystemObjects();
+
+    # system role groups
+    foreach my $name (qw(Owner Requestor Cc AdminCc)) {
+        my $group = RT::Group->new( $RT::SystemUser );
+        $group->LoadSystemRoleGroup( $name );
+        if ( $group->id ) {
+            push @warns, "System role '$name' already exists.";
+            next;
+        }
+
+        $group = RT::Group->new( $RT::SystemUser );
+        my ( $val, $msg ) = $group->_Create(
+            Type        => $name,
+            Domain      => 'RT::System-Role',
+            Description => 'SystemRolegroup for internal use',  # loc
+            Name        => '',
+            Instance    => '',
+        );
+        return ($val, $msg) unless $val;
+    }
+
+    push @warns, "You appear to have a functional RT database."
+        if @warns;
+
+    return (1, join "\n", @warns);
+}
+
+=head2 InsertData
+
+Load some sort of data into the database, takes path to a file.
+
+=cut
+
+sub InsertData {
+    my $self     = shift;
+    my $datafile = shift;
+
+    # Slurp in stuff to insert from the datafile. Possible things to go in here:-
+    our (@Groups, @Users, @ACL, @Queues, @ScripActions, @ScripConditions,
+           @Templates, @CustomFields, @Scrips, @Attributes, @Initial, @Final);
+    local (@Groups, @Users, @ACL, @Queues, @ScripActions, @ScripConditions,
+           @Templates, @CustomFields, @Scrips, @Attributes, @Initial, @Final);
+
+    local $@;
+    $RT::Logger->debug("Going to load '$datafile' data file");
+    eval { require $datafile }
+      or return (0, "Couldn't load data from '$datafile' for import:\n\nERROR:". $@);
+
+    if ( @Initial ) {
+        $RT::Logger->debug("Running initial actions...");
+        foreach ( @Initial ) {
+            local $@;
+            eval { $_->(); 1 } or return (0, "One of initial functions failed: $@");
+        }
+        $RT::Logger->debug("Done.");
+    }
+    if ( @Groups ) {
+        $RT::Logger->debug("Creating groups...");
+        foreach my $item (@Groups) {
+            my $new_entry = RT::Group->new( $RT::SystemUser );
+            my $member_of = delete $item->{'MemberOf'};
+            my ( $return, $msg ) = $new_entry->_Create(%$item);
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+                next;
+            } else {
+                $RT::Logger->debug($return .".");
+            }
+            if ( $member_of ) {
+                $member_of = [ $member_of ] unless ref $member_of eq 'ARRAY';
+                foreach( @$member_of ) {
+                    my $parent = RT::Group->new($RT::SystemUser);
+                    if ( ref $_ eq 'HASH' ) {
+                        $parent->LoadByCols( %$_ );
+                    }
+                    elsif ( !ref $_ ) {
+                        $parent->LoadUserDefinedGroup( $_ );
+                    }
+                    else {
+                        $RT::Logger->error(
+                            "(Error: wrong format of MemberOf field."
+                            ." Should be name of user defined group or"
+                            ." hash reference with 'column => value' pairs."
+                            ." Use array reference to add to multiple groups)"
+                        );
+                        next;
+                    }
+                    unless ( $parent->Id ) {
+                        $RT::Logger->error("(Error: couldn't load group to add member)");
+                        next;
+                    }
+                    my ( $return, $msg ) = $parent->AddMember( $new_entry->Id );
+                    unless ( $return ) {
+                        $RT::Logger->error( $msg );
+                    } else {
+                        $RT::Logger->debug( $return ."." );
+                    }
+                }
+            }
+        }
+        $RT::Logger->debug("done.");
+    }
+    if ( @Users ) {
+        $RT::Logger->debug("Creating users...");
+        foreach my $item (@Users) {
+            my $new_entry = new RT::User( $RT::SystemUser );
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+            } else {
+                $RT::Logger->debug( $return ."." );
+            }
+        }
+        $RT::Logger->debug("done.");
+    }
+    if ( @Queues ) {
+        $RT::Logger->debug("Creating queues...");
+        for my $item (@Queues) {
+            my $new_entry = new RT::Queue($RT::SystemUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+            } else {
+                $RT::Logger->debug( $return ."." );
+            }
+        }
+        $RT::Logger->debug("done.");
+    }
+    if ( @CustomFields ) {
+        $RT::Logger->debug("Creating custom fields...");
+        for my $item ( @CustomFields ) {
+            my $new_entry = new RT::CustomField( $RT::SystemUser );
+            my $values    = delete $item->{'Values'};
+
+            my @queues;
+            # if ref then it's list of queues, so we do things ourself
+            if ( exists $item->{'Queue'} && ref $item->{'Queue'} ) {
+                $item->{'LookupType'} ||= 'RT::Queue-RT::Ticket';
+                @queues = @{ delete $item->{'Queue'} };
+            }
+
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            unless( $return ) {
+                $RT::Logger->error( $msg );
+                next;
+            }
+
+            if ( $item->{'BasedOn'} ) {
+                my $basedon = RT::CustomField->new($RT::SystemUser);
+                my ($ok, $msg ) = $basedon->LoadByCols( Name => $item->{'BasedOn'},
+                                                        LookupType => $new_entry->LookupType );
+                if ($ok) {
+                    ($ok, $msg) = $new_entry->SetBasedOn( $basedon );
+                    if ($ok) {
+                        $RT::Logger->debug("Added BasedOn $item->{BasedOn}: $msg");
+                    } else {
+                        $RT::Logger->error("Failed to add basedOn $item->{BasedOn}: $msg");
+                    }
+                } else {
+                    $RT::Logger->error("Unable to load $item->{BasedOn} as a $item->{LookupType} CF.  Skipping BasedOn");
+                }
+            }
+
+            foreach my $value ( @{$values} ) {
+                my ( $return, $msg ) = $new_entry->AddValue(%$value);
+                $RT::Logger->error( $msg ) unless $return;
+            }
+
+            # apply by default
+            if ( !@queues && !exists $item->{'Queue'} && $item->{LookupType} ) {
+                my $ocf = RT::ObjectCustomField->new($RT::SystemUser);
+                $ocf->Create( CustomField => $new_entry->Id );
+            }
+
+            for my $q (@queues) {
+                my $q_obj = RT::Queue->new($RT::SystemUser);
+                $q_obj->Load($q);
+                unless ( $q_obj->Id ) {
+                    $RT::Logger->error("Could not find queue ". $q );
+                    next;
+                }
+                my $OCF = RT::ObjectCustomField->new($RT::SystemUser);
+                ( $return, $msg ) = $OCF->Create(
+                    CustomField => $new_entry->Id,
+                    ObjectId    => $q_obj->Id,
+                );
+                $RT::Logger->error( $msg ) unless $return and $OCF->Id;
+            }
+        }
+
+        $RT::Logger->debug("done.");
+    }
+    if ( @ACL ) {
+        $RT::Logger->debug("Creating ACL...");
+        for my $item (@ACL) {
+
+            my ($princ, $object);
+
+            # Global rights or Queue rights?
+            if ( $item->{'CF'} ) {
+                $object = RT::CustomField->new( $RT::SystemUser );
+                my @columns = ( Name => $item->{'CF'} );
+                push @columns, Queue => $item->{'Queue'} if $item->{'Queue'} and not ref $item->{'Queue'};
+                $object->LoadByName( @columns );
+            } elsif ( $item->{'Queue'} ) {
+                $object = RT::Queue->new($RT::SystemUser);
+                $object->Load( $item->{'Queue'} );
+            } else {
+                $object = $RT::System;
+            }
+
+            $RT::Logger->error("Couldn't load object") and next unless $object and $object->Id;
+
+            # Group rights or user rights?
+            if ( $item->{'GroupDomain'} ) {
+                $princ = RT::Group->new($RT::SystemUser);
+                if ( $item->{'GroupDomain'} eq 'UserDefined' ) {
+                  $princ->LoadUserDefinedGroup( $item->{'GroupId'} );
+                } elsif ( $item->{'GroupDomain'} eq 'SystemInternal' ) {
+                  $princ->LoadSystemInternalGroup( $item->{'GroupType'} );
+                } elsif ( $item->{'GroupDomain'} eq 'RT::System-Role' ) {
+                  $princ->LoadSystemRoleGroup( $item->{'GroupType'} );
+                } elsif ( $item->{'GroupDomain'} eq 'RT::Queue-Role' &&
+                          $item->{'Queue'} )
+                {
+                  $princ->LoadQueueRoleGroup( Type => $item->{'GroupType'},
+                                              Queue => $object->id);
+                } else {
+                  $princ->Load( $item->{'GroupId'} );
+                }
+            } else {
+                $princ = RT::User->new($RT::SystemUser);
+                $princ->Load( $item->{'UserId'} );
+            }
+
+            # Grant it
+            my ( $return, $msg ) = $princ->PrincipalObj->GrantRight(
+                Right => $item->{'Right'},
+                Object => $object
+            );
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+            }
+            else {
+                $RT::Logger->debug( $return ."." );
+            }
+        }
+        $RT::Logger->debug("done.");
+    }
+
+    if ( @ScripActions ) {
+        $RT::Logger->debug("Creating ScripActions...");
+
+        for my $item (@ScripActions) {
+            my $new_entry = RT::ScripAction->new($RT::SystemUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+            }
+            else {
+                $RT::Logger->debug( $return ."." );
+            }
+        }
+
+        $RT::Logger->debug("done.");
+    }
+
+    if ( @ScripConditions ) {
+        $RT::Logger->debug("Creating ScripConditions...");
+
+        for my $item (@ScripConditions) {
+            my $new_entry = RT::ScripCondition->new($RT::SystemUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+            }
+            else {
+                $RT::Logger->debug( $return ."." );
+            }
+        }
+
+        $RT::Logger->debug("done.");
+    }
+
+    if ( @Templates ) {
+        $RT::Logger->debug("Creating templates...");
+
+        for my $item (@Templates) {
+            my $new_entry = new RT::Template($RT::SystemUser);
+            my ( $return, $msg ) = $new_entry->Create(%$item);
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+            }
+            else {
+                $RT::Logger->debug( $return ."." );
+            }
+        }
+        $RT::Logger->debug("done.");
+    }
+    if ( @Scrips ) {
+        $RT::Logger->debug("Creating scrips...");
+
+        for my $item (@Scrips) {
+            my $new_entry = new RT::Scrip($RT::SystemUser);
+
+            my @queues = ref $item->{'Queue'} eq 'ARRAY'? @{ $item->{'Queue'} }: $item->{'Queue'} || 0;
+            push @queues, 0 unless @queues; # add global queue at least
+
+            foreach my $q ( @queues ) {
+                my ( $return, $msg ) = $new_entry->Create( %$item, Queue => $q );
+                unless ( $return ) {
+                    $RT::Logger->error( $msg );
+                }
+                else {
+                    $RT::Logger->debug( $return ."." );
+                }
+            }
+        }
+        $RT::Logger->debug("done.");
+    }
+    if ( @Attributes ) {
+        $RT::Logger->debug("Creating predefined searches...");
+        my $sys = RT::System->new($RT::SystemUser);
+
+        for my $item (@Attributes) {
+            my $obj = delete $item->{Object}; # XXX: make this something loadable
+            $obj ||= $sys;
+            my ( $return, $msg ) = $obj->AddAttribute (%$item);
+            unless ( $return ) {
+                $RT::Logger->error( $msg );
+            }
+            else {
+                $RT::Logger->debug( $return ."." );
+            }
+        }
+        $RT::Logger->debug("done.");
+    }
+    if ( @Final ) {
+        $RT::Logger->debug("Running final actions...");
+        for ( @Final ) {
+            local $@;
+            eval { $_->(); };
+            $RT::Logger->error( "Failed to run one of final actions: $@" )
+                if $@;
+        }
+        $RT::Logger->debug("done.");
+    }
+
+    my $db_type = RT->Config->Get('DatabaseType');
+    $RT::Handle->Disconnect() unless $db_type eq 'SQLite';
+
+    $RT::Logger->debug("Done setting up database content.");
+
+# TODO is it ok to return 1 here? If so, the previous codes in this sub
+# should return (0, $msg) if error happens instead of just warning.
+# anyway, we need to return something here to tell if everything is ok
+    return( 1, 'Done inserting data' );
+}
+
+=head2 ACLEquivGroupId
+
+Given a userid, return that user's acl equivalence group
+
+=cut
+
+sub ACLEquivGroupId {
+    my $id = shift;
+
+    my $cu = $RT::SystemUser;
+    unless ( $cu ) {
+        require RT::CurrentUser;
+        $cu = new RT::CurrentUser;
+        $cu->LoadByName('RT_System');
+        warn "Couldn't load RT_System user" unless $cu->id;
+    }
+
+    my $equiv_group = RT::Group->new( $cu );
+    $equiv_group->LoadACLEquivalenceGroup( $id );
+    return $equiv_group->Id;
+}
+
+__PACKAGE__->FinalizeDatabaseType;
+
+RT::Base->_ImportOverlays();
 
 1;
index ec0e877..fe109d0 100644 (file)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 use strict;
 
 use RT;
@@ -29,14 +54,12 @@ package RT::Interface::CLI;
 
 
 BEGIN {
-    use Exporter ();
-    use vars qw ($VERSION  @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
+    use base 'Exporter';
+    use vars qw ($VERSION  @EXPORT @EXPORT_OK %EXPORT_TAGS);
     
     # set the version for version checking
-    $VERSION = do { my @r = (q$Revision: 1.2 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
-    
-    @ISA         = qw(Exporter);
-    
+    $VERSION = do { my @r = (q$Revision: 1.3 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
+
     # your exported package globals go here,
     # as well as any optionally exported functions
     @EXPORT_OK   = qw(&CleanEnv 
@@ -76,11 +99,6 @@ BEGIN {
 
 =head1 METHODS
 
-=begin testing
-
-ok(require RT::Interface::CLI);
-
-=end testing
 
 =cut
 
@@ -182,9 +200,9 @@ sub GetMessageContent {
     
     #Load the sourcefile, if it's been handed to us
     if ($source) {
-       open (SOURCE, "<$source");
-       @lines = (<SOURCE>);
-       close (SOURCE);
+    open( SOURCE, '<', $source ) or die $!;
+       @lines = (<SOURCE>) or die $!;
+       close (SOURCE) or die $!;
     }
     elsif ($args{'Content'}) {
        @lines = split('\n',$args{'Content'});
@@ -196,21 +214,21 @@ sub GetMessageContent {
     for (@lines) {
        print $fh $_;
     }
-    close ($fh);
+    close ($fh) or die $!;
     
     #Edit the file if we need to
     if ($edit) {       
 
        unless ($ENV{'EDITOR'}) {
-           $RT::Logger->crit('No $EDITOR variable defined'. "\n");
+           $RT::Logger->crit('No $EDITOR variable defined');
            return undef;
        }
        system ($ENV{'EDITOR'}, $filename);
     }  
     
-    open (READ, "<$filename");
+    open( READ, '<', $filename ) or die $!;
     my @newlines = (<READ>);
-    close (READ);
+    close (READ) or die $!;
 
     unlink ($filename) unless (debug());
     return(\@newlines);
@@ -225,7 +243,7 @@ sub debug {
     my $val = shift;
     my ($debug);
     if ($val) {
-       $RT::Logger->debug($val."\n");
+       $RT::Logger->debug($val);
        if ($debug) {
            print STDERR "$val\n";
        }
@@ -238,9 +256,6 @@ sub debug {
 # }}}
 
 
-eval "require RT::Interface::CLI_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Vendor.pm});
-eval "require RT::Interface::CLI_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/CLI_Local.pm});
+RT::Base->_ImportOverlays();
 
 1;
index 962c378..1aff5ef 100644 (file)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -98,7 +123,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -107,14 +132,14 @@ Returns the current value of id.
 =cut
 
 
-=item Base
+=head2 Base
 
 Returns the current value of Base. 
 (In the database, Base is stored as varchar(240).)
 
 
 
-=item SetBase VALUE
+=head2 SetBase VALUE
 
 
 Set Base to VALUE. 
@@ -125,14 +150,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Target
+=head2 Target
 
 Returns the current value of Target. 
 (In the database, Target is stored as varchar(240).)
 
 
 
-=item SetTarget VALUE
+=head2 SetTarget VALUE
 
 
 Set Target to VALUE. 
@@ -143,14 +168,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Type
+=head2 Type
 
 Returns the current value of Type. 
 (In the database, Type is stored as varchar(20).)
 
 
 
-=item SetType VALUE
+=head2 SetType VALUE
 
 
 Set Type to VALUE. 
@@ -161,14 +186,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item LocalTarget
+=head2 LocalTarget
 
 Returns the current value of LocalTarget. 
 (In the database, LocalTarget is stored as int(11).)
 
 
 
-=item SetLocalTarget VALUE
+=head2 SetLocalTarget VALUE
 
 
 Set LocalTarget to VALUE. 
@@ -179,14 +204,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item LocalBase
+=head2 LocalBase
 
 Returns the current value of LocalBase. 
 (In the database, LocalBase is stored as int(11).)
 
 
 
-=item SetLocalBase VALUE
+=head2 SetLocalBase VALUE
 
 
 Set LocalBase to VALUE. 
@@ -197,7 +222,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -206,7 +231,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -215,7 +240,7 @@ Returns the current value of LastUpdated.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -224,7 +249,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -234,51 +259,34 @@ Returns the current value of Created.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Base => 
-               {read => 1, write => 1, type => 'varchar(240)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 240,  is_blob => 0,  is_numeric => 0,  type => 'varchar(240)', default => ''},
         Target => 
-               {read => 1, write => 1, type => 'varchar(240)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 240,  is_blob => 0,  is_numeric => 0,  type => 'varchar(240)', default => ''},
         Type => 
-               {read => 1, write => 1, type => 'varchar(20)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 20,  is_blob => 0,  is_numeric => 0,  type => 'varchar(20)', default => ''},
         LocalTarget => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LocalBase => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::Link_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Link_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Link_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Link_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Link_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Link_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -288,7 +296,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 7a1773a..d8b6025 100644 (file)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Link item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Link->new($self->CurrentUser));
 }
-
-        eval "require RT::Links_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Links_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Links_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Links_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Links_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Links_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index b362c9f..c0a0229 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -107,7 +132,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -116,14 +141,14 @@ Returns the current value of id.
 =cut
 
 
-=item Name
+=head2 Name
 
 Returns the current value of Name. 
 (In the database, Name is stored as varchar(200).)
 
 
 
-=item SetName VALUE
+=head2 SetName VALUE
 
 
 Set Name to VALUE. 
@@ -134,14 +159,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Description
+=head2 Description
 
 Returns the current value of Description. 
 (In the database, Description is stored as varchar(255).)
 
 
 
-=item SetDescription VALUE
+=head2 SetDescription VALUE
 
 
 Set Description to VALUE. 
@@ -152,14 +177,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item CorrespondAddress
+=head2 CorrespondAddress
 
 Returns the current value of CorrespondAddress. 
 (In the database, CorrespondAddress is stored as varchar(120).)
 
 
 
-=item SetCorrespondAddress VALUE
+=head2 SetCorrespondAddress VALUE
 
 
 Set CorrespondAddress to VALUE. 
@@ -170,14 +195,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item CommentAddress
+=head2 CommentAddress
 
 Returns the current value of CommentAddress. 
 (In the database, CommentAddress is stored as varchar(120).)
 
 
 
-=item SetCommentAddress VALUE
+=head2 SetCommentAddress VALUE
 
 
 Set CommentAddress to VALUE. 
@@ -188,14 +213,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item InitialPriority
+=head2 InitialPriority
 
 Returns the current value of InitialPriority. 
 (In the database, InitialPriority is stored as int(11).)
 
 
 
-=item SetInitialPriority VALUE
+=head2 SetInitialPriority VALUE
 
 
 Set InitialPriority to VALUE. 
@@ -206,14 +231,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item FinalPriority
+=head2 FinalPriority
 
 Returns the current value of FinalPriority. 
 (In the database, FinalPriority is stored as int(11).)
 
 
 
-=item SetFinalPriority VALUE
+=head2 SetFinalPriority VALUE
 
 
 Set FinalPriority to VALUE. 
@@ -224,14 +249,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item DefaultDueIn
+=head2 DefaultDueIn
 
 Returns the current value of DefaultDueIn. 
 (In the database, DefaultDueIn is stored as int(11).)
 
 
 
-=item SetDefaultDueIn VALUE
+=head2 SetDefaultDueIn VALUE
 
 
 Set DefaultDueIn to VALUE. 
@@ -242,7 +267,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -251,7 +276,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -260,7 +285,7 @@ Returns the current value of Created.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -269,7 +294,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -278,14 +303,14 @@ Returns the current value of LastUpdated.
 =cut
 
 
-=item Disabled
+=head2 Disabled
 
 Returns the current value of Disabled. 
 (In the database, Disabled is stored as smallint(6).)
 
 
 
-=item SetDisabled VALUE
+=head2 SetDisabled VALUE
 
 
 Set Disabled to VALUE. 
@@ -297,57 +322,40 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Description => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         CorrespondAddress => 
-               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
         CommentAddress => 
-               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
         InitialPriority => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         FinalPriority => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         DefaultDueIn => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Disabled => 
-               {read => 1, write => 1, type => 'smallint(6)', default => '0'},
+               {read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => '0'},
 
  }
 };
 
-
-        eval "require RT::Queue_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Queue_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Queue_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Queue_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Queue_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Queue_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -357,7 +365,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 60aec90..e634a96 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Queue item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Queue->new($self->CurrentUser));
 }
-
-        eval "require RT::Queues_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Queues_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Queues_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Queues_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Queues_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Queues_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index a69dde0..b430a77 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -65,7 +90,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -120,7 +145,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -129,14 +154,14 @@ Returns the current value of id.
 =cut
 
 
-=item Description
+=head2 Description
 
 Returns the current value of Description. 
 (In the database, Description is stored as varchar(255).)
 
 
 
-=item SetDescription VALUE
+=head2 SetDescription VALUE
 
 
 Set Description to VALUE. 
@@ -147,14 +172,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ScripCondition
+=head2 ScripCondition
 
 Returns the current value of ScripCondition. 
 (In the database, ScripCondition is stored as int(11).)
 
 
 
-=item SetScripCondition VALUE
+=head2 SetScripCondition VALUE
 
 
 Set ScripCondition to VALUE. 
@@ -165,7 +190,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ScripConditionObj
+=head2 ScripConditionObj
 
 Returns the ScripCondition Object which has the id returned by ScripCondition
 
@@ -179,14 +204,14 @@ sub ScripConditionObj {
        return($ScripCondition);
 }
 
-=item ScripAction
+=head2 ScripAction
 
 Returns the current value of ScripAction. 
 (In the database, ScripAction is stored as int(11).)
 
 
 
-=item SetScripAction VALUE
+=head2 SetScripAction VALUE
 
 
 Set ScripAction to VALUE. 
@@ -197,7 +222,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ScripActionObj
+=head2 ScripActionObj
 
 Returns the ScripAction Object which has the id returned by ScripAction
 
@@ -211,14 +236,14 @@ sub ScripActionObj {
        return($ScripAction);
 }
 
-=item ConditionRules
+=head2 ConditionRules
 
 Returns the current value of ConditionRules. 
 (In the database, ConditionRules is stored as text.)
 
 
 
-=item SetConditionRules VALUE
+=head2 SetConditionRules VALUE
 
 
 Set ConditionRules to VALUE. 
@@ -229,14 +254,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ActionRules
+=head2 ActionRules
 
 Returns the current value of ActionRules. 
 (In the database, ActionRules is stored as text.)
 
 
 
-=item SetActionRules VALUE
+=head2 SetActionRules VALUE
 
 
 Set ActionRules to VALUE. 
@@ -247,14 +272,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item CustomIsApplicableCode
+=head2 CustomIsApplicableCode
 
 Returns the current value of CustomIsApplicableCode. 
 (In the database, CustomIsApplicableCode is stored as text.)
 
 
 
-=item SetCustomIsApplicableCode VALUE
+=head2 SetCustomIsApplicableCode VALUE
 
 
 Set CustomIsApplicableCode to VALUE. 
@@ -265,14 +290,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item CustomPrepareCode
+=head2 CustomPrepareCode
 
 Returns the current value of CustomPrepareCode. 
 (In the database, CustomPrepareCode is stored as text.)
 
 
 
-=item SetCustomPrepareCode VALUE
+=head2 SetCustomPrepareCode VALUE
 
 
 Set CustomPrepareCode to VALUE. 
@@ -283,14 +308,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item CustomCommitCode
+=head2 CustomCommitCode
 
 Returns the current value of CustomCommitCode. 
 (In the database, CustomCommitCode is stored as text.)
 
 
 
-=item SetCustomCommitCode VALUE
+=head2 SetCustomCommitCode VALUE
 
 
 Set CustomCommitCode to VALUE. 
@@ -301,14 +326,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Stage
+=head2 Stage
 
 Returns the current value of Stage. 
 (In the database, Stage is stored as varchar(32).)
 
 
 
-=item SetStage VALUE
+=head2 SetStage VALUE
 
 
 Set Stage to VALUE. 
@@ -319,14 +344,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Queue
+=head2 Queue
 
 Returns the current value of Queue. 
 (In the database, Queue is stored as int(11).)
 
 
 
-=item SetQueue VALUE
+=head2 SetQueue VALUE
 
 
 Set Queue to VALUE. 
@@ -337,7 +362,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item QueueObj
+=head2 QueueObj
 
 Returns the Queue Object which has the id returned by Queue
 
@@ -351,14 +376,14 @@ sub QueueObj {
        return($Queue);
 }
 
-=item Template
+=head2 Template
 
 Returns the current value of Template. 
 (In the database, Template is stored as int(11).)
 
 
 
-=item SetTemplate VALUE
+=head2 SetTemplate VALUE
 
 
 Set Template to VALUE. 
@@ -369,7 +394,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item TemplateObj
+=head2 TemplateObj
 
 Returns the Template Object which has the id returned by Template
 
@@ -383,7 +408,7 @@ sub TemplateObj {
        return($Template);
 }
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -392,7 +417,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -401,7 +426,7 @@ Returns the current value of Created.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -410,7 +435,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -420,63 +445,46 @@ Returns the current value of LastUpdated.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Description => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         ScripCondition => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         ScripAction => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         ConditionRules => 
-               {read => 1, write => 1, type => 'text', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         ActionRules => 
-               {read => 1, write => 1, type => 'text', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         CustomIsApplicableCode => 
-               {read => 1, write => 1, type => 'text', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         CustomPrepareCode => 
-               {read => 1, write => 1, type => 'text', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         CustomCommitCode => 
-               {read => 1, write => 1, type => 'text', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         Stage => 
-               {read => 1, write => 1, type => 'varchar(32)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 32,  is_blob => 0,  is_numeric => 0,  type => 'varchar(32)', default => ''},
         Queue => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Template => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::Scrip_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Scrip_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Scrip_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Scrip_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Scrip_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Scrip_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -486,7 +494,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 26824df..21a8a0e 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -95,7 +120,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -104,14 +129,14 @@ Returns the current value of id.
 =cut
 
 
-=item Name
+=head2 Name
 
 Returns the current value of Name. 
 (In the database, Name is stored as varchar(200).)
 
 
 
-=item SetName VALUE
+=head2 SetName VALUE
 
 
 Set Name to VALUE. 
@@ -122,14 +147,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Description
+=head2 Description
 
 Returns the current value of Description. 
 (In the database, Description is stored as varchar(255).)
 
 
 
-=item SetDescription VALUE
+=head2 SetDescription VALUE
 
 
 Set Description to VALUE. 
@@ -140,14 +165,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ExecModule
+=head2 ExecModule
 
 Returns the current value of ExecModule. 
 (In the database, ExecModule is stored as varchar(60).)
 
 
 
-=item SetExecModule VALUE
+=head2 SetExecModule VALUE
 
 
 Set ExecModule to VALUE. 
@@ -158,14 +183,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Argument
+=head2 Argument
 
 Returns the current value of Argument. 
 (In the database, Argument is stored as varchar(255).)
 
 
 
-=item SetArgument VALUE
+=head2 SetArgument VALUE
 
 
 Set Argument to VALUE. 
@@ -176,7 +201,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -185,7 +210,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -194,7 +219,7 @@ Returns the current value of Created.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -203,7 +228,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -213,49 +238,32 @@ Returns the current value of LastUpdated.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Description => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         ExecModule => 
-               {read => 1, write => 1, type => 'varchar(60)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 60,  is_blob => 0,  is_numeric => 0,  type => 'varchar(60)', default => ''},
         Argument => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::ScripAction_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripAction_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripAction_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripAction_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripAction_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripAction_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -265,7 +273,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 614ff37..d2f987c 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::ScripAction item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::ScripAction->new($self->CurrentUser));
 }
-
-        eval "require RT::ScripActions_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripActions_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripActions_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripActions_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripActions_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripActions_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index fe0aa2d..48ea27a 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -98,7 +123,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -107,14 +132,14 @@ Returns the current value of id.
 =cut
 
 
-=item Name
+=head2 Name
 
 Returns the current value of Name. 
 (In the database, Name is stored as varchar(200).)
 
 
 
-=item SetName VALUE
+=head2 SetName VALUE
 
 
 Set Name to VALUE. 
@@ -125,14 +150,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Description
+=head2 Description
 
 Returns the current value of Description. 
 (In the database, Description is stored as varchar(255).)
 
 
 
-=item SetDescription VALUE
+=head2 SetDescription VALUE
 
 
 Set Description to VALUE. 
@@ -143,14 +168,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ExecModule
+=head2 ExecModule
 
 Returns the current value of ExecModule. 
 (In the database, ExecModule is stored as varchar(60).)
 
 
 
-=item SetExecModule VALUE
+=head2 SetExecModule VALUE
 
 
 Set ExecModule to VALUE. 
@@ -161,14 +186,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Argument
+=head2 Argument
 
 Returns the current value of Argument. 
 (In the database, Argument is stored as varchar(255).)
 
 
 
-=item SetArgument VALUE
+=head2 SetArgument VALUE
 
 
 Set Argument to VALUE. 
@@ -179,14 +204,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ApplicableTransTypes
+=head2 ApplicableTransTypes
 
 Returns the current value of ApplicableTransTypes. 
 (In the database, ApplicableTransTypes is stored as varchar(60).)
 
 
 
-=item SetApplicableTransTypes VALUE
+=head2 SetApplicableTransTypes VALUE
 
 
 Set ApplicableTransTypes to VALUE. 
@@ -197,7 +222,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -206,7 +231,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -215,7 +240,7 @@ Returns the current value of Created.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -224,7 +249,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -234,51 +259,34 @@ Returns the current value of LastUpdated.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Description => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         ExecModule => 
-               {read => 1, write => 1, type => 'varchar(60)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 60,  is_blob => 0,  is_numeric => 0,  type => 'varchar(60)', default => ''},
         Argument => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         ApplicableTransTypes => 
-               {read => 1, write => 1, type => 'varchar(60)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 60,  is_blob => 0,  is_numeric => 0,  type => 'varchar(60)', default => ''},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::ScripCondition_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripCondition_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripCondition_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripCondition_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripCondition_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripCondition_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -288,7 +296,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 34f788d..76777cb 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::ScripCondition item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::ScripCondition->new($self->CurrentUser));
 }
-
-        eval "require RT::ScripConditions_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripConditions_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripConditions_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripConditions_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::ScripConditions_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/ScripConditions_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index a394431..7e63217 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Scrip item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Scrip->new($self->CurrentUser));
 }
-
-        eval "require RT::Scrips_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Scrips_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Scrips_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Scrips_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Scrips_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Scrips_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index f73ea3e..b77820d 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -62,7 +87,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -105,7 +130,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -114,14 +139,14 @@ Returns the current value of id.
 =cut
 
 
-=item Queue
+=head2 Queue
 
 Returns the current value of Queue. 
 (In the database, Queue is stored as int(11).)
 
 
 
-=item SetQueue VALUE
+=head2 SetQueue VALUE
 
 
 Set Queue to VALUE. 
@@ -132,7 +157,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item QueueObj
+=head2 QueueObj
 
 Returns the Queue Object which has the id returned by Queue
 
@@ -146,14 +171,14 @@ sub QueueObj {
        return($Queue);
 }
 
-=item Name
+=head2 Name
 
 Returns the current value of Name. 
 (In the database, Name is stored as varchar(200).)
 
 
 
-=item SetName VALUE
+=head2 SetName VALUE
 
 
 Set Name to VALUE. 
@@ -164,14 +189,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Description
+=head2 Description
 
 Returns the current value of Description. 
 (In the database, Description is stored as varchar(255).)
 
 
 
-=item SetDescription VALUE
+=head2 SetDescription VALUE
 
 
 Set Description to VALUE. 
@@ -182,14 +207,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Type
+=head2 Type
 
 Returns the current value of Type. 
 (In the database, Type is stored as varchar(16).)
 
 
 
-=item SetType VALUE
+=head2 SetType VALUE
 
 
 Set Type to VALUE. 
@@ -200,14 +225,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Language
+=head2 Language
 
 Returns the current value of Language. 
 (In the database, Language is stored as varchar(16).)
 
 
 
-=item SetLanguage VALUE
+=head2 SetLanguage VALUE
 
 
 Set Language to VALUE. 
@@ -218,14 +243,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item TranslationOf
+=head2 TranslationOf
 
 Returns the current value of TranslationOf. 
 (In the database, TranslationOf is stored as int(11).)
 
 
 
-=item SetTranslationOf VALUE
+=head2 SetTranslationOf VALUE
 
 
 Set TranslationOf to VALUE. 
@@ -236,14 +261,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Content
+=head2 Content
 
 Returns the current value of Content. 
 (In the database, Content is stored as blob.)
 
 
 
-=item SetContent VALUE
+=head2 SetContent VALUE
 
 
 Set Content to VALUE. 
@@ -254,7 +279,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -263,7 +288,7 @@ Returns the current value of LastUpdated.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -272,7 +297,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -281,7 +306,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -291,55 +316,38 @@ Returns the current value of Created.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Queue => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Name => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Description => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Type => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         Language => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         TranslationOf => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Content => 
-               {read => 1, write => 1, type => 'blob', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'blob', default => ''},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::Template_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Template_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Template_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Template_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Template_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Template_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -349,7 +357,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 37db840..97b37c5 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Template item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Template->new($self->CurrentUser));
 }
-
-        eval "require RT::Templates_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Templates_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Templates_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Templates_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Templates_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Templates_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 2f075a2..edf38f0 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -62,7 +87,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -116,7 +141,7 @@ sub Create {
                 Resolved => '',
                 Disabled => '0',
 
-                 @_);
+          @_);
     $self->SUPER::Create(
                          EffectiveId => $args{'EffectiveId'},
                          Queue => $args{'Queue'},
@@ -144,7 +169,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -153,14 +178,14 @@ Returns the current value of id.
 =cut
 
 
-=item EffectiveId
+=head2 EffectiveId
 
 Returns the current value of EffectiveId. 
 (In the database, EffectiveId is stored as int(11).)
 
 
 
-=item SetEffectiveId VALUE
+=head2 SetEffectiveId VALUE
 
 
 Set EffectiveId to VALUE. 
@@ -171,14 +196,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Queue
+=head2 Queue
 
 Returns the current value of Queue. 
 (In the database, Queue is stored as int(11).)
 
 
 
-=item SetQueue VALUE
+=head2 SetQueue VALUE
 
 
 Set Queue to VALUE. 
@@ -189,7 +214,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item QueueObj
+=head2 QueueObj
 
 Returns the Queue Object which has the id returned by Queue
 
@@ -197,20 +222,22 @@ Returns the Queue Object which has the id returned by Queue
 =cut
 
 sub QueueObj {
-       my $self = shift;
-       my $Queue =  RT::Queue->new($self->CurrentUser);
-       $Queue->Load($self->__Value('Queue'));
-       return($Queue);
+    my $self = shift;
+    my $Queue =  RT::Queue->new($self->CurrentUser);
+    $Queue->Load($self->__Value('Queue'));
+    return($Queue);
 }
 
-=item Type
+
+
+=head2 Type
 
 Returns the current value of Type. 
 (In the database, Type is stored as varchar(16).)
 
 
 
-=item SetType VALUE
+=head2 SetType VALUE
 
 
 Set Type to VALUE. 
@@ -221,14 +248,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item IssueStatement
+=head2 IssueStatement
 
 Returns the current value of IssueStatement. 
 (In the database, IssueStatement is stored as int(11).)
 
 
 
-=item SetIssueStatement VALUE
+=head2 SetIssueStatement VALUE
 
 
 Set IssueStatement to VALUE. 
@@ -239,14 +266,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Resolution
+=head2 Resolution
 
 Returns the current value of Resolution. 
 (In the database, Resolution is stored as int(11).)
 
 
 
-=item SetResolution VALUE
+=head2 SetResolution VALUE
 
 
 Set Resolution to VALUE. 
@@ -257,14 +284,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Owner
+=head2 Owner
 
 Returns the current value of Owner. 
 (In the database, Owner is stored as int(11).)
 
 
 
-=item SetOwner VALUE
+=head2 SetOwner VALUE
 
 
 Set Owner to VALUE. 
@@ -275,14 +302,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Subject
+=head2 Subject
 
 Returns the current value of Subject. 
 (In the database, Subject is stored as varchar(200).)
 
 
 
-=item SetSubject VALUE
+=head2 SetSubject VALUE
 
 
 Set Subject to VALUE. 
@@ -293,14 +320,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item InitialPriority
+=head2 InitialPriority
 
 Returns the current value of InitialPriority. 
 (In the database, InitialPriority is stored as int(11).)
 
 
 
-=item SetInitialPriority VALUE
+=head2 SetInitialPriority VALUE
 
 
 Set InitialPriority to VALUE. 
@@ -311,14 +338,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item FinalPriority
+=head2 FinalPriority
 
 Returns the current value of FinalPriority. 
 (In the database, FinalPriority is stored as int(11).)
 
 
 
-=item SetFinalPriority VALUE
+=head2 SetFinalPriority VALUE
 
 
 Set FinalPriority to VALUE. 
@@ -329,14 +356,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Priority
+=head2 Priority
 
 Returns the current value of Priority. 
 (In the database, Priority is stored as int(11).)
 
 
 
-=item SetPriority VALUE
+=head2 SetPriority VALUE
 
 
 Set Priority to VALUE. 
@@ -347,14 +374,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item TimeEstimated
+=head2 TimeEstimated
 
 Returns the current value of TimeEstimated. 
 (In the database, TimeEstimated is stored as int(11).)
 
 
 
-=item SetTimeEstimated VALUE
+=head2 SetTimeEstimated VALUE
 
 
 Set TimeEstimated to VALUE. 
@@ -365,14 +392,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item TimeWorked
+=head2 TimeWorked
 
 Returns the current value of TimeWorked. 
 (In the database, TimeWorked is stored as int(11).)
 
 
 
-=item SetTimeWorked VALUE
+=head2 SetTimeWorked VALUE
 
 
 Set TimeWorked to VALUE. 
@@ -383,14 +410,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Status
+=head2 Status
 
 Returns the current value of Status. 
 (In the database, Status is stored as varchar(10).)
 
 
 
-=item SetStatus VALUE
+=head2 SetStatus VALUE
 
 
 Set Status to VALUE. 
@@ -401,14 +428,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item TimeLeft
+=head2 TimeLeft
 
 Returns the current value of TimeLeft. 
 (In the database, TimeLeft is stored as int(11).)
 
 
 
-=item SetTimeLeft VALUE
+=head2 SetTimeLeft VALUE
 
 
 Set TimeLeft to VALUE. 
@@ -419,14 +446,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Told
+=head2 Told
 
 Returns the current value of Told. 
 (In the database, Told is stored as datetime.)
 
 
 
-=item SetTold VALUE
+=head2 SetTold VALUE
 
 
 Set Told to VALUE. 
@@ -437,14 +464,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Starts
+=head2 Starts
 
 Returns the current value of Starts. 
 (In the database, Starts is stored as datetime.)
 
 
 
-=item SetStarts VALUE
+=head2 SetStarts VALUE
 
 
 Set Starts to VALUE. 
@@ -455,14 +482,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Started
+=head2 Started
 
 Returns the current value of Started. 
 (In the database, Started is stored as datetime.)
 
 
 
-=item SetStarted VALUE
+=head2 SetStarted VALUE
 
 
 Set Started to VALUE. 
@@ -473,14 +500,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Due
+=head2 Due
 
 Returns the current value of Due. 
 (In the database, Due is stored as datetime.)
 
 
 
-=item SetDue VALUE
+=head2 SetDue VALUE
 
 
 Set Due to VALUE. 
@@ -491,14 +518,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Resolved
+=head2 Resolved
 
 Returns the current value of Resolved. 
 (In the database, Resolved is stored as datetime.)
 
 
 
-=item SetResolved VALUE
+=head2 SetResolved VALUE
 
 
 Set Resolved to VALUE. 
@@ -509,7 +536,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -518,7 +545,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -527,7 +554,7 @@ Returns the current value of LastUpdated.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -536,7 +563,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -545,14 +572,14 @@ Returns the current value of Created.
 =cut
 
 
-=item Disabled
+=head2 Disabled
 
 Returns the current value of Disabled. 
 (In the database, Disabled is stored as smallint(6).)
 
 
 
-=item SetDisabled VALUE
+=head2 SetDisabled VALUE
 
 
 Set Disabled to VALUE. 
@@ -564,81 +591,64 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+        {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         EffectiveId => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Queue => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Type => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         IssueStatement => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Resolution => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Owner => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Subject => 
-               {read => 1, write => 1, type => 'varchar(200)', default => '[no subject]'},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '[no subject]'},
         InitialPriority => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         FinalPriority => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Priority => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         TimeEstimated => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         TimeWorked => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Status => 
-               {read => 1, write => 1, type => 'varchar(10)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 10,  is_blob => 0,  is_numeric => 0,  type => 'varchar(10)', default => ''},
         TimeLeft => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+        {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Told => 
-               {read => 1, write => 1, type => 'datetime', default => ''},
+        {read => 1, write => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Starts => 
-               {read => 1, write => 1, type => 'datetime', default => ''},
+        {read => 1, write => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Started => 
-               {read => 1, write => 1, type => 'datetime', default => ''},
+        {read => 1, write => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Due => 
-               {read => 1, write => 1, type => 'datetime', default => ''},
+        {read => 1, write => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Resolved => 
-               {read => 1, write => 1, type => 'datetime', default => ''},
+        {read => 1, write => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+        {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+        {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+        {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         Disabled => 
-               {read => 1, write => 1, type => 'smallint(6)', default => '0'},
+        {read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => '0'},
 
  }
 };
 
-
-        eval "require RT::Ticket_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Ticket_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Ticket_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Ticket_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Ticket_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Ticket_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -648,7 +658,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index b6b3491..b3a84ae 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Ticket item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Ticket->new($self->CurrentUser));
 }
-
-        eval "require RT::Tickets_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Tickets_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Tickets_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Tickets_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Tickets_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Tickets_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index ca491a6..bc2b5cd 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -45,7 +70,6 @@ RT::Transaction
 
 package RT::Transaction;
 use RT::Record; 
-use RT::Ticket;
 
 
 use vars qw( @ISA );
@@ -62,18 +86,21 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
-  int(11) 'EffectiveTicket'.
-  int(11) 'Ticket'.
+  varchar(64) 'ObjectType'.
+  int(11) 'ObjectId'.
   int(11) 'TimeTaken'.
   varchar(20) 'Type'.
   varchar(40) 'Field'.
   varchar(255) 'OldValue'.
   varchar(255) 'NewValue'.
-  varchar(100) 'Data'.
+  varchar(255) 'ReferenceType'.
+  int(11) 'OldReference'.
+  int(11) 'NewReference'.
+  varchar(255) 'Data'.
 
 =cut
 
@@ -83,24 +110,30 @@ Create takes a hash of values and creates a row in the database:
 sub Create {
     my $self = shift;
     my %args = ( 
-                EffectiveTicket => '0',
-                Ticket => '0',
+                ObjectType => '',
+                ObjectId => '0',
                 TimeTaken => '0',
                 Type => '',
                 Field => '',
                 OldValue => '',
                 NewValue => '',
+                ReferenceType => '',
+                OldReference => '',
+                NewReference => '',
                 Data => '',
 
                  @_);
     $self->SUPER::Create(
-                         EffectiveTicket => $args{'EffectiveTicket'},
-                         Ticket => $args{'Ticket'},
+                         ObjectType => $args{'ObjectType'},
+                         ObjectId => $args{'ObjectId'},
                          TimeTaken => $args{'TimeTaken'},
                          Type => $args{'Type'},
                          Field => $args{'Field'},
                          OldValue => $args{'OldValue'},
                          NewValue => $args{'NewValue'},
+                         ReferenceType => $args{'ReferenceType'},
+                         OldReference => $args{'OldReference'},
+                         NewReference => $args{'NewReference'},
                          Data => $args{'Data'},
 );
 
@@ -108,7 +141,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -117,64 +150,50 @@ Returns the current value of id.
 =cut
 
 
-=item EffectiveTicket
+=head2 ObjectType
 
-Returns the current value of EffectiveTicket
-(In the database, EffectiveTicket is stored as int(11).)
+Returns the current value of ObjectType
+(In the database, ObjectType is stored as varchar(64).)
 
 
 
-=item SetEffectiveTicket VALUE
+=head2 SetObjectType VALUE
 
 
-Set EffectiveTicket to VALUE. 
+Set ObjectType to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, EffectiveTicket will be stored as a int(11).)
+(In the database, ObjectType will be stored as a varchar(64).)
 
 
 =cut
 
 
-=item Ticket
+=head2 ObjectId
 
-Returns the current value of Ticket
-(In the database, Ticket is stored as int(11).)
+Returns the current value of ObjectId
+(In the database, ObjectId is stored as int(11).)
 
 
 
-=item SetTicket VALUE
+=head2 SetObjectId VALUE
 
 
-Set Ticket to VALUE. 
+Set ObjectId to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Ticket will be stored as a int(11).)
+(In the database, ObjectId will be stored as a int(11).)
 
 
 =cut
 
 
-=item TicketObj
-
-Returns the Ticket Object which has the id returned by Ticket
-
-
-=cut
-
-sub TicketObj {
-       my $self = shift;
-       my $Ticket =  RT::Ticket->new($self->CurrentUser);
-       $Ticket->Load($self->__Value('Ticket'));
-       return($Ticket);
-}
-
-=item TimeTaken
+=head2 TimeTaken
 
 Returns the current value of TimeTaken. 
 (In the database, TimeTaken is stored as int(11).)
 
 
 
-=item SetTimeTaken VALUE
+=head2 SetTimeTaken VALUE
 
 
 Set TimeTaken to VALUE. 
@@ -185,14 +204,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Type
+=head2 Type
 
 Returns the current value of Type. 
 (In the database, Type is stored as varchar(20).)
 
 
 
-=item SetType VALUE
+=head2 SetType VALUE
 
 
 Set Type to VALUE. 
@@ -203,14 +222,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Field
+=head2 Field
 
 Returns the current value of Field. 
 (In the database, Field is stored as varchar(40).)
 
 
 
-=item SetField VALUE
+=head2 SetField VALUE
 
 
 Set Field to VALUE. 
@@ -221,14 +240,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item OldValue
+=head2 OldValue
 
 Returns the current value of OldValue. 
 (In the database, OldValue is stored as varchar(255).)
 
 
 
-=item SetOldValue VALUE
+=head2 SetOldValue VALUE
 
 
 Set OldValue to VALUE. 
@@ -239,14 +258,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item NewValue
+=head2 NewValue
 
 Returns the current value of NewValue. 
 (In the database, NewValue is stored as varchar(255).)
 
 
 
-=item SetNewValue VALUE
+=head2 SetNewValue VALUE
 
 
 Set NewValue to VALUE. 
@@ -257,25 +276,79 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Data
+=head2 ReferenceType
+
+Returns the current value of ReferenceType. 
+(In the database, ReferenceType is stored as varchar(255).)
+
+
+
+=head2 SetReferenceType VALUE
+
+
+Set ReferenceType to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, ReferenceType will be stored as a varchar(255).)
+
+
+=cut
+
+
+=head2 OldReference
+
+Returns the current value of OldReference. 
+(In the database, OldReference is stored as int(11).)
+
+
+
+=head2 SetOldReference VALUE
+
+
+Set OldReference to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, OldReference will be stored as a int(11).)
+
+
+=cut
+
+
+=head2 NewReference
+
+Returns the current value of NewReference. 
+(In the database, NewReference is stored as int(11).)
+
+
+
+=head2 SetNewReference VALUE
+
+
+Set NewReference to VALUE. 
+Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
+(In the database, NewReference will be stored as a int(11).)
+
+
+=cut
+
+
+=head2 Data
 
 Returns the current value of Data. 
-(In the database, Data is stored as varchar(100).)
+(In the database, Data is stored as varchar(255).)
 
 
 
-=item SetData VALUE
+=head2 SetData VALUE
 
 
 Set Data to VALUE. 
 Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
-(In the database, Data will be stored as a varchar(100).)
+(In the database, Data will be stored as a varchar(255).)
 
 
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -284,7 +357,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -294,53 +367,42 @@ Returns the current value of Created.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
-        EffectiveTicket => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
-        Ticket => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
+        ObjectType => 
+               {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
+        ObjectId => 
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         TimeTaken => 
-               {read => 1, write => 1, type => 'int(11)', default => '0'},
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Type => 
-               {read => 1, write => 1, type => 'varchar(20)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 20,  is_blob => 0,  is_numeric => 0,  type => 'varchar(20)', default => ''},
         Field => 
-               {read => 1, write => 1, type => 'varchar(40)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 40,  is_blob => 0,  is_numeric => 0,  type => 'varchar(40)', default => ''},
         OldValue => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         NewValue => 
-               {read => 1, write => 1, type => 'varchar(255)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+        ReferenceType => 
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+        OldReference => 
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
+        NewReference => 
+               {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Data => 
-               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::Transaction_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Transaction_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Transaction_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Transaction_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -350,7 +412,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index 23a475a..0b977c6 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::Transaction item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::Transaction->new($self->CurrentUser));
 }
-
-        eval "require RT::Transactions_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Transactions_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Transactions_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Transactions_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Transactions_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Transactions_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index cbc10f5..b7ebd5b 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -61,7 +86,7 @@ sub _Init {
 
 
 
-=item Create PARAMHASH
+=head2 Create PARAMHASH
 
 Create takes a hash of values and creates a row in the database:
 
@@ -170,7 +195,7 @@ sub Create {
 
 
 
-=item id
+=head2 id
 
 Returns the current value of id. 
 (In the database, id is stored as int(11).)
@@ -179,14 +204,14 @@ Returns the current value of id.
 =cut
 
 
-=item Name
+=head2 Name
 
 Returns the current value of Name. 
 (In the database, Name is stored as varchar(200).)
 
 
 
-=item SetName VALUE
+=head2 SetName VALUE
 
 
 Set Name to VALUE. 
@@ -197,14 +222,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Password
+=head2 Password
 
 Returns the current value of Password. 
 (In the database, Password is stored as varchar(40).)
 
 
 
-=item SetPassword VALUE
+=head2 SetPassword VALUE
 
 
 Set Password to VALUE. 
@@ -215,14 +240,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Comments
+=head2 Comments
 
 Returns the current value of Comments. 
 (In the database, Comments is stored as blob.)
 
 
 
-=item SetComments VALUE
+=head2 SetComments VALUE
 
 
 Set Comments to VALUE. 
@@ -233,14 +258,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Signature
+=head2 Signature
 
 Returns the current value of Signature. 
 (In the database, Signature is stored as blob.)
 
 
 
-=item SetSignature VALUE
+=head2 SetSignature VALUE
 
 
 Set Signature to VALUE. 
@@ -251,14 +276,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item EmailAddress
+=head2 EmailAddress
 
 Returns the current value of EmailAddress. 
 (In the database, EmailAddress is stored as varchar(120).)
 
 
 
-=item SetEmailAddress VALUE
+=head2 SetEmailAddress VALUE
 
 
 Set EmailAddress to VALUE. 
@@ -269,14 +294,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item FreeformContactInfo
+=head2 FreeformContactInfo
 
 Returns the current value of FreeformContactInfo. 
 (In the database, FreeformContactInfo is stored as blob.)
 
 
 
-=item SetFreeformContactInfo VALUE
+=head2 SetFreeformContactInfo VALUE
 
 
 Set FreeformContactInfo to VALUE. 
@@ -287,14 +312,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Organization
+=head2 Organization
 
 Returns the current value of Organization. 
 (In the database, Organization is stored as varchar(200).)
 
 
 
-=item SetOrganization VALUE
+=head2 SetOrganization VALUE
 
 
 Set Organization to VALUE. 
@@ -305,14 +330,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item RealName
+=head2 RealName
 
 Returns the current value of RealName. 
 (In the database, RealName is stored as varchar(120).)
 
 
 
-=item SetRealName VALUE
+=head2 SetRealName VALUE
 
 
 Set RealName to VALUE. 
@@ -323,14 +348,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item NickName
+=head2 NickName
 
 Returns the current value of NickName. 
 (In the database, NickName is stored as varchar(16).)
 
 
 
-=item SetNickName VALUE
+=head2 SetNickName VALUE
 
 
 Set NickName to VALUE. 
@@ -341,14 +366,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Lang
+=head2 Lang
 
 Returns the current value of Lang. 
 (In the database, Lang is stored as varchar(16).)
 
 
 
-=item SetLang VALUE
+=head2 SetLang VALUE
 
 
 Set Lang to VALUE. 
@@ -359,14 +384,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item EmailEncoding
+=head2 EmailEncoding
 
 Returns the current value of EmailEncoding. 
 (In the database, EmailEncoding is stored as varchar(16).)
 
 
 
-=item SetEmailEncoding VALUE
+=head2 SetEmailEncoding VALUE
 
 
 Set EmailEncoding to VALUE. 
@@ -377,14 +402,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item WebEncoding
+=head2 WebEncoding
 
 Returns the current value of WebEncoding. 
 (In the database, WebEncoding is stored as varchar(16).)
 
 
 
-=item SetWebEncoding VALUE
+=head2 SetWebEncoding VALUE
 
 
 Set WebEncoding to VALUE. 
@@ -395,14 +420,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ExternalContactInfoId
+=head2 ExternalContactInfoId
 
 Returns the current value of ExternalContactInfoId. 
 (In the database, ExternalContactInfoId is stored as varchar(100).)
 
 
 
-=item SetExternalContactInfoId VALUE
+=head2 SetExternalContactInfoId VALUE
 
 
 Set ExternalContactInfoId to VALUE. 
@@ -413,14 +438,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ContactInfoSystem
+=head2 ContactInfoSystem
 
 Returns the current value of ContactInfoSystem. 
 (In the database, ContactInfoSystem is stored as varchar(30).)
 
 
 
-=item SetContactInfoSystem VALUE
+=head2 SetContactInfoSystem VALUE
 
 
 Set ContactInfoSystem to VALUE. 
@@ -431,14 +456,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item ExternalAuthId
+=head2 ExternalAuthId
 
 Returns the current value of ExternalAuthId. 
 (In the database, ExternalAuthId is stored as varchar(100).)
 
 
 
-=item SetExternalAuthId VALUE
+=head2 SetExternalAuthId VALUE
 
 
 Set ExternalAuthId to VALUE. 
@@ -449,14 +474,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item AuthSystem
+=head2 AuthSystem
 
 Returns the current value of AuthSystem. 
 (In the database, AuthSystem is stored as varchar(30).)
 
 
 
-=item SetAuthSystem VALUE
+=head2 SetAuthSystem VALUE
 
 
 Set AuthSystem to VALUE. 
@@ -467,14 +492,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Gecos
+=head2 Gecos
 
 Returns the current value of Gecos. 
 (In the database, Gecos is stored as varchar(16).)
 
 
 
-=item SetGecos VALUE
+=head2 SetGecos VALUE
 
 
 Set Gecos to VALUE. 
@@ -485,14 +510,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item HomePhone
+=head2 HomePhone
 
 Returns the current value of HomePhone. 
 (In the database, HomePhone is stored as varchar(30).)
 
 
 
-=item SetHomePhone VALUE
+=head2 SetHomePhone VALUE
 
 
 Set HomePhone to VALUE. 
@@ -503,14 +528,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item WorkPhone
+=head2 WorkPhone
 
 Returns the current value of WorkPhone. 
 (In the database, WorkPhone is stored as varchar(30).)
 
 
 
-=item SetWorkPhone VALUE
+=head2 SetWorkPhone VALUE
 
 
 Set WorkPhone to VALUE. 
@@ -521,14 +546,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item MobilePhone
+=head2 MobilePhone
 
 Returns the current value of MobilePhone. 
 (In the database, MobilePhone is stored as varchar(30).)
 
 
 
-=item SetMobilePhone VALUE
+=head2 SetMobilePhone VALUE
 
 
 Set MobilePhone to VALUE. 
@@ -539,14 +564,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item PagerPhone
+=head2 PagerPhone
 
 Returns the current value of PagerPhone. 
 (In the database, PagerPhone is stored as varchar(30).)
 
 
 
-=item SetPagerPhone VALUE
+=head2 SetPagerPhone VALUE
 
 
 Set PagerPhone to VALUE. 
@@ -557,14 +582,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Address1
+=head2 Address1
 
 Returns the current value of Address1. 
 (In the database, Address1 is stored as varchar(200).)
 
 
 
-=item SetAddress1 VALUE
+=head2 SetAddress1 VALUE
 
 
 Set Address1 to VALUE. 
@@ -575,14 +600,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Address2
+=head2 Address2
 
 Returns the current value of Address2. 
 (In the database, Address2 is stored as varchar(200).)
 
 
 
-=item SetAddress2 VALUE
+=head2 SetAddress2 VALUE
 
 
 Set Address2 to VALUE. 
@@ -593,14 +618,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item City
+=head2 City
 
 Returns the current value of City. 
 (In the database, City is stored as varchar(100).)
 
 
 
-=item SetCity VALUE
+=head2 SetCity VALUE
 
 
 Set City to VALUE. 
@@ -611,14 +636,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item State
+=head2 State
 
 Returns the current value of State. 
 (In the database, State is stored as varchar(100).)
 
 
 
-=item SetState VALUE
+=head2 SetState VALUE
 
 
 Set State to VALUE. 
@@ -629,14 +654,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Zip
+=head2 Zip
 
 Returns the current value of Zip. 
 (In the database, Zip is stored as varchar(16).)
 
 
 
-=item SetZip VALUE
+=head2 SetZip VALUE
 
 
 Set Zip to VALUE. 
@@ -647,14 +672,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Country
+=head2 Country
 
 Returns the current value of Country. 
 (In the database, Country is stored as varchar(50).)
 
 
 
-=item SetCountry VALUE
+=head2 SetCountry VALUE
 
 
 Set Country to VALUE. 
@@ -665,14 +690,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Timezone
+=head2 Timezone
 
 Returns the current value of Timezone. 
 (In the database, Timezone is stored as varchar(50).)
 
 
 
-=item SetTimezone VALUE
+=head2 SetTimezone VALUE
 
 
 Set Timezone to VALUE. 
@@ -683,14 +708,14 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item PGPKey
+=head2 PGPKey
 
 Returns the current value of PGPKey. 
 (In the database, PGPKey is stored as text.)
 
 
 
-=item SetPGPKey VALUE
+=head2 SetPGPKey VALUE
 
 
 Set PGPKey to VALUE. 
@@ -701,7 +726,7 @@ Returns (1, 'Status message') on success and (0, 'Error Message') on failure.
 =cut
 
 
-=item Creator
+=head2 Creator
 
 Returns the current value of Creator. 
 (In the database, Creator is stored as int(11).)
@@ -710,7 +735,7 @@ Returns the current value of Creator.
 =cut
 
 
-=item Created
+=head2 Created
 
 Returns the current value of Created. 
 (In the database, Created is stored as datetime.)
@@ -719,7 +744,7 @@ Returns the current value of Created.
 =cut
 
 
-=item LastUpdatedBy
+=head2 LastUpdatedBy
 
 Returns the current value of LastUpdatedBy. 
 (In the database, LastUpdatedBy is stored as int(11).)
@@ -728,7 +753,7 @@ Returns the current value of LastUpdatedBy.
 =cut
 
 
-=item LastUpdated
+=head2 LastUpdated
 
 Returns the current value of LastUpdated. 
 (In the database, LastUpdated is stored as datetime.)
@@ -738,99 +763,82 @@ Returns the current value of LastUpdated.
 
 
 
-sub _ClassAccessible {
+sub _CoreAccessible {
     {
      
         id =>
-               {read => 1, type => 'int(11)', default => ''},
+               {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Password => 
-               {read => 1, write => 1, type => 'varchar(40)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 40,  is_blob => 0,  is_numeric => 0,  type => 'varchar(40)', default => ''},
         Comments => 
-               {read => 1, write => 1, type => 'blob', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'blob', default => ''},
         Signature => 
-               {read => 1, write => 1, type => 'blob', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'blob', default => ''},
         EmailAddress => 
-               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
         FreeformContactInfo => 
-               {read => 1, write => 1, type => 'blob', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'blob', default => ''},
         Organization => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         RealName => 
-               {read => 1, write => 1, type => 'varchar(120)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
         NickName => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         Lang => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         EmailEncoding => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         WebEncoding => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         ExternalContactInfoId => 
-               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => ''},
         ContactInfoSystem => 
-               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
         ExternalAuthId => 
-               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => ''},
         AuthSystem => 
-               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
         Gecos => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         HomePhone => 
-               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
         WorkPhone => 
-               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
         MobilePhone => 
-               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
         PagerPhone => 
-               {read => 1, write => 1, type => 'varchar(30)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
         Address1 => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Address2 => 
-               {read => 1, write => 1, type => 'varchar(200)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         City => 
-               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => ''},
         State => 
-               {read => 1, write => 1, type => 'varchar(100)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => ''},
         Zip => 
-               {read => 1, write => 1, type => 'varchar(16)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         Country => 
-               {read => 1, write => 1, type => 'varchar(50)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 50,  is_blob => 0,  is_numeric => 0,  type => 'varchar(50)', default => ''},
         Timezone => 
-               {read => 1, write => 1, type => 'varchar(50)', default => ''},
+               {read => 1, write => 1, sql_type => 12, length => 50,  is_blob => 0,  is_numeric => 0,  type => 'varchar(50)', default => ''},
         PGPKey => 
-               {read => 1, write => 1, type => 'text', default => ''},
+               {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         Creator => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
         LastUpdatedBy => 
-               {read => 1, auto => 1, type => 'int(11)', default => '0'},
+               {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LastUpdated => 
-               {read => 1, auto => 1, type => 'datetime', default => ''},
+               {read => 1, auto => 1, sql_type => 11, length => 0,  is_blob => 0,  is_numeric => 0,  type => 'datetime', default => ''},
 
  }
 };
 
-
-        eval "require RT::User_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/User_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::User_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/User_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::User_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/User_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -840,7 +848,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);
 
index d58f696..f0f07fd 100755 (executable)
@@ -1,26 +1,51 @@
-# BEGIN LICENSE BLOCK
-# 
-# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
-# 
-# (Except where explictly superceded by other copyright notices)
-# 
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+#                                          <sales@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
 # This work is made available to you under the terms of Version 2 of
 # the GNU General Public License. A copy of that license should have
 # been provided with this software, but in any event can be snarfed
 # from www.gnu.org.
-# 
+#
 # This work is distributed in the hope that it will be useful, but
 # WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 # General Public License for more details.
-# 
-# Unless otherwise specified, all modifications, corrections or
-# extensions to this work which alter its source code become the
-# property of Best Practical Solutions, LLC when submitted for
-# inclusion in the work.
-# 
-# 
-# END LICENSE BLOCK
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301 or visit their web page on the internet at
+# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+
 # Autogenerated by DBIx::SearchBuilder factory (by <jesse@bestpractical.com>)
 # WARNING: THIS FILE IS AUTOGENERATED. ALL CHANGES TO THIS FILE WILL BE LOST.  
 # 
@@ -64,7 +89,7 @@ sub _Init {
 }
 
 
-=item NewItem
+=head2 NewItem
 
 Returns an empty new RT::User item
 
@@ -74,24 +99,7 @@ sub NewItem {
     my $self = shift;
     return(RT::User->new($self->CurrentUser));
 }
-
-        eval "require RT::Users_Overlay";
-        if ($@ && $@ !~ qr{^Can't locate RT/Users_Overlay.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Users_Vendor";
-        if ($@ && $@ !~ qr{^Can't locate RT/Users_Vendor.pm}) {
-            die $@;
-        };
-
-        eval "require RT::Users_Local";
-        if ($@ && $@ !~ qr{^Can't locate RT/Users_Local.pm}) {
-            die $@;
-        };
-
-
-
+RT::Base->_ImportOverlays();
 
 =head1 SEE ALSO
 
@@ -101,7 +109,7 @@ _Vendor is for 3rd-party vendor add-ons, while _Local is for site-local customiz
 
 These overlay files can contain new subs or subs to replace existing subs in this module.
 
-If you'll be working with perl 5.6.0 or greater, each of these files should begin with the line 
+Each of these files should begin with the line 
 
    no warnings qw(redefine);